Bypassing CSRF Tokens via CORS Misconfigurations
Last updated
Last updated
In addition to the attack vectors discussed in the previous sections, CORS misconfigurations can also be used to bypass CSRF defenses and carry out CSRF attacks even if proper defenses are implemented.
If CORS is misconfigured so that session cookies are sent along with cross-origin requests, i.e., the Access-Control-Allow-Credentials
is set, we can effectively bypass the Same-Origin policy. In that case, common CSRF defenses are ineffective, as we will discuss in this section.
If we can bypass the Same-Origin policy due to a CORS misconfiguration, we can access the response of cross-origin requests we make. This allows us to make a cross-origin request to the endpoint that creates a valid CSRF token, read it, embed it into our state-changing cross-origin request, and send the state-changing cross-origin request with the valid CSRF token. Since all this happens in the victim's session, the CSRF token is valid even if properly checked and tied to the victim's user session.
However, for the victim's browser to send the victim's session cookie along with requests made from JavaScript, we require the vulnerable web application to explicitly set the SameSite
cookie attribute to None
in addition to the CORS misconfiguration. Per the specification, this is only allowed with the Secure
cookie attribute, which allows cookie transmission via secure HTTPS connections only. The cookie will not be sent along any unencrypted HTTP connections.
Due to this restriction, the sample web application and all other lab components are only accessible using HTTPS. If we analyze the web application, we can notice that the web application sets the Access-Control-Allow-Origin
and Access-Control-Allow-Credentials
CORS headers, indicating that we should check for a CORS misconfiguration. Furthermore, the session cookie is set with both the Secure
and SameSite=None
cookie attributes:
We can analyze the web application's behavior if we supply different values in the HTTP Origin
header. If we supply an arbitrary value, we can see that the web application is indeed misconfigured, as arbitrary origins are reflected in the Access-Control-Allow-Origin
CORS header:
We can exploit this CORS misconfiguration with the SameSite=None
cookie attribute to bypass proper CSRF protection and execute a CSRF attack. Let us analyze the web application further to identify potential targets for this attack.
Like before, the web application implements a functionality to promote user accounts to administrators. This time, the corresponding POST request is properly protected by a CSRF token:
Let us write an exploit to obtain a valid CSRF token in the victim's session and subsequently make the corresponding cross-origin request to make the victim promote our user account to have administrator privileges. The CSRF token is sent in response to a GET request to the /profile.php
endpoint. We can make the corresponding request, parse the response, and extract the CSRF token using JavaScript code similar to the following:
Code: js
Afterward, we can construct the cross-origin request to promote our user with the valid CSRF token:
Code: js
We can combine both parts to come up with the following payload on our exploit server:
Code: html
If we view our exploit, we can see an authenticated GET request to /profile.php
followed by an authenticated POST request to /profile.php
with the valid CSRF token. Thus, our exploit should work. After delivering it to the victim and waiting for a few seconds, our user is promoted to administrator. Thus, we successfully exploited the CORS misconfiguration to bypass the CSRF protection and conduct a successful CSRF attack: