Prevent cross-site request forgery: Know the hidden danger in your browser tabs

Learn to prevent cross-site request forgery or your clients might do a hacker's bidding without knowing it

Explore two strategies to help prevent cross-site request forgery attacks as you review a detailed, step-by-step cross-site request forgery attack scenario. Also, look at some issues for scanning tools as they try to find cross-site request forgery vulnerabilities.

Paul Ionescu (pionescu@ca.ibm.com), Secure Engineering Program Coordinator, IBM

Photo of Paul IonescuPaul Ionescu leads the secure engineering program for the IBM Security Systems division. He is also part of the AppScan Research and Development team. Since he joined IBM in 2007, he worked in several areas of the application security business including support, technical sales, technical enablement, and development.



25 March 2014

Also available in Japanese

Introduction

IBM Security AppScan Standard

IBM® Security AppScan® Standard can help you identify potential XSRF vulnerabilities in your application. You can download and try an evaluation version of IBM Security AppScan Standard from developerWorks.

Sometimes you might wonder if you are becoming forgetful. You might ask yourself, "When did I post a link to this site on my social networking account?" Some people don't even notice. They find out from their friends that all of a sudden their social networking account has a link to an adult website.

As it turns out, other websites that you open in your browser's tabs can execute actions on your behalf.

Suppose you open a tab to your social networking site and a second tab to another site that is called many_ads.com. Unknown to you, many_ads.com is a malicious site. The many_ads.com site can post messages to your social networking site. This action is called a Cross-Site Request Forgery (XSRF or CSRF for short).

While that malicious posting is unpleasant and embarrassing, it's not a significant deal, right? You can delete the post anytime.

An XSRF attack can cost you money. If your banking site is vulnerable to an XSRF attack, you might pay money into an unknown overseas account and apparently you did it. In fact, according to the server logs, it is you that did it.


The exploit scenario

Suppose that a fictitious bank called Altoro Mutual has a page that processes money transfers to a specific account number. The request might look like:

http://www.altoromutual.com/bank/transfer.aspx?creditAccount=1001160141&transferAmount=1000

The attacker notices the link and realizes that if he got other people to go to it he can credit his overseas account with any amount of money he wants.

He might send that link in an email:

Dear customer of Altoro Mutual,

We recently applied several security improvements to our server that require you to revalidate your account.

Please click the following link to proceed.

Sending emails though might expose the attacker's intention especially when the user ends up on a page that states: Successfully transferred $1000 to account 1001160141

What if the attacker can make the users go to his link inadvertently?

Conveniently for the attacker, many users of Altoro Mutual frequent a financial discussion forum. On this fictional site, called Altoro Community, you can create avatars that are included in your forum posts.

A forum avatar is an image, perhaps like this generic human figure:

Figure 1. Sample image of a AltorJ Community Site avatar
Simple AltorJ Community Site avatar image

The avatar in a user post might look like this example:

Table 1. Example of an AltorJ Community avatar in a forum post
Sample avatarSample post
AltorJ Community avatar image in a forum post
Evil Hacker
50 Posts
Hey guys,

I was wondering if any one has seen the latest Altoro Financial Statements.

The community site allows users to specify a URL to a custom avatar. The avatar is typically specified by filling out a field like this example:

Table 2. Specify a custom avatar
Sample fieldSample URL
Specify your avatar: http://some_image_site_found_with_google/random_image.jpg

What if the attacker uses the transfer link as an avatar instead? For example:

Table 3. The attacker specifies an avatar
Sample fieldSample URL
Specify your avatar: http://www.altoromutual.com/bank/transfer.aspx?creditAccount=1001160141&transferAmount=1000

Now every time a user visits the community forum and goes to a post that the attacker wrote, the request executes when the browser tries to load the avatar. The image for the attacker's avatar won't load. Every user to that forum topic transfers money to the attacker, if the user is also logged in to the Altoro Online Banking in another tab of their browser.

Figure 2. Sample post by an attacker with a missing avatar image
Image showing an attacker's post appears with missing avatar image

You might tell yourself, "Right but I use forms to do money transfers, surely I'm not impacted!"

True, most money transfer requests are initiated by submitting form requests and these requests are not as easy for an attacker to use as the avatar example. But the attacker has ways to work around form requests. The attacker can craft a page with a form that submits the money transfer request and submits it from a malicious website.

The attacker cannot use the page as an avatar but can make it look like a financial blog of some sort and get the victim to go to it.

The page at the malicious site might look like Listing 1:

Listing 1. Example of code for malicious web page
<html>
<body onLoad="document.getElementById('transferForm').submit()">

<form id="transferForm" action="http://www.altoromutual.com/bank/transfer.aspx" method="post">

<input type="hidden" name="creditAccount" value="1001160141">
<input type="hidden" name="transferAmount" value="10">

</form>

</body>

Notice that this form is automatically submitted when the URL is loaded. No interaction from the user is necessary.


Protecting against XSRF

What might the developers of the bank site do differently to prevent this attack? Look at a few ways to handle XSRF attacks.

The referer solution

The simplest method relies on the browser referer header. Most browsers tell the web server what page sent the request. Listing 2 shows what the evil site request looks like when the browser sends it to the server:

Listing 2. Example of a malicious request sent to a server
POST /bank/transfer.aspx HTTP/1.1
Referer: http://evilsite.com/myevilblog
User-Agent: Mozilla/4....
Host: www.altoromutual.com
Content-Length: 42
Cookie: SessionId=x3q2v0qpjc0n1c55mf35fxid;

creditAccount=1001160141&transferAmount=10

The developers can compare the referer header to the domain name of the bank's host and reject any other requests. For example:

If(request.getHeaders("referer") != null 	&&request.getHeaders("referer").indexOf(
	"http://www.altoromutual.com") != 0){
	throw new Exception("Invalid referer");
        }

Additionally, you might specify a list of allowed URLs if needed, for example if a trusted site needed to execute the request.

You can apply the method to a base servlet or page class so all the pages of the site inherit this protection. Be careful though because if you need to allow other sites to link to Altoro, this method breaks those links. For example, customers of Altoro cannot get to it from Google.

GET /marketingannouncements HTTP/1.1
Referer: http://www.google.com

A better solution is to protect only pages that require authentication.

The referer solution does not protect against links to your site sent in an email. The referer solution also relies on the client, setting and handling the referer value properly. Privacy software might remove the header and cause this protection method to be unreliable.

The advantage of the referer solution is that it is compatible with earlier versions of other HTTP-based interactions like web services. For example, if a client mobile application relies on a REST API at the site, the referer solution is transparent to the client because the client doesn't use the referer header.

However, if compatibility with earlier versions is not a major concern, there are more bulletproof solutions such as making sensitive requests expire by using a token.

The token solution

The token solution relies on adding a parameter to the form that expires when the user logs out, or after a timeout period. See Listing 3.

Listing 3. Example of token solution
<form id="transferForm" action="https://www.altoromutual.com/bank/transfer.aspx" method="post">

Enter the credit account:
<input type="text" name="creditAccount" value="">
Enter the transfer amount:
<input type="text" name="transferAmount" value="">

<input type="hidden" name="xsrftoken" value="JKBS38633jjhg0987PPll">

<input type="submit" value="Submit">

</form>

Do not use the token as a query parameter because that makes the session information visible in the browser history or in web log metrics and analytics. For example, the following request is not a good idea:

Click to see code listing

To protect all types of requests with an all encompassing measure and ensure that the token value is not exposed in the URL, the best approach is to use an HTTP header. See Listing 4 for example:

Listing 4. Example of an HTTP XSRF Token header
POST /bank/transfer.aspx HTTP/1.1
Referer: https://www.altoromutual.com/bank
xsrftoken: JKBS38633jjhg0987PPll 
User-Agent: Mozilla/4....
Host: www.altoromutual.com
Content-Length: 42
Cookie: SessionId=x3q2v0qpjc0n1c55mf35fxid;

creditAccount=1001160141&transferAmount=10

An HTTP header is a preferred solution in most modern applications with the increased use of REST APIs and Ajax. The header token can be set by using code like in Listing 5:

Listing 5. Setting a header token
<form id="transferForm" action="https://www.altoromutual.com/bank/transfer.aspx" method="post">

Enter the credit account:
<input type="text" name="creditAccount" value="">
Enter the transfer amount:
<input type="text" name="transferAmount" value="">

<button onClick="addXsrfHeaderAndSubmitForm(dojo.byId(transferForm))" value="Submit">
</form>

Protect the entire framework

As with the referer solution, the best place to check the token is somewhere affecting all the authenticated pages.

A good design decision is to have all such pages inherit from a base class, which would look something like Listing 6:

Listing 6. Inheriting from a base class
class AuthenticatedServletBase extends ServletBase {

protected bool service(...){
	.....
	if(sessionUtil.getXsrfToken().equals(requestUtil.getXsrfToken())==false){
		showXSRFTokenError();
		return true;// handled..stop any further processing here

	}
	....
}

}

Positive side effects of the XSRF token

In addition to protecting against XSRF attacks, the token header solution has more security benefits in thwarting other types of client-side attacks on the protected pages:

  • JSON hijacking
  • Reflected cross-site scripting
  • Phishing through URL redirection

XSRF and security scanning tools

Security scanners often report this flaw and often the issue is not an actual vulnerability. The scanner can't understand if the request is sensitive or not. However, if the site implemented an all encompassing method such as the one described earlier in this article, the scanner does not find any of these XSRF issues.

If you fix all requests as described in this article rather than fix only the requests that you believe are sensitive, you might prevent inexperienced developers from introducing the problem in the future.

Resources

Learn

Get products and technologies

Comments

developerWorks: Sign in

Required fields are indicated with an asterisk (*).


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Information in your profile (your name, country/region, and company name) is displayed to the public and will accompany any content you post, unless you opt to hide your company name. You may update your IBM account at any time.

All information submitted is secure.

Choose your display name



The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

Required fields are indicated with an asterisk (*).

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


All information submitted is secure.

Dig deeper into Security on developerWorks


  • Bluemix Developers Community

    Get samples, articles, product docs, and community resources to help build, deploy, and manage your cloud apps.

  • Security

    Pragmatic, intelligent, risk-based IT Security practices.

  • DevOps Services

    Software development in the cloud. Register today to create a project.

  • IBM evaluation software

    Evaluate IBM software and solutions, and transform challenges into opportunities.

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Security, Web development
ArticleID=965379
ArticleTitle=Prevent cross-site request forgery: Know the hidden danger in your browser tabs
publish-date=03252014