CSRF and XSS: A Lethal Combination - Part I
Introduction
In the second installment of this series, we discussed one of the most prevalent attacks to applications: SQL Injection. The previous discussion introduced the reader to a technical understanding of how SQL Injection attacks inflict the most exposure of sensitive data, and how these vulnerabilities are not unique to just web applications.
This article will address the second most prevalent kind of attacks and a sleeping giant: Cross-Site Scripting (XSS) and Cross-site Request Forgery (CSRF). While XSS by itself can be quite malicious, the combination of the two in an attack scenario can wreak havoc for any unsuspecting user, application, and organization.
11 courses, 8+ hours of training
11 courses, 8+ hours of training
XSS is defined by the Open Web Application Security Projection (OWASP) as "a type of injection problem, in which malicious scripts are injected into the otherwise benign and trusted web sites." According to the Web Application Security Consortium, XSS "is an attack technique that involves echoing attacker-supplied code into a user's browser instance. A browser instance can be a standard web browser client, or a browser object embedded in a software product."
CSRF is defined by the Open Web Application Security Projection (OWASP) as "an attack which forces an end user to execute unwanted actions on a web application in which he/she is currently authenticated." According to the Web Application Security Consortium, CSRF "is an attack that involves forcing a victim to send an HTTP request to a target destination without their knowledge or intent in order to perform an action as the victim."
Unlike SQL Injection, which affects any application type, CSRF and XSS affect only web-based applications and technologies. Web applications are externally facing, exposing them to the virtual world. However, internal threats can be even more dangerous, opening up the organization to pilferage of data from malware, viruses, employees, and other influences. These internal threats have access to more resources than external attackers, which makes the combination of XSS and CSRF a lethal combination. In an attack scenario, an external attacker combines a CSRF attack with an XSS attack, allowing infiltration, escalation of privilege, and other gains to internal resources. One common form of this combination is called phishing, which utilizes email to entice a user to click a link to a malicious site that contains a CSRF attack signature along with malicious XSS in order to capture and send information or download malicious content without the unsuspecting user's knowledge.
In this first part we are going to focus on CSRF. Part II will discuss XSS and how the combination of the two can be lethal to an unsuspecting organization.
CSRF Explained
CSRF is an attack that requires two elements: 1) a web application that performs actions and 2) an authenticated user. An action can consist of purchasing items, transferring monies, administering users, and managing records. For each action there is a corresponding GET or POST request that communicates this action from the client browser to the server. As many of these actions are sensitive in nature, most web applications require that the user is authenticated and that the communication channel is encrypted, i.e. HTTPS. Table1 is a summary of a CSRF attack.
Method Type
Attack Details
So how does this attack work? Let's say you are logged into your banking website, called ABCBank.com. The bank adheres to the principle of two factor authentication (for example, username and password and a subsequent PIN) and the communication between you and the bank is encrypted (via HTTPS). After the browser recognizes and validates the certificate issued by the bank you are logged in and viewing your information in a secure session. Figure 1 demonstrates this process, with the name of the bank changed to protect the institution.
a)
b)
c) d)
Figure 1: a) Banking website requesting credentials (1st factor of authentication); b) Banking website asking for personal PIN (2nd factor of authentication); c) Communication is in a secure session (https); d) The Lock symbol indicates the certificate information from the banking website is valid and authenticate.
Now that you are authenticated to the banking website and authorized to access your account, the credential information (generally represented by a Session Identifier) is cached on the local machine, usually in the form of an encrypted cookie. The cookie will act on your behalf when credential information is repeatedly requested as you move through the website, thereby not requiring you to type your credential information repeatedly for each page you visit. While this is a convenience to you, this is where the CSRF attack takes advantage of this convenience, combined with the trusted nature the application gives to the process: in other words, the application fails at the cliché "trust but verify."
CSRF In Action
Now that we have a taste of how CSRF works, let's take a look at real-life CSRF in action. The scenario is as follows (all real values and the name of the site have been replaced or removed): 1) A user logs into his/her bank account; 2) the bank account uses URL parameters to pass a unique identifier for the bank account number and the type of view; 3) the user clicks a link in an email message that he believes is from his friend; 4) the link takes him to a malicious site that exposes the URL parameters of the banking website to perform actions on behalf of the user without the user's knowledge.
From Figure 1, we can see the user is logged into the banking website. The following URL is used by the banking site to determine navigation and action:
https://www.somebank.com/inet/sb_bank/BkAccounts?target=AccountSummary¤taccountkey=encryptedec117d8fd0eb30ab690c051f73f4be34&TransferView=TRUE.
The Request information for the above URL is as follows (the real values are removed or replaced with fake values where applicable):
[sourcecode]
Accept: text/html, application/xhtml+xml, */*
Referer: https://www.somebank.com/inet/sb_bank/BkAccounts?target=AccountSummary& currentaccountkey=encryptedec117d8fd0eb30ab690c051f73f4be34&
TransferView=TRUE
Accept-Language: en-US
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)
Accept-Encoding: gzip, deflate
Host: www.somebank.com
Connection: Keep-Alive
Cookie: JSESSIONID={value}; BrowserNavData=true|-1; somebank.com.uniqueId={value}; somebank.com.machine.session={value}; SSID={value}; SSRT={value}; SSPV={value}; UASK=39bwcDrir8moz_f8p6JftTH9hWt6EEhWpqSct35zzsfv86wySvpnVPA; somebank.com.machine.ident={value}; VisitorId=AIBJLR221KWGQYKERWP5C20120205; grpId=7; MemberGlobalSession=2:1000:5ZJBAM5213M3C515PLAR; TDO_RANDOM_COOKIE=97890180120120205153123; dcenv=1; LtpaToken2={value}=; LtpaToken={value}
[/sourcecode]
The user then receives an email from what he believes to be his best friend asking him to check out his items on an auction site at the following URL:
http://www.somecoolacutionsite.com/sampleauction.html.
Unknown to the user, the email was not from his friend, and when he clicks on the URL, the auction site does not contain any auctions. However, what the "auction" site did was use CSRF to perform an action on behalf of the user to the banking site the user is still logged into. Here is the HTML code from the "auction" site:
[sourcecode]
<html>
<head></head>
<body>
Welcome to the “auction” portal. Buyer beware!
<iframe
src=”https://www.somebank.com/inet/sb_bank/BkAccounts ?target=AccountSummary¤taccountkey=encryptedec117d8fd0eb30ab
690c051f73f4be34&TransferView=TRUE” id=”xsrf” style=”width:0px;
height:0px; border:0px”></iframe>
</body>
</html>
[/sourcecode]
And the malicious Request information is as follows:
[sourcecode]
HTTP/1.0
Accept: text/html, application/xhtml+xml, */*
Referer: http://www.malicioussite.com/sampleauction.html
Accept-Language: en-US
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)
Accept-Encoding: gzip, deflate
Host: www.somebank.com
Connection: Keep-Alive
Cookie: JSESSIONID={value}; SSLB=1; SSSC=1.G5704896267906605088.7|10.607; BrowserNavData=true|-1; somebank.com.uniqueId=MTIgISEgITQwJjM2MDM3OTk0; somebank.com.machine.session=9DUvMKuboaOuRCYdLlct6Nm; UASK=39bwcDrir8moz_f8p6JftTH9hWt6EEhWpqSct35zzsfv86wySvpnVPA; MemberGlobalSession={value}; TDO_RANDOM_COOKIE={value}; dcenv=1; LtpaToken2={value}=; LtpaToken={value}
[/sourcecode]
Notice something different between the two? The Referrer between the two Requests is different - also, all of the session and unique ID information were the same. We will address these areas a bit more in a later section.
Other Vectors for CSRF Attack
As the above scenario demonstrated, one use of a CSRF attack is in an <iframe> because an <iframe> allows for the cross-domain generation of content within the current domain's session. Other tags that can also be used for this purpose are shown in Table 2.
<img src=…>
<script src=…>
<FORM ….>
Ajax
JSON
Table 2: Additional Cross-Domain Requests used in CSRF attacks.
CSRF Protection Mechanisms
While there is never a 100% guarantee that any one or a combination of the following controls will provide full protection, the implementation of the recommended controls will significantly reduce the risk of exposure. Table 3 provides a list of remediation strategies and where the strategies can be implemented to reduce the risk of exposure, as well as the cost to implement.
Mitigation
Phase
Remediation Recommendation
- Use a unique identifier to associate a user request with a specific action. The identifier should be recreated for every request and action. The identifier is considered invalid if it arrived with a request without the associated action. An example is the use of a token that is attached to each request/action.
- In addition, checking the HTTP Referer header can also be used to validate an incoming request was actually one from an allowed or authorized domain.
- The user must be prompted to confirm an action every time for actions concerning potentially sensitive data. The confirmation along with the design approach of uniquely identifying requests and actions will thwart phishing and related attacks.
- All requests must be checked for the appropriate authentication token as well as authorization in the current session context.
- Check the Referral and make sure it is generated from the target page residing in the same domain.
- For XML and JSON verify and validate the Content Type.
Table 3: CSRF Remediation Strategies
Final Thoughts
CSRF can truly be a Sleeping Giant lurking quietly and softly within a web application without notice until damage has already been done. It is difficult to learn the culprit behind CSRF because it takes the form of Spoofing, appearing as though the User authorized the transactions. CSRF is also difficult to detect with static analysis products, and only a handful of dynamic scanners can detect the possibility of a CSRF lurking within. The most effective strategy for detecting CSRF is to manually test the application by creating a page with one of the Cross-Domain Request Types listed in Table 2 and point the src of one of those types to your site.
We've also presented several recommendations to follow to protect yourself against CSRF in Table 3. However, as with any security practice, an in-depth, multi-faceted approach is the best approach to protecting applications. The following guidelines provide the ultimate protection for any web application:
- Input Validation – do not trust any data from any source. Validate the information for content, length, format, and other factors prior to use.
- Parameterized statements – avoid dynamic SQL statements. Always bind data to parameters that clearly identify the data type of the bind value.
- Business rule validation – always apply business validation to input. Business validations include length, type, and expected value.
- Least privilege – only allow read only access to the data as a general rule, and other access as an exception. If a form within an application simply views the data, only call the database with a read-only database user. If adding or modifying data, call the database with a modify and add database user.
- Logging – always log access to data, modification of data, and, if necessary, access to the data.
- As a general rule, do not allow deletion - mark record for deletion and create a separate process to delete.
- Threat modeling – always threat model an application to understand access points to the database, input points to the application, and what boundaries and layers are involved through the data flow of the application.
- Error handling – do not throw detailed error messages to the screen for viewing by the user. The detailed information that is included in an error message is invaluable to an attacker providing valuable clues on how to modify the attack to allow the attack to execute without error.
- Trust but verify - verify and validate any requests, data, and calls into your application, even if you trust the source, because the source itself could have been compromised.
The next installment of the series will be a Part II discussion of Cross-Site Scripting (XSS) and Cross-Site Request Forgery (CSRF) and how the combination of the two can truly be a lethal combination for any organization with a web presence.
References
- Auger, R. (2009, December 30). Cross Site Request Forgery. Retrieved from http://projects.webappsec.org/w/page/13246919/Cross%20Site%20Request%20Forgery.
- Auger, R. (2011, February 1). Cross-Site Scripting. Retrieved from http://projects.webappsec.org/w/page/13246920/Cross%20Site%20Scripting.
- OWASP. (2010, September 4). Cross-Site Request Forgery (CSRF). Retrieved from https://www.owasp.org/index.php/CSRF.
- OWASP. (2011, December 8). Cross-site Scripting (XSS). Retrieved from https://www.owasp.org/index.php/Cross-site_scripting.