Application security

CSRF and XSS: A Lethal Combination - Part I

Mark Wireman
February 20, 2012 by
Mark Wireman

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.

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

Spoofing The attacker needs to figure out the exact invocation of the targeted malicious action and then craft a link that performs the said action. Having the user click on such a link is often accomplished by sending an email or posting such a link to a bulletin board or similar message system.


Table 1: CSRF Attack Summary

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&currentaccountkey=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&currentaccountkey=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.

Cross-Domain

Request Type Explanation

<img src=…>

Image tags allow pulling the src image from other domains. Since the browser does not validate the request is an actual image, any valid URL pointing to any location and resource can be placed in the src attribute.

<script src=…>

Script tags allow pulling the src script file from other domains. Since the browser does not validate the request is an actual script, any valid URL pointing to any location and resource can be placed in the src attribute.

<FORM ….>

<iframe>, <img>, and <script> are considered GET request methods. POST methods submit a <FORM> with input variables with a name and value attribute, to a URL specified in the action attribute of <FORM>. The <FORM> is then submitted when the user lands on the malicious page.

Ajax

Taking advantage of the <FORM> POST method, an Ajax-based site can be sent information in an XML stream, as an example.*

JSON

Many applications are developed using a JSON stream to exchange information between clients and servers. Because of the way a JSON string is formatted, it is possible to once again use the <FORM> request type to carefully craft a JSON type string and send the action URL. JSON strings take the form of {"field": "value", ...}. An input field in a <FORM> can be used to by placing the {"field": "value",...} pair as the name attribute value and setting value='no'.*

*<FORM> is not the only method to use. It is just easier to explain the attack using <FORM>. Also, using <FORM>, <img>, and <script> will allow a read-only access to the data. Information access is possible using a combination of <script> and Ajax. However, this exercise is left to the reader.

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

Design

  • 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.

Implementation

  • 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:

  1. Input Validation – do not trust any data from any source. Validate the information for content, length, format, and other factors prior to use.
  2. Parameterized statements – avoid dynamic SQL statements. Always bind data to parameters that clearly identify the data type of the bind value.
  3. Business rule validation – always apply business validation to input. Business validations include length, type, and expected value.
  4. 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.
  5. Logging – always log access to data, modification of data, and, if necessary, access to the data.
  6. As a general rule, do not allow deletion - mark record for deletion and create a separate process to delete.
  7. 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.
  8. 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.
  9. 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

  1. Auger, R. (2009, December 30). Cross Site Request Forgery. Retrieved from http://projects.webappsec.org/w/page/13246919/Cross%20Site%20Request%20Forgery.
  2. Auger, R. (2011, February 1). Cross-Site Scripting. Retrieved from http://projects.webappsec.org/w/page/13246920/Cross%20Site%20Scripting.
  3. OWASP. (2010, September 4). Cross-Site Request Forgery (CSRF). Retrieved from https://www.owasp.org/index.php/CSRF.
  4. OWASP. (2011, December 8). Cross-site Scripting (XSS). Retrieved from https://www.owasp.org/index.php/Cross-site_scripting.
Mark Wireman
Mark Wireman

Mark A. Wireman is the Application Security National Practice Lead at OpenSky, working in the IT Risk Management & Security practice. For the last 12 years, Mark has worked in the Application Development space, primarily focusing on application security from a process and practice perspective within the DoD, Financial, and Health Care sectors.

Mark has presented at the CSO Breakfast Philadelphia Chapter and the Joint ISACA/OWASP conference, as well as published articles on application security best practices and participated on blogs and forums about application security. Prior to OpenSky, Mr. Wireman worked in Iraq with the DoD as a Technical Advisor to the Multi-National Corp on matters relating to secure coding in secure and non-secure systems, SharePoint, Business Intelligence, and other systems.

Mark is also an Associate Professor and teaches computer science and cyber security courses at University of Maryland University College and is currently working with the university to develop a first-of-its kind Application Security course.

Mark holds a B.S. in Computer Science and a MS in Information Technology with a concentration in Information Assurance.