Repository navigation
v1.16.0
-
Added the
cross_originconfiguration entry, grouping every cross-origin
response header and splitting it by the kind of response it applies to, the
same shape thecacheentry already uses:cross_origin: api: allow_origin: '' allow_methods: 'GET,HEAD,PUT,POST,PATCH,DELETE,OPTIONS' allow_headers: 'Content-Type, Access-Control-Allow-Headers, Authorization' allow_credentials: true expose_headers: 'Content-Length, Content-Type, Last-Modified, X-Access-Token, X-Access-Token-Expiration' max_age: 0 vary_origin: true static_files: opener_policy: 'same-origin-allow-popups' embedder_policy: '' resource_policy: ''
The split is not cosmetic:
CORSis set on API responses only, while the
cross-origin isolation policies are set on static file responses only, and
the two never meet on the same response.Every entry is also a command-line option
(--cross-origin-api-max-age,--cross-origin-static-files-opener-policy,
...), and anAPICrossOriginConfigcan be passed straight toAPIServer.
SeeAPICORSConfigandAPICrossOriginPolicies.Until now all of these values were hardcoded in
APIServer.setCORS, with no
way to change them short of rewriting the response. -
Behavior change: static
text/htmlresponses are now served with
Cross-Origin-Opener-Policy: same-origin-allow-popups.It severs the opener relationship with a cross-origin document that opened
the page — the isolation ofsame-origin— while still allowing the popups
the page itself opens to keep a handle back to it. That is what popup-based
sign-in flows need (Sign in with Google, OAuth popups): the popup reports
its result by calling back into its opener.A document served by this server that is itself opened as a cross-origin
popup and callswindow.opener(an OAuth callback landing page) must now opt
out withopener_policy: none.COOPandCOEPare only sent fortext/html, since they are document
headers, whileCORPapplies to every static file.COEPandCORPare
disabled by default. -
Behavior change: API responses are now served with
Vary: Origin.Access-Control-Allow-Originreflects the requestOrigin, and without
Varya shared cache is free to serve one origin's
Access-Control-Allow-Originto another. Disable withvary_origin: false. -
allow_originaccepts an allowlist. When set, the requestOriginis
reflected only if it matches, otherwise noAccess-Control-Allow-Originis
sent and the browser blocks the cross-origin read.Worth noting for anyone leaving it empty: reflecting any origin together with
Access-Control-Allow-Credentials: true— the behavior before this version,
and still the default — lets any site make credentialed calls to the API and
read the responses. The browser only rejects that pairing for a literal*. -
Access-Control-Max-Ageis now available throughmax_age, sent only on
OPTIONSresponses, the only ones a browser caches. Defaults to0, which
omits the header. -
Fixed: a
cookielessserver did not apply the cookieless guarantee to static
file responses.Set-Cookiewas dropped andX-Cookieless-Server: Blocking all cookieswas
added by the API response builder, but a static file response is built by the
shelfhandler and returned before reaching it. So the header was missing
from every static file, and nothing enforced the absence ofSet-Cookie
there. Both now happen for static files as well, including the non-2xx
responses.