HackBlue

Labs / Web and API security

CSRF token flow

Follow a CSRF token from form to server check, then pick SameSite and server checks until four forged requests fail and your own three still work.

  • Interactive lab
  • Intermediate
  • 5 steps
  • 0 of 5 solved

Goal

bank.example keeps you signed in with a session cookie. Any site you visit can make your browser send a request to the bank, and the browser decides whether your cookie goes with it.

Seven requests reach the bank: three are yours and four are forged by other pages. Pick the SameSite setting and the server checks until every forged request fails and yours still work.

Session cookie SameSite

Server

How the token travels
  1. 1
    GET /transferThe server renders the form and puts a token tied to this session in a hidden field.
  2. 2
    <input type="hidden" name="csrf" value="lab-only-csrf-7f3a9c">Only pages from bank.example can read this value. The same-origin policy stops other sites from reading the response.
  3. 3
    POST /transfer csrf=lab-only-csrf-7f3a9cThe browser sends the session cookie automatically. The token is sent because the page put it in the form.
  4. 4
    Server compares the token with the one stored for the sessionA match proves the request came from a page the bank rendered, not just from a browser that has the cookie.
Requests4 wrong
RequestFromCookieTokenResult
YoursYou submit the transfer form on bank.examplePOST /transfer
bank.example (same-origin)
sentvalidperformed
The server performed the action.
YoursThe bank’s own page calls the API with the token in a headerPOST /api/payees
bank.example (same-origin)
sentvalidperformed
The server performed the action.
YoursYou click a link in the bank’s newsletter (sent from mail.example) to view your statementsGET /statements
mail.example (cross-site)
sentnonepage shown
Read-only page shown with the session.
ForgedA page on prizes.example auto-submits a hidden form to /transferPOST /transfer
prizes.example (cross-site)
sentnoneperformed
The server performed the action.
ForgedA forum post links to /transfer?to=lab-only-acct&amount=900GET /transfer
forum.example (cross-site)
sentnoneperformed
CSRF middleware skips safe methods, so this GET performed the transfer.
ForgedA compromised page on blog.bank.example submits a form to /transferPOST /transfer
blog.bank.example (same-site)
sentnoneperformed
The server performed the action.
Forgedprizes.example submits the form with a guessed tokenPOST /transfer
prizes.example (cross-site)
sentwrong valueperformed
The server performed the action.

Steps

  1. 01Choose the cookie setting and server checks so that all four forged requests fail and all three of your own requests still work.

    Do this in the workbench above. This step completes itself when the condition is met.

  2. 02With SameSite=Strict, which of your own requests stops working? Give the site it came from.

  3. 03Why does SameSite not stop the request from blog.bank.example?

  4. 04SameSite=Lax still sends the cookie on the forum link. What is the right fix?

  5. 05What makes the token work?