Cross-Site Request Forgery (CSRF, a.k.a. XSRF, one-click attacks, session riding, confused deputy, client-side Trojan, hostile linking, automation attack or sea surf) is a client-side Web application attack, where an attacker exploits implicit authentication mechanisms to force an end user to execute unwanted actions in an authenticated Web application. CSRF is a non-avoidable dangerous security risk, and its constant 5th position in OWASP’s Top 10 most critical security risks for the past three years, underlines this fact.
A little social engineering (for example, through email or IM) is all it needs to trap a victim into unwittingly executing actions of the attacker’s choice. A successful CSRF exploit can compromise end-user data and operations, when it targets a normal user. If targeted at an administrator account, the attack can compromise the entire Web application.
The word CSRF itself means that the attack is done using a cross-site request; it’s “forged” because it’s invisible to the user. A cross-site request is one where a page loaded from one website makes a request to another site for resources that are part of the page (like images, for example). While it’s easy for a malicious site to have such HTML code in its pages, such cross-site requests can also be caused by viewing bulletin boards, forums, or social networking sites (for example) where users are allowed to post images with foreign URL sources — that is, the images are hosted on other sites. CSRF attacks are effective in situations which meet the following criteria:
- The victim has an active session on the target site.
- The victim is authenticated by implicit authentication mechanisms (like cookies or HTTP authentication) on the target site.
The main aim of a CSRF attack is to perform an action against the target site using the victim’s privileges in a properly authenticated session. The key requirement is prior access to, and knowledge of the Web application’s valid URLs, by the attacker. In a typical CSRF attack, the attacker creates a hidden HTTP request inside the victim’s Web browser, which is executed in the victim’s authentication context, without his knowledge.
Three sample CSRF scenarios
We will now look at three sample scenarios in which CSRF is possible, and how the attack could be carried out.
Scenario 1
Assume the victim is logged in to his online bank account, and is using the money transfer feature. The bank’s site uses cookies (implicit authentication) to authenticate logged-in user sessions. After filling out the money transfer form, when the Submit/OK/Transfer button is clicked, the victim’s Web browser issues an HTTP request to the bank’s Web server, to perform the transfer. Here’s what the request looks like when using an HTTP POST request:
POST http://fictitiousbank/transfer.cgi HTTP/1.1 Host: fictitiousbank User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; de; rv:1.9) Gecko/2008052906 Firefox/3.6.2 Cookie: PHPSESSIONID=7757ADD8766d455NFJJ23875JBJKBFR from=35367021&to48412334&amount=5000&date=05072010
Using an HTTP GET request, it would look like what follows:
GET http://fictitiousbank/transfer.cgi?from=35367021&to48412334&amount=5000&date=05072010 HTTP/1.1 Host: fictitiousbank User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; de; rv:1.9) Gecko/2008052906 Firefox/3.6.2 Cookie: PHPSESSIONID=7757ADD8766d455NFJJ23875JBJKBFR
Now assume that the victim, while still logged in to the online banking site, opens another tab/window in the same browser, for a malicious site (let’s call it www.attacker.com
). This could be due to clicking on a malicious link sent to the victim via IM or email. Such a link might take the victim to http://www.attacker.com/checkthisout.html
, which contains the following malicious HTML code:
<HTML> ……. ……. <IMG SRC="http://fictiousbank/transfer.cgi?from=35367021&to48412334&amount=5000&date=05072010" width="0" height="0"> ……. ……. </HTML>
When the victim’s browser loads this page, it will try to display the specified zero-width, zero-height (thus invisible) image as well, by making a request to the URL specified in the src
attribute. Since the customer is still logged in to the banking site, an amount of 5,000 from account 35367021 will be transferred to account 48412334, which could belong to the attacker. The bank site sees this request as completely legitimate, since the browser’s session cookie tells it that the user authenticated himself with the correct credentials! The attack above is depicted in Figure 1.
To prevent wary users or someone accidentally stumbling across the CSRF URL as the image source (if they view the source HTML of the page), the URL could be obfuscated as a seemingly innocent HTTP request. The attacker could make it look like a valid image URL such as <img src="https://www.attacker.com/picture1.gif" width="0" height="0" />
. Here, when this request for picture1.gif
is received, attacker.com
uses the HTTP redirect mechanism to redirect the browser to a different URL. That different URL is the Web application state-changing URL — like the money-transfer action URL in this scenario.
The attack method above (img src
) could be used if the Web application uses HTTP GET to submit requests. If it uses HTTP POST instead, then the attacker can use a hidden iframe
containing an HTML form, plus JavaScript that submits it to the bank site, like this snippet:
<form name="badform" method="post" action="http://fictitiousbank/transfer.cgi"> <input type="hidden" name="from" value="35367021"> <input type="hidden" name="to" value="48412334"> <input type="hidden" name="amount" value="5000"> <input type="hidden" name="date" value="05072010"> </form> <script>document.badform.submit()</script>
The CSRF attack using the HTTP POST method is summarised in Figure 2.
Please note that this scenario was used just to explain CSRF clearly, and that no bank is careless enough to let such an attack happen. I reiterate that you should not try any of these steps on any public server.
Scenario 2
Another CSRF attack scenario exploits the firewall Web management system. This is again based on session cookies. Let’s suppose the firewall Web management application has a function that allows an authenticated user to delete a rule, specified by its positional number, or all the rules of the configuration, if the user enters ‘*’. For example, a valid URL to delete a single rule, number 5, would be: http://www.example.com/firemange/delete?rule=5
Malicious HTML for the CSRF, using HTTP GET is as follows:
<HTML> …… …… <IMG SRC="http://www.example.com/firemange/delete?rule=5" width="0" height="0"> …. </HTML>
Scenario 3
Routers for private use, like popular DSL routers, come with a preconfigured IP address for the LAN interface (e.g., 192.168.0.1), which most users do not change. Thus, the host-part of the URL is known in most cases. Attackers are familiar with the workings and URLs of most popular routers, and if they can social-engineer the victim into clicking a malicious link, this will (for example) enable the remote Web management on port 8080, allowing it to be administered from any computer on the Internet.
The malicious Web page might contain the following HTML:
<IMG SRC=http://192.168.0.1/enable_remote_management=true&ips_allowed=*&mgmtport=8080>
The attacker can also change the router’s default account name, and could also compromise network printers — so if you have a DSL/home router left at its default settings, change the preconfigured IP and default passwords right now!
Using well-known URLs for Web applications, an attacker can also reset your Web-based account passwords, tamper with your corporate Web mail, and delete or modify accounts in Web applications. CSRF is a serious vulnerability, and cannot be taken lightly.
The differences between XSS and CSRF
Though CSRF seems similar to Cross-Site Scripting (XSS) at first, both are completely different attack vectors. Where XSS aims at inserting active code in an HTML document to either abuse client-side active scripting holes, or to send privileged information (e.g., authentication/session cookies) to an unknown evil website, CSRF aims to perform unwanted actions on a website where the victim has some prior relationship and authority.
Moreover, where XSS sought to steal your online trading cookies so an attacker could manipulate a victim’s account, CSRF seeks to use the victims’ cookies to force them to execute a trade without their knowledge or consent. While XSS attacks exploits the trust that a user has on the website, CSRF attacks exploit the trust that the website has in its user.
Types of CSRF attacks
CSRF attacks can be divided into two major categories — reflected and stored/local.
Reflected CSRF attacks
In a reflected CSRF attack, the attacker uses a system outside the application to expose the victim to the exploit link or content. This can be done using a blog, an email message, an instant message, a message-board posting, or even a flyer posted in a public place with a URL that a victim types in.
Reflected CSRF attacks will frequently fail, as users may not be currently logged into the target system when the exploits are tried. The trail from a reflected CSRF attack, however, may be under the attacker’s control, and could be deleted once the exploit is completed. The three attack scenarios we looked at earlier are examples of reflected CSRF attacks.
Local/stored CSRF attacks
A stored/local CSRF attack is one where the attacker can use the application itself to provide the victim the exploit link, or other content which directs the victim’s browser to perform attacker-controlled actions in the application. Stored CSRF vulnerabilities are more likely to succeed, since the user who receives the exploit content is almost certainly currently authenticated to perform actions.
Stored CSRF attacks also have a more obvious trail, which may lead back to the attacker, since the origin of the malicious HTTP request is hosted in the attacked website. Examples include bulletin boards and social sites where users are allowed to post images with foreign URL sources. These are harder to find and destroy.
Why CSRF works
To explain the root causes of, and solutions to CSRF attacks, I need to share with you the two broad types of authentication mechanisms used by Web applications:
- Implicit authentication
- Explicit authentication
Implicit authentication by Web browsers
Implicit authentication by Web browsers occurs when the browser automatically includes authentication information in HTTP requests; in other words, the Web browser itself is responsible for tracking the authenticated state. Widely used implicit authentication mechanisms in the browser include:
- HTTP authentication:This enables the Web server to request authentication credentials from the browser in order to restrict access to certain Web pages. In all the three methods (basic, digest and NTLM), the initial authentication process undergoes the same basic steps. Figure 3 shows a simplified version of the authentication process. If the client requests further restricted resources that lie in the same authentication realm, the browser includes the credentials automatically in the request.
- Cookies:Web browser cookie technology provides persistent data storage on the client side, which is often used by today’s Web applications to store authentication tokens. After a successful login procedure, the server sends a cookie to the client. Every subsequent HTTP request that contains this cookie is automatically regarded as authenticated. The typical cookie authentication process is shown in Figure 4.
- Client-side SSL authentication: The Secure Socket Layer (SSL), and its successor, the Transport Layer Security (TLS) protocol, enable cryptographically authenticated communication between the Web browser and the Web server. To authenticate, X.509 certificates and digital signature schemes are used.
What all these schemes have in common is that after a successful initial authentication, tokens are sent automatically in further requests, without asking the user for permission — this is what makes Web applications that use these authentication techniques, vulnerable to CSRF attacks.
Implicit authentication by IP address
This special case of implicit authentication is often found on intranets. Here, the authentication is based on certain IP (or MAC) addresses from which requests are made to the application. Shown in Figure 5 is a typical IP-based authentication, in which only users within the intranet are allowed to access the intranet server, and requests from all other IP addresses are denied access.
Explicit authentication is safer
In this type of authentication, the Web application (or the Web server) is itself responsible for tracking the authenticated state of the user. This is generally done in two ways:
- URL rewriting, in which the session tokens are included in the URL for every request sent to the server; the URL is generated by the Web application/Web server, and does not require the browser to pass authentication tokens along with the request.
- Form-based session tokens, in which hyperlinks are replaced with HTML forms that contain session identifiers in hidden form fields.
Though explicit authentication is immune to CSRF, it has other problems, which we will discuss in a while.
The main reason that CSRF works is that Web applications using implicit authentication mechanisms do not verify that a state-changing request was created within the Web application. Because of the implicit authentication of the user, the attacker can easily control the user’s session.
Another underlying factor that enables CSRF attacks is the application’s use of predictable URL/form actions in a repeatable way.
Some myths about CSRF | |
Myths | Facts |
CSRF is just a special case of XSS | XSRF is a separate vulnerability from XSS, with a different solution. XSS protection won’t stop XSRF attacks, though it is also important to guard against XSS on a priority basis. |
Applications aren’t vulnerable to CSRF if they use multi‐page forms to perform actions. | While multi‐page forms certainly make exploitation harder, attackers usually can exploit them. Attackers frequently use multiple IFRAMEs when building multi‐page form CSRF exploits. |
CSRF is solvable by forcing all sensitive requests over POST while denying GETs. | While POSTs can be more difficult to exploit, they certainly are exploitable, as shown in Scenario 1. Using POST rather than GET can provide a defense only against local CSRF attacks; POST requests can still be created with hidden IFRAMEs on foreign Web pages. Forms can mislead users about what they are sending, and where, and scripting can lead to automatic submission. JavaScript is fully capable of sending POST requests via form submissions. |
CSRF can be prevented by filtering based on the referrer header. | This option is very unreliable, since attackers can easily block the sending of the referrer header, through the use of certain browser and Flash exploits. Some browsers also omit the referrer header when they are being used over SSL. Moreover, many firewalls and anti-spyware software often drop referrers, in their default mode, without letting users know. But, using referrers can be viewed as another incremental roadblock. |
Browser enforcement of Same Origin Policy (SOP) prevents CSRF. | Browsers that implement SOP will prevent scripts from accessing the DOM of a page originating from another domain, or accessing cookies that originate from other domains. However, they do not prevent scripts from sending requests to other domains. Furthermore, when a script sends a request to another domain (or when an IMG tag’s SRC attribute is set to another domain), the browser will execute the request, and will also send any cookies it has that are valid for the domain, along with the request. (See the following highlight on SOP). |
Advanced uses of CSRF
The following advanced techniques that use CSRF attacks have been observed in recent years.
Bypassing CSRF protections with click-jacking
This recently-evolved technique can be used to bypass CSRF protection and submit POST method-based forms with attacker controlled data, using click-jacking. (See the highlight box on click-jacking for more information.) The best example of this attack is exploiting email update services. Such services are quite common in Web applications. In this, the attacker manages to force victims to update their e-mail IDs with that of the attacker, so that the attacker can then compromise the victims’ account by performing a password reset.
This attack can occur even if the Web application contains tokens for CSRF protection. A elaborate description of this is available on this blog post.
Click-jacking is an attack involving embedded objects on a maliciously crafted Web page. Using framed content, or that from Flash, Silverlight, or Java, the attacker places a transparent or invisible click button beneath the mouse, so that whenever the user clicks on something they see on the page, the user is also clicking to an unseen website that may contain malicious code. The attack can also take advantage of dynamic HTML and CSS (Cascading Style Sheets) code for further disguise.
The difference between CSRF and click-jacking is that in CSRF, the victim’s browser performs the attack (loading the state-changing URL directly) without the victim clicking to launch it, while in click-jacking, the user actually interacts with something, but the action is “hijacked” by placing a layer between the user and the page element that launches a legitimate action.
Using XSS to bypass CSRF protection
This technique applies to websites that have an application that guards against CSRF, yet have pages that are vulnerable to XSS attacks. It’s a big misconception that guarding against CSRF will also secure the application against XSS. Using XSS, attackers can bypass the CSRF protection, and can automate any action that can be done on the application, without problems. Attackers simply read the site-generated token from the response, and include that token with a forged request. One such example of this is attackers exploiting an XSS vulnerability of a website to add a fake user with administrator privileges, when the site is secured against CSRF attacks.
A good discussion on this type of attack (with code) is available in the Further Reading section at the end of the article. Please do spend some time on it. It was by using an XSS vulnerability that the Samy worm bypassed MySpace’s CSRF protection in 2005, infecting over one million accounts within just 20 hours of its release.
Attacking intranets
Exploiting intranets involves CSRF attacks through IP-based implicit authentication schemes. Most intranet Web servers are vulnerable to this type of attack. The fact that many intranet servers continue to use default passwords, leave hosts unpatched, and blindly rely on perimeter firewalls to block external attacks has given rise to intranet vulnerabilities to CSRF and malicious JavaScript. This malicious JavaScript, once behind the firewall, can attack the intranet; since it is independent of the operating system and the Web browser, it is hard to defend against.
One such example is port scanning of the intranet Web server, using JavaScript and CSRF. The JavaScript constructs a local (intranet) URL that contains the IP address and the port to be scanned. The script then includes an element in the Web page (such as an image, IFRAME or remote script) that is addressed by the URL.
Also, using JavaScript time-out functions, and event handlers like OnLoad
and OnError
, the script can decide whether the host exists and whether the given port is open. If a time-out occurs, the host probably does not exist. An OnLoad
event indicates that the host probably runs a Web server, and an OnError
event indicates that the host exists, but the port is closed. The typical attack scenario is shown in Figure 6.
In this scenario, the attacker forces/convinces the intranet user to visit a malicious page on the attacker’s server, which contains the following HTML in a hidden IFRAME:
<SCRIPT SRC="http://211.224.196.1/"></SCRIPT>
As soon as the user executes this page, the information about the existence of the Web server is sent to the attacker in the form of errors. Apart from this, the attacker can fingerprint applications/routers/network devices, and also might locate HTTPS or development servers by varying the ports.
Guarding against CSRF attacks
Following a few guidelines for both users and developers can help to curb CSRF attacks a lot.
For users
- Log out of the important Web application when you have completed your work/transactions. Do not open any non-trusted site in the same browser while logged in to the important site. If you need to do this for some reason, use a separate browser for the untrusted site(s).
- Use Mozilla Firefox with the NoScript addon, which allows JavaScript, Java and other executable content to run only from trusted domains of your choice. It is one of the best defenses available for protection against XSS, CSRF and click-jacking attacks. Also consider using the CsFire addons, which autonomously protect you against CSRF and other dangerous or malicious cross-domain requests. CsFire will remove authentication information (cookies and authentication headers).
- Use multiple browsers and segregate your browsing into trusted/sensitive sites/applications and untrusted/less important sites/applications. For example, use Firefox, with the NoScript and Adblock Plus (ABP) addons installed, to browse trusted/sensitive sites/applications. In NoScript, whitelist trusted sites so JavaScript from those sites will work. Set up ABP to block known malicious sites; use the auto-configuration URL at the end of this blog post to add the filter list to ABP. For other (untrusted) sites, install another browser like Google Chrome, Chromium or Opera. If you’re not certain about off-site links encountered in trusted sites (e.g., someone mails you a link to your GMail, which you are viewing in Firefox), then instead of visiting it in Firefox, drag the link from the page in Firefox to Chrome/Chromium’s tab bar (or copy/paste it), to have it open in a new tab in Chromium. Since only the link URL is transferred to the other browser, and any implicit-authentication tokens remain in Firefox, this is a safer practice.
- Regularly deleting long-duration cookies (those which are set to expire after an inordinately long time) will also help mitigate the threat.
- If possible, don’t store usernames and passwords in the browser’s password manager (for example, see this LWN article).
For developers
- The best defense against CSRF attacks is unpredictable tokens, a piece of data that the server can use to validate the request, and which an attacker can’t guess. For example, an important request could contain a digest of the user’s session credential, which is different for every user. And, for a little extra security, add a timestamp to the token, to limit the window of opportunity, as shown in the POST body below:
POST http://fictitiousbank/transfer.cgi HTTP/1.1 Host: fictitiousbank User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; de; rv:1.9) Gecko/2008052906 Firefox/3.6.2 Cookie: PHPSESSIONID=7757ADD8766d455NFJJ23875JBJKBFR from=35367021&to48412334&amount=5000&date=05072010&token=40E03EF45T443W20K4IC567HY4334DD44×tamp=1184001456
The tokens used should also be cryptographically very strong.
- Limit the time for which the user’s credentials are valid. By enforcing inactivity timeouts, you reduce chances of CSRF attacks.
- Password re-verification should be given priority over single-sign on. In this method, the users must type in their passwords again when accessing particularly critical functions.
- Switching over to URL rewriting is not recommended since, when URLs contain session tokens, the tokens could be leaked via proxy-logs/referrers. Moreover, they are also not very helpful against local/stored attacks, since all URLs produced by the application contain the token.
- Do not rely (solely) on referrer checking, as techniques exist to selectively create HTTP requests without referrers.
- For protection against local/stored attacks, you should mirror all foreign content, and don’t allow arbitrary URLs in your Web application. Moreover, local attacks can be mitigated if you only serve images from your own servers (like for social sites and forums) and also don’t allow users to store arbitrary data on your servers.
- When building defenses against CSRF, you must eliminate XSS vulnerabilities.
- Throw as many roadblocks at the attacker as possible, including customised error messages, checks on HTTP referrer headers and Web application firewalls.
- Use CAPTCHAs, especially for important transactions, to check whether there’s a human being at the other end, and not an automated attack.
- Harden the intranet websites, apply security patches and updates, and change default passwords.
Tools of the security trade
There are Web scanners available, both commercial and FOSS, to test websites for CSRF, but it’s very rare that they find CSRF code, given the complexity of CSRF attacks. However, there is some FOSS available to make security work easy:
- OWASP CSRF tester: This is basically a JavaEE filter that implements the synchroniser token pattern to mitigate the risk of CSRF attacks. Read it’s documentation here. A PHP implementation of this CSRF guard is available here and a .NET implementation is here.
- RequestRodeo is an HTTP proxy written in Python, using the Twisted framework, OpenSSL and SQLite. It protects its user against CSRF. You can find it here.
For more detailed information on CSRF, and more defenses against it, don’t forget to visit the Further Reading section below. We will deal with other dangerous attacks on Web applications and Apache in the next article.
Always remember: know hacking, but no hacking.
Further reading
- Whitepaper called Using XSS to Bypass XSRF Protection
- secologic project
- CSRF Prevention Cheat Sheet
- whitehatsec.com contains good information both on XSS and CSRF and other attacks