Skip to content

CSRF cheat sheet: clarify SameSite limitations and fix pseudocode syntax highlighting#2080

Open
Copilot wants to merge 2 commits intomasterfrom
copilot/review-csrf-cheat-sheet-issues
Open

CSRF cheat sheet: clarify SameSite limitations and fix pseudocode syntax highlighting#2080
Copilot wants to merge 2 commits intomasterfrom
copilot/review-csrf-cheat-sheet-issues

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Mar 26, 2026

Two long-standing issues in the CSRF Prevention Cheat Sheet addressed here: vague/outdated SameSite bypass language, and missing syntax highlighting on HMAC pseudocode blocks.

Changes

SameSite limitations (fixes #1101)

Replaced the vague "2 ways to bypass it" sentence (linked to a stale IETF draft) with two concrete, actionable limitations:

  • SameSite=Lax does not protect state-changing GET requests — cross-site top-level navigations using safe HTTP methods still send cookies
  • SameSite is defeated by any compromised same-site subdomain (XSS, HTML injection, subdomain takeover) — especially relevant for multi-tenant SaaS

Pseudocode syntax highlighting (fixes #1143, Improvement 1)

Changed both HMAC CSRF token pseudocode fences from ```code to ```javascript — the pseudocode already uses JS-style // comments and const, so this gives accurate highlighting without altering content.

Note: The request.setCookie()response.setCookie() bug (Improvement 3) and the session-dependency clarification (Improvement 2) are already addressed in the current file and required no changes.


  • In case of a new Cheat Sheet, you have used the Cheat Sheet template.
  • All the markdown files do not raise any validation policy violation, see the policy.
  • All the markdown files follow these format rules.
  • All your assets are stored in the assets folder.
  • All the images used are in the PNG format.
  • Any references to websites have been formatted as [TEXT](URL)
  • You verified/tested the effectiveness of your contribution (e.g., the defensive code proposed is really an effective remediation? Please verify it works!).
  • The CI build of your PR pass, see the build status here.

AI Tool Usage Disclosure (required for all PRs)

  • I have used AI tools to generate the contents of this PR. I have verified the contents and I affirm the results. The LLM used is claude-sonnet-4.5 and the prompt used is Review https://github.com/OWASP/CheatSheetSeries/issues/1101 and https://github.com/OWASP/CheatSheetSeries/issues/1143 and later review Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.md and implement the necessary changes to address the open issues.

⌨️ Start Copilot coding agent tasks without leaving your editor — available in VS Code, Visual Studio, JetBrains IDEs and Eclipse.

…ax highlighting

Co-authored-by: mackowski <35339942+mackowski@users.noreply.github.com>
Agent-Logs-Url: https://github.com/OWASP/CheatSheetSeries/sessions/f2a2a8a6-1fd5-4936-b973-5b3cda2299b5
Copilot AI changed the title [WIP] Review issues related to CSRF prevention cheat sheet CSRF cheat sheet: clarify SameSite limitations and fix pseudocode syntax highlighting Mar 26, 2026
Copilot AI requested a review from mackowski March 26, 2026 10:24
@mackowski mackowski marked this pull request as ready for review March 26, 2026 10:29
Copy link
Copy Markdown
Member

@jmanico jmanico left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The first bullet is substantively correct, with one nuance. Under SameSite=Lax, cookies are sent on cross-site top-level navigations that use a safe method, including GET; that means a state-changing GET endpoint would still be exposed.

It is important to note that this attribute should be implemented as an additional layer _defense in depth_ concept. This attribute protects the user through the browsers supporting it, and it contains as well 2 ways to bypass it as mentioned in the following [section](https://tools.ietf.org/html/draft-ietf-httpbis-rfc6265bis-02#section-5.3.7.1). This attribute should not replace a CSRF Token. Instead, it should co-exist with that token to protect the user in a more robust way.
It is important to note that this attribute should be implemented as an additional layer of _defense in depth_. This attribute protects the user through browsers supporting it, but has important limitations:

- **`SameSite=Lax` does not protect state-changing `GET` requests**: `SameSite=Lax` only blocks cookies on cross-site requests that use unsafe HTTP methods (e.g., `POST`, `PUT`, `DELETE`). Cross-site top-level navigations using safe methods (`GET`, `HEAD`, `OPTIONS`) still transmit cookies under `Lax`. If your application performs any state-changing operations via `GET` requests (which is itself strongly discouraged), `SameSite=Lax` will not protect those endpoints.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The first bullet is correct, with one nuance. Under SameSite=Lax, cookies are sent on cross-site top-level navigations that use a safe method, including GET; that means a state-changing GET endpoint would still be exposed.

Also, when Lax is applied as a browser default rather than explicitly set, some browsers use a temporarily more permissive variant that may also send cookies on certain recent cross-site POST requests.


- **`SameSite=Lax` does not protect state-changing `GET` requests**: `SameSite=Lax` only blocks cookies on cross-site requests that use unsafe HTTP methods (e.g., `POST`, `PUT`, `DELETE`). Cross-site top-level navigations using safe methods (`GET`, `HEAD`, `OPTIONS`) still transmit cookies under `Lax`. If your application performs any state-changing operations via `GET` requests (which is itself strongly discouraged), `SameSite=Lax` will not protect those endpoints.

- **Subdomain and sibling-domain vulnerabilities**: `SameSite` can be bypassed if any subdomain or sibling domain of your application is compromised (e.g., via XSS, HTML injection, or a [subdomain takeover](https://owasp.org/www-project-web-security-testing-guide/latest/4-Web_Application_Security_Testing/02-Configuration_and_Deployment_Management_Testing/10-Test_for_Subdomain_Takeover) attack). A subdomain is considered "same-site", so an attacker controlling `vulnerable.example.com` can inject or overwrite cookies that are sent to `example.com`, defeating `SameSite` protection entirely. This is a significant risk on SaaS platforms where multiple tenants share a domain.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Brief note, “inject or overwrite cookies sent to example.com” is accurate primarily when cookies are domain-scoped; it is less accurate for properly host-only cookies, especially __Host- cookies.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

3 participants