
- Read
Sec-Fetch-Site, mode and destination at the edge or application boundary. - Log first, list real cross-site exceptions, then reject unwanted cross-site resource and state-changing requests.
- Keep CSRF tokens, authorization and safe HTTP methods. Fetch Metadata is an added boundary, not a replacement.
A browser may send a user's cookies with a request that began on another site. The app may see a valid session first. It still needs the request context.
Fetch Metadata adds that context through Sec-Fetch-* request headers. A server can sort the request as same-origin, same-site, direct or cross-site. It can then apply a resource isolation rule before doing the work.
Browsers send these headers. Your job is to decide which request types each endpoint should accept.
Start with the request relationship
Sec-Fetch-Site carries one of four values. same-origin means the initiator shares the origin. same-site allows a related subdomain. cross-site names an unrelated site, while none covers some direct user actions such as an address-bar visit or bookmark.
The browser also describes the mode and destination. A page visit differs from an image, script or embedded object request.
| Context | Typical decision | Caveat |
|---|---|---|
| Same origin | Allow | Normal authentication still applies |
| Same site | Allow only if subdomains are trusted | A weaker sibling can share the site boundary |
| Direct navigation | Allow safe top-level GET pages | Never make a state change depend on GET |
| Cross site | Reject unless the endpoint needs it | CORS APIs, webhooks and public assets need explicit rules |
Page JavaScript cannot freely set these Sec- headers. That makes them useful context. A non-browser client can send any HTTP value, so this is not proof of identity or access.
Write policy around endpoints, not one global guess
Begin with endpoints that change state or return user data. Let a same-origin request pass this gate. Then run its normal identity, access, CSRF and input checks.
Reject an unwanted cross-site request before sensitive work begins. Do it early. For a normal site, allow safe top-level GET visits so outside links still open.
Never use that exception for a state change. A request that deletes, buys or updates must use a proper method. It still needs its normal anti-CSRF control.
List each endpoint meant for cross-origin browser use. Keep the list narrow. CORS APIs, public assets and login flows may need an exception. The OAuth redirect guide shows why each callback also needs one exact destination rule.
Decide whether same-site is really trusted
Same-site is wider than same-origin. Two subdomains can be same-site while their origins still differ.
First map who controls each host. If one team and one standard cover them all, allowing same-site may fit. If customers, old apps or vendors control sibling hosts, use same-origin for sensitive endpoints.
Cookie settings still matter. A device-bound session addresses a different problem, and neither control removes the need for narrow session scope and authorization.
Handle missing headers as a compatibility path
Modern browser engines send Fetch Metadata on eligible trustworthy requests. Other clients may omit it. Old browsers, monitors, mobile webviews or server jobs can arrive with no header.
Do not call a missing value safe. Use the endpoint's existing controls during rollout, and record the client type. A browser-only endpoint can become stricter later, after real use has been measured.
Webhooks should prove who sent each message. They must also be safe to retry. A missing browser header does not make them trusted; use the webhook idempotency workflow for that boundary.
Log before you enforce
if sec_fetch_site == "cross-site":
if is_safe_top_level_get(request):
allow()
elif path in reviewed_cross_site_exceptions:
allow()
else:
reject(403)
This is a policy sketch, not drop-in code. Read header names without case rules. Define a safe visit with care, and keep exceptions in reviewed config.
Start in log-only mode. Record the endpoint, method, site value, mode, destination and decision. Do not log session secrets or personal request bodies. Study valid failures, then narrow the list.
Some cacheable GET results depend on these headers. In that case, W3C and web.dev guidance calls for a matching Vary response header. Without it, a shared cache may reuse one context's result for another.
Run a small rejection matrix
- Same-origin action. Confirm a normal signed-in request still passes every existing check.
- Cross-site form. Send a harmless test from another origin. Expect the server to reject it without changing state.
- External link. Open a public page from another site. Safe top-level visits should still work.
- Public exception. Load each planned cross-site asset or API from an approved origin.
- Missing header. Send a server-to-server request. Confirm that the written support path works as planned.
- Cache check. Allow a response in one context. Make sure it is not reused for a denied one.
These are test steps, not claims about your system. TechWeb did not inspect your headers, subdomains, middleware, CDN, browser clients or CSRF controls.
Use a Content Security Policy for browser-side resource rules. Fetch Metadata makes a server-side context choice. The two controls guard different paths.
Frequently asked questions
Does Fetch Metadata replace a CSRF token?
No. It adds another layer. Keep CSRF protection, suitable SameSite cookies, access checks and safe method design.
Should every cross-site request be blocked?
No. External links, CORS endpoints, public assets and federated flows can need cross-site access. Write narrow, reviewed exceptions.
Can I trust every same-site subdomain?
Only if your security boundary supports that choice. Use same-origin when sibling subdomains have weaker or different owners.
What if Sec-Fetch-Site is missing?
Use the controls you already have. Record which client sent it. Absence is not proof that the request is safe.
Sources
W3C: Fetch Metadata Request Headers · web.dev: Protect resources with Fetch Metadata · MDN: Sec-Fetch-Site · OWASP: CSRF Prevention Cheat Sheet. Browser and framework behavior can change; verify the clients and middleware you operate.
More in this sectionTechnology →