Cross-Site Request Forgery (CSRF) Protection Methods and Bypasses
Cross-Site Request Forgery is a vulnerability found in web applications that lets a third party attacker perform sensitive actions on a user’s behalf. The exploitation of this bug can target normal users as well as site administrators, sometimes leading to a full compromise of a website. Modern websites tend to deploy some protection mechanisms from this attack. Most of the protection mechanisms are to identify and reject a request that originated from a different website.
The protection methods used currently are :
1. Anti CSRF Token
This is a cryptographically strong string that is submitted to the website separately from cookies. This can be sent as a request parameter or as an HTTP header. The server checks for the presence and correctness of this token when a request is made and proceeds only if the token is correct and the cookies are valid.
2. HTTP PUT method
The PUT method is used to create instances of a resource on the server. It is similar to POST except that sending the same PUT requests multiple times does not do anything extra. If the server is using PUT method for sensitive actions then there is no need for any additional CSRF protection(unless Cross-Origin Resource Sharing is enabled) at that endpoint. It is because the PUT request cannot be duplicated through a web page like POST request(HTTP forms do not allow PUT requests ). XHR PUT requests, however, can be sent and will be successful if the endpoint has misconfigured CORS.
3. HTTP Bearer Authentication
This is a type of HTTP authentication where the user is identified through a token that is submitted in “Authorization” header of each request. This mechanism solves CSRF because unlike cookies it is not submitted by the browser automatically.
There are problems and potential bypasses to each of these methods. Anti CSRF tokens do not have a fixed standard so their generation mechanism and use depends solely on how developers intended it to be. Due to this lack of a standard, a lot of implementation specific loopholes exist in web applications.
- Some websites check if the CSRF token is tied to a session or not, but do not verify whether the token is bound to the same session that the request tries to access.
- Some websites send the token in a header/request parameter as well as in a cookie and these tokens are matched at server side. If the match is successful then the operation is allowed. But if the website does not check the authenticity of the token itself and the website is vulnerable to XSS, this mechanism can be easily bypassed by providing a random token in request parameter/header and putting the same token as the cookie by exploiting the XSS vulnerability.
- This can also be bypassed if the endpoint is having a misconfigured CORS.
- If the website is vulnerable to UI redressing(clickjacking) then this mechanism is of no use.
The HTTP PUT method is safe from XSS because there is no “token” to be leaked. But if the website allows Cross-Origin Resource Sharing and it is not properly configured then an attacker can simply duplicate a PUT request by sending it through XHR. The most common misconfiguration is reflecting the origin header in the response as a value of “Access-Control-Allow-Origin”. Along with this, if the PUT method is allowed for CORS request, then a CSRF attack can be easily done by sending a crafted XHR request to the endpoint. Since the HTML forms may allow PUT requests in some upcoming standard. SO the developer has to stay updated on it.
Also, a misconfigured PUT method can allow arbitrary file upload to the server.
The Bearer Authentication is a good way to prevent CSRF, as there is no way for an attacker to know the value of a valid token of an authenticated user. But some websites use both the cookies and bearer token as an authentication mechanism. In absence of a token, they may rely on cookies for authentication which will make the web application vulnerable to CSRF.
Developers should always keep these things in mind while developing an anti-CSRF mechanism –
1. Never send CSRF tokens over GET requests.
2. Bind the token to a user’s session and invalidate it as soon as the session expires.
3. Do not use reversible encoding systems for the creation of CSRF tokens.
4. Do not allow Cross Domain PUT requests if you are relying on PUT requests for CSRF protection.
5. Do not use a single token for each session of a user.