Cross-site request forgery
Cross-site request forgery, also known as CSRF or XSRF, is a attack in which an alternate website sends fake requests to a real website.
Attack
The attack is like this:
- A user is logged into
shopping.com
, an online store where he shops regularly.shopping.com
leaves a session id in a cookie so the user doesn't need to login every visit.
- The user is sent a email linking to
attacker-website.com
. They visit this website. - The JS code in
attacker-website.com
sends a POST request toshopping.com
to order an item.- This request will carry the session id which is already authenticated.
- Without CSRF protection, the order will go through.
Defense
To protect against CSRF, the website shopping.com
should do the following:
- While the user is browsing
shopping.com
, the backend sets a CORS cookie using an HTTP header in a response.XSRF-TOKEN:UKL7smHAK4xENQj5pYbi
- This cookie will be different for each session.
- When making requests to checkout, the front-end will add the XSRF token to the HTTP request as a header or hidden form field.
X-XSRF-TOKEN:UKL7smHAK4xENQj5pYbi
- Before processing the order, the backend will check the XSRF header to make sure that it matches what was sent originally.
- I.e. it checks that the (XSRF header or hidden field) matches the (sent cookie or save session token).
- Notes
- Typically, the server will update the CSRF cookie every request.
- If using a header, the defense is call cookie-to-header.
- Using a hidden form field is called double submit cookie and does not require JavaScript.
Defense Explanation
This works for the following reasons:
- When sending the XSRF token, the backend sends it in an HTTP header telling the browser to stores it as a cookie,
- If other websites make a request (via fetch or XmlHTTPRequest) to get an XSRF token, the token will be sent in the HTTP header.
- By default, the browser will only let the other website see a few whitelisted HTTP headers due to same-origin policy so they will not see the XSRF token.
- If other websites make a request (via fetch or XmlHTTPRequest) to get an XSRF token, the token will be sent in the HTTP header.
- Next the browser stores the cookie under
shopping.com
.- Due to same-origin policy, other websites cannot see the cookies for
shopping.com
.
- Due to same-origin policy, other websites cannot see the cookies for
Note that other origins may be able to read hidden form fields and can send custom headers if Access-Control-Allow-Origin
is set incorrectly.
It is important for the backend to check the XSRF key against one that other websites cannot read.
If you send the XSRF token in a cookie and a hidden form field, this will not require any JS since the browser will automatically repeat the hidden form field.
However, you need to make sure no CORS header is sent otherwise other websites will be able to read the XSRF token sent in the hidden form field.
E.g.
Access-Control-Allow-Origin: https://shopping.com