====== Sec-Fetch-Site Header Protection ====== **Sec-Fetch-Site** is an HTTP request header that provides modern defense against Cross-Site Request Forgery (CSRF) attacks by communicating the origin context of a request to the server. As part of the Fetch metadata request headers specification, this header enables servers to make informed decisions about request legitimacy without relying on traditional token-based mechanisms(([[https://fetch.spec.whatwg.org/|WHATWG Fetch Standard]])). ===== Overview and Purpose ===== The Sec-Fetch-Site header is automatically added by modern web browsers to HTTP requests and indicates the relationship between the requesting site and the target origin. Unlike traditional CSRF tokens that require developers to manage stateful session data, this header leverages the browser's inherent knowledge of request context to provide transparent protection(([[https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)|OWASP - Cross-Site Request Forgery (CSRF]])). The header can contain one of four possible values: * **same-origin**: The request originates from the exact same origin (scheme, domain, and port all match) * **same-site**: The request comes from a site on the same registrable domain but potentially different subdomain * **cross-site**: The request originates from a completely different site * **none**: The request was user-initiated or the browser cannot determine the context By evaluating these values, servers can reject suspicious cross-site requests while permitting legitimate same-origin operations, effectively blocking CSRF attacks at the HTTP layer(([[https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Sec-Fetch-Site|MDN Web Docs - Sec-Fetch-Site]])). ===== Technical Implementation ===== The Sec-Fetch-Site header is part of a broader set of Fetch metadata request headers that includes Sec-Fetch-Mode, Sec-Fetch-Dest, and Sec-Fetch-User. These headers are automatically set by compliant browsers and cannot be forged by JavaScript code running in web pages, providing cryptographic-grade trust in their values(([[https://www.w3.org/TR/fetch-metadata/|W3C - Fetch Metadata Request Headers]])). Server-side implementation requires examining the header value in request handlers and applying authorization logic. For state-changing operations (POST, PUT, DELETE), servers should reject requests where Sec-Fetch-Site equals "cross-site". For sensitive data endpoints (GET), servers may choose to also reject cross-site requests depending on risk assessment(([[https://owasp.org/www-community/attacks/csrf|OWASP - CSRF Attack Examples]])). The protection works because browsers enforce same-origin policy restrictions on form submissions and JavaScript fetch calls. A malicious website cannot trigger a POST request to a target site and inspect the response if that site uses Sec-Fetch-Site validation, since the browser will not allow JavaScript access to the response body. ===== Advantages Over Token-Based CSRF Protection ===== Traditional CSRF protection using tokens requires developers to: * Generate unique tokens per session or request * Store tokens in server-side session storage * Embed tokens in HTML forms * Validate token presence and value on each state-changing request This approach introduces operational complexity, requires session management overhead, and can create scaling challenges in distributed systems. Sec-Fetch-Site header protection eliminates these requirements by delegating context verification to the browser, which already has this information(([[https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html|OWASP - CSRF Prevention Cheat Sheet]])). The header-based approach is **stateless**, requiring no server-side session data, and **automatic**, providing protection without developer effort to embed tokens in templates or validate them in code. ===== Browser Support and Limitations ===== Sec-Fetch-Site is supported in all modern browsers including Chrome, Firefox, Safari, and Edge. However, support is not universal across all clients, particularly older browser versions and non-browser HTTP clients that may not implement the header(([[https://caniuse.com/mdn-http_headers_sec-fetch-site|Can I Use - Sec-Fetch-Site Support]])). Servers implementing this protection should apply a defense-in-depth strategy, using Sec-Fetch-Site as the primary CSRF protection layer while maintaining backward compatibility with token-based mechanisms for older clients. Additionally, servers must implement proper **SameSite cookie attributes** on session cookies to prevent exploitation through cross-site cookie transmission, complementing the Sec-Fetch-Site validation. ===== Current Adoption and Practical Considerations ===== Major web frameworks and platforms increasingly include built-in support for Sec-Fetch-Site validation. Tools like [[datasette|Datasette]], various Python web frameworks, and Node.js middleware now offer configuration options to enable this protection automatically. Datasette is transitioning away from token-based CSRF protection in favor of Sec-Fetch-Site validation, a change that simplifies the codebase and eliminates the need to selectively disable protection for external APIs(([[https://simonwillison.net/2026/Apr/14/replace-token-based-csrf/#atom-blogmarks|Simon Willison Blogmarks - CSRF Protection (2026]])). The approach represents a shift toward browser-based security primitives that reduce the attack surface for developers while improving defense mechanisms. Organizations implementing Sec-Fetch-Site protection should monitor their request logs to identify clients that do not send the header and evaluate whether exempting those clients creates unacceptable security risks. In scenarios where compatibility with legacy systems is unavoidable, hybrid approaches using both Sec-Fetch-Site validation and traditional tokens provide comprehensive coverage. ===== See Also ===== * [[api_endpoint_security|API Endpoint Security]] * [[web_fetch_tool|Web Fetch Tool]] * [[access_control_vulnerabilities|Access Control Vulnerabilities]] ===== References =====