Hey, someone stole my account! – CSRF explained, with nuance
Imagine clicking on a link in a phishing mail. Nothing seems to have happened. But a few days later you try to log into your bank account, and your password no longer works. Someone has changed your password, hijacked your account and undoubtedly is having fun with it. It can happen to you thanks to CSRF attacks.
CSRF (short for Cross-Site Request Forgery) is a web application security vulnerability that, with the help of social engineering, leads to the unintended execution of actions in a target application, in which the victim is currently authenticated.
In the scenario described above, the attacker has used social engineering to lead the victim to an attacker-controlled website, which contains code that performs a submit action to a certain site. For example, code is included that targets an application that has a password-change function (in which it is not required to supply the old password). Such an auto-submit can easily be created by using the Burp Suite Pro CSRF-PoC functionality:
When the victim is lured to this website, the victim’s browser sends a password change request to the banking application. When the session management of the banking website is such that the victim’s session information was still stored in the browser (in such a way that the victim was still authenticated), the user’s password will be changed, and the attacker will now control your bank account!
Of course if the target application allows it, the same type attack can be used to for example transfer funds.
Preconditions for CSRF are:
- The target application has an action (function) that is a profitable target for an attacker, even when he is not the person performing the action himself. An example are functions to take over accounts or to transfer funds
- The target application has a session management implementation in which the user credentials are added automatically by the victim’s browser to the requests that are sent to it. Examples are session cookies, basic authentication or client certificates
- The attacker has all required information to set up a correct message to submit; there are no unpredictable or unknown values / headers
Most modern banking applications, even if they would not explicitly protect against CSRF attacks (which they mostly do) do not provide one-call fund transfer or password change functions. Funds transfer now usually also requires something like multi-factor authentication. Password change functions now often also require the current password as part of a password change. As such, as applications have matured in terms of security, the chances of a successful high-profile CSRF attack have diminished, and CSRF findings are shifting more towards lower severity findings in smaller applications or applications built in-house.
Take for example the recently discovered CSRF vulnerability in the MediaWiki extension PushToWatch (CVE-2020-35626). This is a CSRF finding in an extension (not all implementations of the MediaWiki platform. The function targeted here is a function that takes a page and an account name as parameter and will send the target account a notification that they from now on will be watching this page. Is this a finding? Should this function be protected? Probably yes. Is it likely that this vulnerability will be used as part of an exploit? If yes, it’s a much softer yes.
How to protect against CSRF
Protecting against CSRF can be done in various ways. Of course, all critical application functions should be checked for possibility of adding additional controls such as MFA. But in addition to this, many development platforms and frameworks also offer a token with a value unpredictable for the attacker, to be sent by the browser and which is checked server side, making it impossible for the attacker to create a successful CSRF message.
To actually work, the CSRF token implementation however has to meet the following requirements:
- The token has to be so complex that it is unpredictable (and practically can’t be brute forced)
- The token is validated server side in all cases where a relevant action is executed
- The token is explicitly linked to a session
The issues often lie in the details of the implementation: for example, the server only checks for a valid CSRF token value when the CSRF header is supplied, but skips the check if the CSRF token request header is missing. Also it can happen that the CSRF token is validated on POST, but not checked when the same function is called through the HTTP PUT method.
As for linking the CSRF token to a specific user (which is necessary because otherwise the attacker can just create an account and use his own CSRF tokens to set up a successful CSRF attack), this is often very difficult to implement. Proper implementation requires the CSRF functionality to be integrated with the session management functionality. Already challenging in itself, this becomes more complex when an application is built using multiple components; it’s not always obvious which session ID is handling the session for exactly which functions.
Another common mistake is to check server side on correct CSRF tokens, but to also include them in a cookie, effectively directly eliminating all protection.
Other mechanisms that can help protect against CSRF are the SameSite cookie property, which blocks browsers from using cookies for site A when the request originates from site B, and CORS (Cross-origin resource sharing), a relatively new security feature in browsers.
When CORS is configured on server then resources from the relevant domain when requested must be initiated from assets that are also served from that same domain, if not, an error is produced. CORS is also often accompanied by pre-flight requests, requests that are used to first ask a web application specific methods and headers are required. This mechanism also provides an additional layer of protection against CSRF attacks.
Although successful CSRF attacks are becoming less likely, it is still required to protect all relevant application functions from these types of attacks. Not sure if your applications are sufficiently secured against CSRF attacks? Ask one of our security consultants for advice!