Five Ways to Reduce Your Vulnerability to CSRF Attacks
Are any corporate Web applications running on your network susceptible to cross-site request forgery (CSRF)? It's a question worth asking, because a successful CSRF attack -- aka an XSRF, Sea Surf, session riding, hostile linking, or One-Click attack -- can have devastating consequences, potentially costing your company a great deal of money or resulting in the loss of confidential information.
So what is CSRF?
A CSRF attack causes your Web application to carry out an action (such as transferring money, making a purchase or changing an account password) by making the application believe that the request resulting in this action is coming from an authorized user of the application. That could be an employee at your company, a business partner, or an external customer.
To achieve this, a CSRF attack relies on the fact that many Web applications use nothing more than a cookie with a relatively long expiration time to enable users to continue accessing the application after they initially authenticate themselves.
For a CSRF attack to work, then, a potential victim first has to use their browser to authenticate themselves and log on to your Web application. As long as the user does not subsequently log out of the application, and until the cookie from the application in the user's browser expires, the user is a potential victim of a CSRF attack.
How does a CSRF attack work?
To carry out a CSRF attack, a hacker places a specially crafted link to your Web application (which a potential victim is known to use) on some other Web page or in an email. But rather than making the link a standard hyperlink, the hacker typically hides the link by placing it in an image or script tag, with the link as the image's or script's source.
An example of such a link (from Wikipedia) is:
Now if the victim views the Web page with this "image" on it in their browser, or reads an email containing this link in an email program which uses the browser's HTML rendering capabilities, the browser will attempt to fetch the "image" by following the link. And if the victim has recently logged in to the site, their browser will provide a cookie to authenticate, and tell the Web application to transfer $100,000 from the account "bob" to the account "mallory." In general there is no reason that the victim would know that the transaction has been carried out (at least until they check their bank balance) because the victim's browser would carry out the transaction without displaying any feedback (such as a confirmation Web page) from bank.example.com.
In the example above, the link is specifically targeted at bob, which limits its usefulness. In practice a hacker is likely to try to use a more generic link that would work with any potential victim that happens to be logged in to your Web application. But crafting a successful CSRF is hard for the attacker precisely because they get no feedback from your Web application during the attack. That means that the attack is only likely to be successful as long as the responses from your Web application are entirely predictable, and involve nothing more than further clicks (for example, to confirm a transaction) which can be included in a script.
So for your Web application to be susceptible to a CSRF attack, it must:
- Allow access to users with nothing more than a valid cookie. with a usefully long time before expiry
- Allow transactions to be carried out on submission of a suitable URL that can be sent from an external site
- Respond in a predictable way
What can a CSRF attack achieve?
Although a CSRF attack can "only" carry out a transaction in a Web application, the results can be very far-ranging indeed. For example, it could result in the victim unwittingly making a forum posting, subscribing to a mailing list, making purchases or stock trades, or carrying out activities such as changing a user name or password. CSRF attacks work on applications protected behind the same firewall that the victim is located, and can allow a hacker to access an application which has access restricted by IP range if the victim's machine is within that range.
A strange twist on CSRF is called login CSRF, which logs a victim into a Web application using the attacker's credentials. This allows the hacker to log in subsequently and retrieve information about the victim, such as the user's activity history, or any confidential information that has been submitted by the victim.
How to mitigate the risk of your Web applications being vulnerable to CSRF attacks
- Limit the time-to-expiration of authentication cookies. The shorter the period in which these cookies are valid, the smaller the window of opportunity for a hacker to exploit your Web application. However, the shorter the period the more inconvenient it is for users. In the end, as is often the case, there is a compromise to be made between convenience and security.
- Make users submit additional information before allowing important transactions to be carried out. Requiring a user to solve a CAPTCHA or enter a password before important transactions can be carried out can prevent a hacker from carrying out an attack (as long as the password is not stored in the browser) because this information is not predictable (CAPTCHA) or freely available (password).
- Use secret non-predictable validation tokens. CSRF attacks work when a session is identified only by the cookie stored in the user's browser. So they can be foiled by having additional session-specific information in each HTTP request that a attacker can't know in advance, and therefore add to a link. If the app has an existing cross site scripting vulnerability it might still enable a hacker to access this validation token, however.
- Use custom HTTP headers. The XMLHttpRequest API can be used to protect against CSRF attacks if all requests that carry out a transaction use XMLHttpRequest and attach a custom HTTP header, rejecting any such requests which lack the custom header. This is useful because browsers normally only allow sites to send custom HTTP headers to the same site, thus preventing a transaction being initiated from the site which is the source of the CSRF attack.
- Check the referrer header. When a browser sends an HTTP request it usually includes the URL that it originated from in the referrer header. In theory you can use this information to block requests that originate from another site instead of from within the Web application itself. Unfortunately the referer header is not always present (some organizations strip it out for privacy reasons, for example) or can be spoofed, so this measure is not really effective.