Web Security - Cross-site request forgery (CSRF)
Table of Contents
About
A Cross-site request forgery (CSRF) is:
- made by real users unknowingly
- with the help of the browser
- from a website
- to another target website (ie making the request a cross-site or cross-origin request )
This cross-origin http request is performed via:
- an image tag
- or tricks (a fake or invisible form).
and:
- send along the cookies of the targeted domain.
If the user was logged in and the cookie were storing session information, the request will be also authenticated and made in the name of the user.
Why ? This problem exists because any HTTP requests can be send from any other origins. An image or a HTML form will create a HTTP request
This request can be used to:
- post messages on a forum under the user's name,
- make purchases,
- transfer money
- or apply for a passport.
This is then important to verify that the request was made:
- by the user intentionally,
- rather than by another site tricking the user into making the request unknowingly.
Articles Related
Example
A common example is an <img> tag embedded in a malicious page with the src pointing to the attack’s target. For instance:
<!-- This is embedded in another domain's site -->
<img src="http://target.site.com/add-user?user=name&grant=admin">
The above <img> tag will send a http get request to target.site.com every time the page that contains it is loaded.
If the user had previously logged in to target.site.com and the site used a cookie to keep the session active, this cookie will be sent as well.
If the target site does not implement any CSRF mitigation techniques, the request will be handled as a valid request on behalf of the user.
Prevention
Sites can prevent such attacks:
- by populating forms with user-specific hidden tokens,
- by allowing cookie to be sent only to the same origin via the samesite parameter
- by allowing only post request
- and/or by allowing only certain Origin
- by setting the CORS setting
- or by checking programmatically the Origin header on all requests
If session data are not stored as cookies, CSRF attacks are not possible.
Headers with Token
A CSRF token is a random, hard-to-guess string aimed at protect a form from a CSRF attack
Steps:
- the server generate for each served page (form) a random string, the CSRF token,
- The CSRF token is added to the form as a hidden field
- It's very difficult to guess the token and therefore it's difficult to submit a fake form.
The CSRF token is sent generally as an header called X-CSRF
Don't write the token in a cookie because the browser send always every cookies even with a cross origin request. The Cross Site request forgery exploit it but the cross-site scripting exploit also.
Because an header is not automatically sent, the token is under control.
Origin
The origin is the cornerstone of the web security and you can:
- check the origin value against the origin that created the session
Origin Header Check
The Origin HTTP headers can be checked against the value obtained when the session was created.
The Referer header may also be used.
The browser add it automatically but for server-side or native apps, the Origin header should be sent with an identifying URL as the value. Example:
curl -c cookie.txt \
-d [email protected] \
-d password=123 \
-H "Origin: https://mywebsite.com" \
https://api-host.com/api/create-session/
- Use the session cookie to call your api
curl -b cookie.txt \
-d '{"posts": [{"title": "Hello World"}]}' \
-H "Content-Type: application/json" \
-H "Origin: https://mywebsite.com" \
https://api-host.com/api/posts
Cors
The cors setting can also prevent this kind of attack. It allows only request from some origin
Example with access-control-allow-origin
- Request can be made by the browser for every domain
Access-Control-Allow-Origin: *
- Request can be made by the browser for only from the domain example.com
Access-Control-Allow-Origin: http://example.com
On this site for instance, we allows that the fetching of resources from https://jsfiddle.net/ because it's where you can try our code live and this code sometimes fetch some resources such a json or csv file.
Access-Control-Allow-Origin: https://jsfiddle.net
SameSite cookie property
State
This method mitigates CSRF exploit against the the Oauth redirection URI
The client send pass a nonce parameter (called state in oauth) and the client validate that the the value coming from the response matches the one it sent.
This is mostly used in the two way authentication code flow method where the client gets a code via a redirection url and needs to ask an authorization point to transform it as authentication token.
Documentation
- __csrf_token: 5b6e840a22eb21ba55fadd2d8d6421299f68f9eb