CSRF where token is duplicated in cookie

2 min read Easy PortSwigger
CSRF
Contents

On this page

The lab

here is how portswigger describes it

This lab's email change functionality is vulnerable to CSRF. It attempts to use the insecure "double submit" CSRF prevention technique.

To solve the lab, use your exploit server to host an HTML page that uses a CSRF attack to change the viewer's email address.

The idea#

the double submit cookie technique works like this the site puts the same csrf token in two places, a hidden field in the form and a cookie, and when the request comes in it simply checks that the form value and the cookie value are equal. the thinking is that an attacker writing a forged form cannot know the victim's cookie value, so they cannot make the two match.

the flaw is that the server never checks the token is one it actually issued it only checks that the two copies agree. so if there is any way for us to set the victim's cookie, the whole thing falls apart, because then we choose both sides. we pick any value we like put it in the form and set the cookie to the very same value, and the equality check passes. it does not need to be a genuine token a made up string works just as well.

Step 1 - Spot the duplicated token#

logging in and intercepting an email change, the token shows up twice. there is a csrf field in the request body and a csrf cookie and both hold the exact same value. that duplication is the signature of the double submit pattern and it tells us the server is probably just comparing the two

11

to set both sides we need to write the victim's csrf cookie and we already have a way to do that from the previous lab the search on the home page reflects our input into the response's Set-Cookie header. the same crlf trick lets us plant a csrf cookie of our choosing

HTTP
/?search=test%0d%0aSet-Cookie:%20csrf=logicbreaker%3b%20SameSite=None
22

Step 3 - Build the POC and deliver it#

now we put the same value on both sides the form and the cookie. as before we drop the auto submit script and use an image so the cookie is set first and the form submits only after.

HTML
<html>
  <body>
    <form action="https://your-lab-id.web-security-academy.net/my-account/change-email" method="POST">
      <input type="hidden" name="email" value="[email protected]" />
      <input type="hidden" name="csrf" value="fake" />
      <input type="submit" value="Submit request" />
    </form>
    <img src="https://your-lab-id.web-security-academy.net/?search=test%0d%0aSet-Cookie:%20csrf=fake%3b%20SameSite=None" onerror="document.forms[0].submit()"/>
  </body>
</html>

notice the value on both sides is just fake, and that is the whole point, it does not have to be a real token, it only has to be the same string in both the form and the cookie. when the victim loads the page, the <img> fetches our injected search url, the response plants a csrf cookie with the value fake the load fails so onerror fires and submits the form, and the form carries a csrf field that is also fake. the server compares the two sees they match and accepts the change on the victim's session.

33

with this, the lab is solved!