Same-origin and direct browser requests passing a context gate while a cross-site request is diverted before reaching an application
Fetch Metadata lets a server reject a suspicious cross-site context before application work begins.

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.

ContextTypical decisionCaveat
Same originAllowNormal authentication still applies
Same siteAllow only if subdomains are trustedA weaker sibling can share the site boundary
Direct navigationAllow safe top-level GET pagesNever make a state change depend on GET
Cross siteReject unless the endpoint needs itCORS 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

  1. Same-origin action. Confirm a normal signed-in request still passes every existing check.
  2. Cross-site form. Send a harmless test from another origin. Expect the server to reject it without changing state.
  3. External link. Open a public page from another site. Safe top-level visits should still work.
  4. Public exception. Load each planned cross-site asset or API from an approved origin.
  5. Missing header. Send a server-to-server request. Confirm that the written support path works as planned.
  6. 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 →