Cross Site Request Forgery
An attacker can compromise a web application that has a Cross Site Request Forgery (CSRF) vulnerability by exploiting a valid authenticated session that has been set up in a users browser. For example, if a user logs into a secure web application and then visits other sites whilst the connection to the web application is still in place then the attacker can send embedded commands on the third party pages to the secure web application. As these requests are coming from an authenticated browser there is no way for the web application to differentiate them and will treat them as valid requests. The malicious commands sent from a third party site can be hidden on the page. In information associated with image files for example. So the user visiting the third party site won’t even notice anything suspicious when browsing a page.
As an example of how a CSRF vulnerability could be exploited consider the following. Attackers send an email to users suggesting they should log into their online banking accounts and make sure there are no suspicious transactions. This email doesn’t even have a link in it to their bank website. It doesn’t look like a phishing email by asking for any confidential information. Some users connect to their online banking accounts and log in to check. This sets up an authenticated session cookie between the banking site and the browser. The attackers also send emails to the users that have links to sites offering free offers, celebrity news or some other content that might entice them to click on a link. If a user is enticed into clicking on one of these links the page that is shown to them also has a hidden script embedded. The purpose of this hidden script is to send a command to the targeted online banking application.
If the user in question has an account with that online bank, and they are currently logged in, then the command from the script could be treated as a valid request. A typical action by the script is to transfer a sum of money out of the victims account to an account the attacker controls. There will be no evidence to the user that anything untoward has happened. The banking site will just log it as a valid transaction and execute it. This only works if the user has an account with an online banking site that the attacker is targeting. But the third party sites with malicious scripts will be casting a large net and targeting all banks. The attack also relies on users being logged into their online banking account, mostly in response to the email asking them to check their account. The attackers will be sending out a lot of emails using spam accounts and playing a numbers game. Hoping that a certain percentage of users access their bank accounts and then visit a page with malicious code.
This example focuses on online banking, but the basic principle applies to any web application that requires authentication and responds to commands with actions. CSRF attacks tend to be focused on state changing actions, such as changing users details or transferring money, rather than stealing data for later use. It should be understood that CSRF is a web application vulnerability in the secure web application that responds to the malicious requests. It is not a browser fault or the fault of the third party web site that hosts the malicious script. Note also that the only information attackers need to perform a CSRF is the web address that processes requests and the parameters that are required.
If you have been reading our previous articles in the OWASP Series, then you might think that the Cross Site Request Forgery vulnerability is very like the Cross Site Scripting (XSS) vulnerability. You would be correct. The two vulnerabilities are similar. In XSS the attacker exploits the trust a user has for a website, with CSRF on the other hand, the attacker exploits the trust a website has with a user’s browser. This difference and other subtle differences warrant their separation and inclusion in the OWASP Top 10 separately.
How to protect against Cross Site Request Forgery vulnerabilities
There are several ways to protect again CSRF attacks. Probably the best defence is to use randomly generated challenge tokens that are included with every request from the authenticated browser to the web application. Many modern web application frameworks include the ability to use a token scheme like this. For example, the Synchroniser Token Pattern is found in Ruby on Rails and ASP.NET Web Stack Runtime. In this method of defence for each session on a web application a unique token is generated and stored in the session cookie. The session cookies used are also digitally signed with a valid secure certificate to prevent them being tampered with. The token associated with each session is included, but hidden, on every screen and form that the web application renders during a users session. This means that any forms or commands that the user submits to the web application include the token and session cookie as well. This allows the web application to know that the submitted form or command is valid and from the authenticated user. If there is a mismatch then the submitted commands are rejected. Any requests coming from third party web sites will not have this token and session cookie included. Even if the user is logged into the web application. So they will be flagged as not valid and rejected. It’s also good practice to forcibly log a user out when a failed request is detected.
You should also make sure that you don’t have any XSS vulnerabilities. If you do then these can be used to get a valid copy of the token and session cookie. This will compromise a token based CSRF protection model. See the Cross Site Scripting article in this OWASP Series for information on XSS attacks.
For really sensitive commands, such as money transfer requests, a Challenge-Response protection model could also be considered. In this the user is asked to perform an action before the request is executed. Some examples are:
- Re-authenticate by entering their password
- Enter a digit from a PIN or code only they should know
- Enter a randomly selected CAPTCHA
- Enter a one-time token that is sent to a trusted device
These Challenge-Response protections can be really effective, but they do have an impact on user experience. Implementing a robust token based protection system, with Challenge-Response in a few areas where appropriate, is a good model to adopt to protect against CSRF vulnerabilities.