Difference between revisions of "Cross-Site Request Forgery (CSRF) Prevention Cheat Sheet"

From OWASP
Jump to: navigation, search
m
m (Minor grammar change.)
(47 intermediate revisions by 9 users not shown)
Line 1: Line 1:
 
= Introduction =
 
= Introduction =
  
Cross-Site Request Forgery (CSRF) is a type of attack that occurs when a malicious Web site, email, blog, instant message, or program causes a user’s Web browser to perform an unwanted action on a trusted site that the user is currently authenticated to. For example, this attack could result in a transfer of funds, changing a password, or purchasing an item in the user's context.
+
Cross-Site Request Forgery (CSRF) is a type of attack that occurs when a malicious Web site, email, blog, instant message, or program causes a user’s Web browser to perform an unwanted action on a trusted site for which the user is currently authenticated. The impact of a successful cross-site request forgery attack is limited to the capabilities exposed by the vulnerable application. For example, this attack could result in a transfer of funds, changing a password, or purchasing an item in the user's context. In effect, CSRF attacks are used by an attacker to make a target system perform a function (funds Transfer, form submission etc.) via the target's browser without knowledge of the target user, at least until the unauthorized function has been committed.
  
A successful CSRF exploit can compromise end user data and operation, when it targets a normal user. If the targeted end user is an administrator account, a CSRF attack can compromise the entire Web application. The sites that are more likely to be attacked are community Websites (social networking, email) or sites that have high dollar value accounts associated with them (banks, stock brokerages, bill pay services). This attack can happen even if the user is logged into a Web site using strong encryption (HTTPS).
+
Impacts of successful CSRF exploits vary greatly based on the role of the victim. When targeting a normal user, a successful CSRF attack can compromise end-user data and their associated functions. If the targeted end user is an administrator account, a CSRF attack can compromise the entire Web application. The sites that are more likely to be attacked are community Websites (social networking, email) or sites that have high dollar value accounts associated with them (banks, stock brokerages, bill pay services). This attack can happen even if the user is logged into a Web site using strong encryption (HTTPS). Utilizing social engineering, an attacker will embed malicious HTML or JavaScript code into an email or Website to request a specific 'task url'. The task then executes with or without the user's knowledge, either directly or by utilizing a Cross-site Scripting flaw (ex: Samy MySpace Worm).
  
Utilizing social engineering, an attacker will embed malicious HTML or JavaScript code into an email or Website to request a specific 'task url'.  The task then executes with or without the user's knowledge, either directly or by utilizing a Cross-site Scripting flaw.
+
For more information on CSRF, please see the OWASP [[Cross-Site Request Forgery (CSRF)]] page.
  
In affect, CSRF attacks are used by an attacker to make a target system perform a function (funds Transfer, form submission etc.) via the target's browser without knowledge of the target user, at least until the unauthorized function has been committed.
+
= Prevention Measures That Do NOT Work =
  
For more information on CSRF, please see the OWASP [[Cross-Site Request Forgery (CSRF)]] page.
+
'''Using a Secret Cookie'''
  
= Prevention =
+
Remember that all cookies, even the secret ones, will be submitted with every request. All authentication tokens will be submitted regardless of whether or not the end-user was tricked into submitting the request. Furthermore, session identifiers are simply used by the application container to associate the request with a specific session object. The session identifier does not verify that the end-user intended to submit the request.
 +
 
 +
'''Only Accepting POST Requests'''
 +
 
 +
Applications can be developed to only accept POST requests for the execution of business logic. The misconception is that since the attacker cannot construct a malicious link, a CSRF attack cannot be executed. Unfortunately, this logic is incorrect. There are numerous methods in which an attacker can trick a victim into submitting a forged POST request, such as a simple form hosted in an attacker's Website with hidden values. This form can be triggered automatically by JavaScript or can be triggered by the victim who thinks the form will do something else.
 +
 
 +
'''Multi-Step Transactions'''
 +
 
 +
Multi-Step transactions are not an adequate prevention of CSRF. As long as an attacker can predict or deduce each step of the completed transaction, then CSRF is possible.
 +
 
 +
'''URL Rewriting'''
 +
 
 +
This might be seen as a useful CSRF prevention technique as the attacker can not guess the victim's session ID. However, the user’s credential is exposed over the URL.
  
== Token Based ==
+
= General Recommendation: Synchronizer Token Pattern =
  
The most common defense for CSRF is to append challenge tokens to each sensitive request. These challenge tokens must be associated with the user's session. By including a challenge token with each request, the developer can ensure that the request is valid and not coming from another source other than the user. The following describes how to incorporate challenge tokens:
+
In order to facilitate a "transparent but visible" CSRF solution, developers are encouraged to adopt the Synchronizer Token Pattern (http://www.corej2eepatterns.com/Design/PresoDesign.htm). The synchronizer token pattern requires the generating of random "challenge" tokens that are associated with the user's current session. These challenge tokens are then inserted within the HTML forms and links associated with sensitive server-side operations. When the user wishes to invoke these sensitive operations, the HTTP request should include this challenge token. It is then the responsibility of the server application to verify the existence and correctness of this token. By including a challenge token with each request, the developer has a strong control to verify that the user actually intended to submit the desired requests. Inclusion of a required security token in HTTP requests associated with sensitive business functions helps mitigate CSRF attacks as successful exploitation assumes the attacker knows the randomly generated token for the target victim's session. This is analogous to the attacker being able to guess the target victim's session identifier. The following synopsis describes a general approach to incorporate challenge tokens within the request.
  
When a Web application formulates a request (by generating a link or form that causes a request when submitted or clicked by the user), the application should include a hidden input tag query parameter with a name such as CSRFToken. It is important to note that the CSRFToken should not be included in the URL or in URL parameters as it may be leaked. The CSRFToken should have a value that is a randomly generated such as a 256-bit hash that has been base 64 encoded.  
+
When a Web application formulates a request (by generating a link or form that causes a request when submitted or clicked by the user), the application should include a hidden input parameter with a common name such as "CSRFToken". The value of this token must be randomly generated such that it cannot be guessed by an attacker. Consider leveraging the java.security.SecureRandom class for Java applications to generate a sufficiently long random token. Alternative generation algorithms include the use of 256-bit BASE64 encoded hashes. Developers that choose this generation algorithm must make sure that there is randomness and uniqueness utilized in the data that is hashed to generate the random token.
  
 
   <form action="/transfer.do" method="post">
 
   <form action="/transfer.do" method="post">
Line 25: Line 37:
 
   </form>
 
   </form>
  
For each request, this token only needs to be randomly generated once. After the initial random generation, the token value is stored in a session specific table mapping request names to validation tokens. When a request is performed by the user, before the request is executed the submitted CSRFToken has it's value verified by comparing the provided token to the value stored in the mapping table for this request. If there is no value in the table for this request name, or if the value provided does not match the value in the table exactly, then the request should be aborted and the event can be logged as a potential security incident.
+
In general, developers need only generate this token once for the current session. After initial generation of this token, the value is stored in the session and is utilized for each subsequent request until the session expires. When a request is issued by the end-user, the server-side component must verify the existence and validity of the token in the request as compared to the token found in the session. If the token was not found within the request or the value provided does not match the value within the session, then the request should be aborted, token should be reset and the event logged as a potential CSRF attack in progress.
  
The request name should be different for each request. The CSRFToken must be strictly protected. For example, an application that does not use SSL or passes the token through a URL parameter will result in the CSRFToken being leaked.
+
To further enhance the security of this proposed design, consider randomizing the CSRF token parameter name and or value for each request. Implementing this approach results in the generation of per-request tokens as opposed to per-session tokens. Note, however, that this may result in usability concerns. For example, the "Back" button browser capability is often hindered as the previous page may contain a token that is no longer valid. Interaction with this previous page will result in a CSRF false positive security event at the server. Regardless of the approach taken, developers are encouraged to protect the CSRF token the same way they protect authenticated session identifiers, such as the use of SSLv3/TLS.
  
=== Viewstate (ASP.NET) ===
+
=== Disclosure of Token in URL ===
  
ASP.NET has an option to maintain your ViewState. The ViewState indicates the status of a page when submitted to the server. The status is defined through a hidden field placed on each page with a <form runat="server"> control.  
+
Many implementations of this control include the challenge token in GET (URL) requests as well as POST requests. This is often implemented as a result of sensitive server-side operations being invoked as a result of embedded links in the page or other general design patterns. These patterns are often implemented without knowledge of CSRF and an understanding of CSRF prevention design strategies. While this control does help mitigate the risk of CSRF attacks, the unique per-session token is being exposed for GET requests. CSRF tokens in GET requests are potentially leaked at several locations: browser history, HTTP log files, network appliances that make a point to log the first line of an HTTP request, and Referrer headers if the protected site links to an external site.
 +
 
 +
In the latter case (leaked CSRF token due to the Referer header being parsed by a linked site), it is trivially easy for the linked site to launch a CSRF attack on the protected site, and they will be able to target this attack very effectively, since the Referer header tells them the site as well as the CSRF token. The attack could be run entirely from javascript, so that a simple addition of a script tag to the HTML of a site can launch an attack (whether on an originally malicious site or on a hacked site).  This attack scenario is easy to prevent, the referer will be omitted if the origin of the request is HTTPS.  Therefore this attack does not affect web applications that are HTTPS only.  
 +
 
 +
The ideal solution is to only include the CSRF token in POST requests and modify server-side actions that have state changing affect to only respond to POST requests. This is in fact what the [http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.1.1 RFC 2616] requires for GET requests. If sensitive server-side actions are guaranteed to only ever respond to POST requests, then there is no need to include the token in GET requests.
 +
 
 +
In most JavaEE web applications, however, HTTP method scoping is rarely ever utilized when retrieving HTTP parameters from a request. Calls to "HttpServletRequest.getParameter" will return a parameter value regardless if it was a GET or POST. This is not to say HTTP method scoping cannot be enforced. It can be achieved if a developer explicitly overrides doPost() in the HttpServlet class or leverages framework specific capabilities such as the AbstractFormController class in Spring.
 +
 
 +
For these cases, attempting to retrofit this pattern in existing applications requires significant development time and cost, and as a temporary measure it may be better to pass CSRF tokens in the URL. Once the application has been fixed to respond to HTTP GET and POST verbs correctly, CSRF tokens for GET requests should be turned off.
 +
 
 +
=== Viewstate (ASP.NET) ===
  
Viewstate can be used as a CSRF defense, as it is difficult for an attacker to forge a valid Viewstate. It is not impossible to forge a valid Viewstate since it is feasible that parameter values could be obtained or guessed by the attacker. However, if the current session ID is added to the ViewState, it then makes each Viewstate unique, and thus immune to CSRF.  
+
ASP.NET has an option to maintain your ViewState. The ViewState indicates the status of a page when submitted to the server. The status is defined through a hidden field placed on each page with a <form runat="server"> control. Viewstate can be used as a CSRF defense, as it is difficult for an attacker to forge a valid Viewstate. It is not impossible to forge a valid Viewstate since it is feasible that parameter values could be obtained or guessed by the attacker. However, if the current session ID is added to the ViewState, it then makes each Viewstate unique, and thus immune to CSRF.  
  
 
To use the ViewStateUserKey property within the Viewstate to protect against spoofed post backs. Add the following in the OnInit virtual method of the Page-derived class (This property must be set in the Page.Init event)
 
To use the ViewStateUserKey property within the Viewstate to protect against spoofed post backs. Add the following in the OnInit virtual method of the Page-derived class (This property must be set in the Page.Init event)
Line 48: Line 70:
 
This must be applied in Page_Init because the key has to be provided to ASP.NET before Viewstate is loaded. This option has been available since ASP.NET 1.1.
 
This must be applied in Page_Init because the key has to be provided to ASP.NET before Viewstate is loaded. This option has been available since ASP.NET 1.1.
  
However, there are [http://keepitlocked.net/archive/2008/05/29/viewstateuserkey-doesn-t-prevent-cross-site-request-forgery.aspx limitations] on this mechanism.  Such as, ViewState MACs are only checked on POSTback, so any other application requests not using postbacks will happily allow CSRF.
+
However, there are limitations on this mechanism.  Such as, ViewState MACs are only checked on POSTback, so any other application requests not using postbacks will happily allow CSRF.
  
 
=== Double Submit Cookies ===
 
=== Double Submit Cookies ===
  
Double submitting cookies is defined as sending the session ID cookie in two different ways for every form request. First as a traditional header value, and again as a hidden form value.
+
Double submitting cookies is defined as sending the session ID cookie in two different ways for every form request. First as a traditional header value, and again as a hidden form value. When a user visits a site, the site should generate a (cryptographically strong) pseudorandom value and set it as a cookie on the user's machine. This is typically referred to as the session ID. The site should require every form submission to include this pseudorandom value as a hidden form value and also as a cookie value. When a POST request is sent to the site, the request should only be considered valid if the form value and the cookie value are the same. When an attacker submits a form on behalf of a user, he can only modify the values of the form. An attacker cannot read any data sent from the server or modify cookie values, per the same-origin policy. This means that while an attacker can send any value he wants with the form, the attacker will be unable to modify or read the value stored in the cookie. Since the cookie value and the form value must be the same, the attacker will be unable to successfully submit a form unless he is able to guess the session ID value.
  
When a user visits a site, the site should generate a (cryptographically strong) pseudorandom value and set it as a cookie on the user's machine. This is typically referred to as the session ID. The site should require every form submission to include this pseudorandom value as a hidden form value and also as a cookie value. When a POST request is sent to the site, the request should only be considered valid if the form value and the cookie value are the same. When an attacker submits a form on behalf of a user, he can only modify the values of the form. An attacker cannot read any data sent from the server or modify cookie values, per the same-origin policy. This means that while an attacker can send any value he wants with the form, the attacker will be unable to modify or read the value stored in the cookie. Since the cookie value and the form value must be the same, the attacker will be unable to successfully submit a form unless he is able to guess the session ID value.
+
While this approach is effective in mitigating the risk of cross-site request forgery, including authenticated session identifiers in HTTP parameters may increase the overall risk of session hijacking. Architects and developers must ensure that no network appliances or custom application code or modules explicitly log or otherwise disclose HTTP POST parameters. An attacker that is able to obtain access to repositories or channels that leak HTTP POST parameters will be able to replay the tokens and perform session hijacking attacks. Note, however, that transparently logging all HTTP POST parameters is a rare occurrence across network systems and web applications as doing so will expose significant sensitive data aside from session identifiers including passwords, credit card numbers, and or social security numbers. Inclusion of the session identifier within HTML can also be leveraged by cross-site scripting attacks to bypass HTTPOnly protections. Most modern browsers prevent client-side script from accessing HTTPOnly cookies. However, this protection is lost if HTTPOnly session identifiers are placed within HTML as client-side script can easily traverse and extract the identifier from the DOM. Developers are still encouraged to implement the synchronizer token pattern as described in this article.
  
 
[http://directwebremoting.org Direct Web Remoting (DWR)] Java library version 2.0 has CSRF protection built in as it implements the double cookie submission transparently.
 
[http://directwebremoting.org Direct Web Remoting (DWR)] Java library version 2.0 has CSRF protection built in as it implements the double cookie submission transparently.
  
=== Prevention Frameworks ===
+
=== Encrypted Token Pattern ===
  
There are CSRF prevention modules available for J2EE, .Net, and PHP.
+
'''Overview'''
  
[[:Category:OWASP_CSRFGuard_Project | OWASP CSRF Guard (For Java)]]
+
The Encrypted Token Pattern leverages an encryption, rather than comparison, method of Token-validation. After successful authentication, the server generates a unique Token comprised of the user's ID, a timestamp value and a [http://en.wikipedia.org/wiki/Cryptographic_nonce nonce], using a unique key available only on the server. This Token is returned to the client and embedded in a hidden field. Subsequent AJAX requests include this Token in the request-header, in a similar manner to the Double-Submit pattern. Non-AJAX form-based requests will implicitly persist the Token in its hidden field, although I recommend persisting this data in a custom HTTP header in such cases. On receipt of this request, the server reads and decrypts the Token value with the same key used to create the Token.
  
The OWASP CSRFGuard Project makes use of a unique per-session token verification pattern using a JavaEE filter to mitigate the risk of CSRF attacks. When an HttpSession is first instantiated, CSRFGuard will generate a cryptographically random token using the SecureRandom class to be stored in the session.
+
'''Validation'''
  
CSRFGuard is a "reference implementation". Developers are encouraged to leverage more tightly integrated solutions for performance (ex: speed of parsing HTML) and technical (ex: AJAX requests) challenges.
+
On successful Token-decryption, the server has access to parsed values, ideally in the form of [http://en.wikipedia.org/wiki/Claims-based_identity claims]. These claims are processed by comparing the UserId claim to any potentially stored UserId (in a Cookie or Session variable, if the site already contains a means of authentication). The Timestamp is validated against the current time, preventing replay attacks.
 +
Alternatively, in the case of a CSRF attack, the server will be unable to decrypt the poisoned Token, and can block and log the attack.
  
'''Similar Projects'''
+
This pattern exists primarily to allow developers and architects protect against CSRF without session-dependency. It also addresses some of the shortfalls in other stateless approaches, such as the need to store data in a Cookie, circumnavigating the Cookie-subdomain and HTTPONLY issues.
  
CSRFGuard has been implemented in other languages besides Java. They are:  
+
Please refer to the following resources for more information:
  
*[[PHP CSRF Guard]]
+
*[http://insidethecpu.files.wordpress.com/2013/09/encrypted-token-pattern.pdf Encrypted Token Architecture] High-level overview and process-flow.
*[[.Net CSRF Guard]]  
+
*[http://insidethecpu.wordpress.com/2013/09/23/encrypted-token-pattern/ Encrypted Token Overview] High-level overview and process-flow.
 +
 
 +
= CSRF Prevention without a Synchronizer Token =
 +
CSRF can be prevented in a number of ways. Using a Synchronizer Token is one way that an application can rely upon the Same-Origin Policy to prevent CSRF by maintaining a secret token to authenticate requests.  This section details other ways that an application can prevent CSRF by relying upon similar rules that CSRF exploits can never break.
 +
 
 +
=== Checking The Referer Header ===
 +
Although it is trivial to spoof the referer header on your own browser,  it is impossible to do so in a CSRF attack.  Checking the referer is a commonly used method of preventing CSRF on embedded network devices because it does not require a per-user state.  This makes a referer a useful method of CSRF prevention when memory is scarce.  This method of CSRF mitigation is also commonly used with unauthenticated requests,  such as requests made prior to establishing a session state which is required to keep track of a synchronization token.
 +
 
 +
However, checking the referer is considered to be a weaker from of CSRF protection.  For example,  open redirect vulnerabilities can be used to exploit GET-based requests that are protected with a referer check.  It should be noted that GET requests should never incur a state change as this is a violation of the HTTP specification.
 +
 
 +
There are also common implementation mistakes with referer checks.  For example if the CSRF attack originates from an HTTPS domain then the referer will be omitted.  In this case the lack of a referer should be considered to be an attack when the request is performing a state change.  Also note that the attacker has limited influence over the referer.  For example,  if the victim's domain is "site.com" then an attacker have the CSRF exploit originate from "site.com.attacker.com" which may fool a broken referer check implementation.  XSS can be used to bypass a referer check.
 +
 
 +
=== Checking The Origin Header ===
 +
The [https://wiki.mozilla.org/Security/Origin Origin HTTP Header] standard was introduced as a method of defending against CSRF and other Cross-Domain attacks.  Unlike the referer, the origin will be present in HTTP request that originates from an HTTPS url.
 +
 
 +
If the origin header is present,  then it should be checked for consistency.
  
== Challenge-Response ==
+
=== Challenge-Response ===
  
 
Challenge-Response is another defense option for CSRF. The following are some examples of challenge-response options.
 
Challenge-Response is another defense option for CSRF. The following are some examples of challenge-response options.
Line 85: Line 123:
 
While challenge-response is a very strong defense to CSRF (assuming proper implementation), it does impact user experience. For applications in need of high security, tokens (transparent) and challenge-response should be used on high risk functions.
 
While challenge-response is a very strong defense to CSRF (assuming proper implementation), it does impact user experience. For applications in need of high security, tokens (transparent) and challenge-response should be used on high risk functions.
  
= Prevention Measures That Do NOT Work =
+
= Prevention Frameworks =
  
'''Using a Secret Cookie'''
+
There are CSRF prevention modules available for J2EE, .Net, and PHP.
  
Remember that all cookies, even the secret ones, will be submitted with every request. All authentication tokens will be submitted regardless of whether or not the end-user was tricked into submitting the request. Furthermore, session identifiers are simply used by the application container to associate the request with a specific session object. The session identifier does not verify that the end-user intended to submit the request.
+
[[:Category:OWASP_CSRFGuard_Project | OWASP CSRF Guard (For Java)]]
  
'''Only Accepting POST Requests'''
+
The OWASP CSRFGuard Project makes use of a unique per-session token verification pattern using a JavaEE filter to mitigate the risk of CSRF attacks. When an HttpSession is first instantiated, CSRFGuard will generate a cryptographically random token using the SecureRandom class to be stored in the session.
  
Applications can be developed to only accept POST requests for the execution of business logic. The misconception is that since the attacker cannot construct a malicious link, a CSRF attack cannot be executed. Unfortunately, this logic is incorrect. There are numerous methods in which an attacker can trick a victim into submitting a forged POST request, such as a simple form hosted in an attacker's Website with hidden values. This form can be triggered automatically by JavaScript or can be triggered by the victim who thinks the form will do something else.
+
'''Similar Projects'''
  
'''Checking Referer Header'''
+
CSRFGuard has been implemented in other languages besides Java. They are:
  
An attacker can easily block the sending of the Referer header, and the HTTP RFC’s make it clear that this header is optional. Browsers also omit the Referer header when they are being used over SSL.
+
*[[PHP CSRF Guard]]
 
+
*[[.Net CSRF Guard]]
'''Multi-Step Transactions'''
+
 
+
Multi-Step transactions are not an adequate prevention of CSRF. As long as an attacker can predict or deduce each step of the completed transaction, then CSRF is possible.
+
 
+
'''URL Rewriting'''
+
 
+
This might be seen as a useful CSRF prevention technique as the attacker can not guess the victim's session ID. However, the user’s credential is exposed over the URL.
+
  
 
= Client/User Prevention =
 
= Client/User Prevention =
Line 114: Line 145:
 
* Do not allow your browser to save username/passwords, and do not allow sites to “remember” your login  
 
* Do not allow your browser to save username/passwords, and do not allow sites to “remember” your login  
 
* Do not use the same browser to access sensitive applications and to surf the Internet freely (tabbed browsing).  
 
* Do not use the same browser to access sensitive applications and to surf the Internet freely (tabbed browsing).  
 +
* The use of plugins such as No-Script makes POST based CSRF vulnerabilities difficult to exploit.  This is because JavaScript is used to automatically submit the form when the exploit is loaded. Without JavaScript the attacker would have to trick the user into submitting the form manually.
  
 
Integrated HTML-enabled mail/browser and newsreader/browser environments pose additional risks since simply viewing a mail message or a news message might lead to the execution of an attack.  
 
Integrated HTML-enabled mail/browser and newsreader/browser environments pose additional risks since simply viewing a mail message or a news message might lead to the execution of an attack.  
Line 119: Line 151:
 
= No Cross-Site Scripting (XSS) Vulnerabilities =
 
= No Cross-Site Scripting (XSS) Vulnerabilities =
  
Cross-Site Scripting is not necessary for CSRF to work. However, Cross-Site Scripting flaws can be used to defeat most token based CSRF defenses, since a malicious XSS script can simply read the site generated token from the response, and include that token with a forged request. This technique is exactly how the [http://en.wikipedia.org/wiki/Samy_(XSS) MySpace (Samy) worm] defeated MySpace's anti CSRF defenses in 2005, which enabled the worm to propagate. XSS cannot defeat challenge-response defenses such as re-authentication or one-time passwords. It is imperative that no XSS vulnerabilities are present to ensure that CSRF defenses can't be circumvented. Please see the OWASP [[XSS_(Cross_Site_Scripting)_Prevention_Cheat_Sheet | XSS Prevention Cheat Sheet]] for detailed guidance on how to prevent XSS flaws.
+
Cross-Site Scripting is not necessary for CSRF to work. However, any cross-site scripting vulnerability can be used to defeat token, Double-Submit cookie, referer and origin based CSRF defenses.  This is because an XSS payload can simply read any page on the site using a XMLHttpRequest and obtain the generated token from the response, and include that token with a forged request. This technique is exactly how the [http://en.wikipedia.org/wiki/Samy_(XSS) MySpace (Samy) worm] defeated MySpace's anti CSRF defenses in 2005, which enabled the worm to propagate. XSS cannot defeat challenge-response defenses such as Captcha, re-authentication or one-time passwords. It is imperative that no XSS vulnerabilities are present to ensure that CSRF defenses can't be circumvented. Please see the OWASP [[XSS_(Cross_Site_Scripting)_Prevention_Cheat_Sheet | XSS Prevention Cheat Sheet]] for detailed guidance on how to prevent XSS flaws.
  
 
= Related Articles =
 
= Related Articles =
Line 138: Line 170:
  
 
Check out the [[:Category:OWASP_CSRFTester_Project | OWASP CSRF Tester]] tool which allows you to test for CSRF vulnerabilities. This tool is also written in Java.  
 
Check out the [[:Category:OWASP_CSRFTester_Project | OWASP CSRF Tester]] tool which allows you to test for CSRF vulnerabilities. This tool is also written in Java.  
 
'''Other Articles in the OWASP Prevention Cheat Sheet Series'''
 
 
* [[XSS (Cross Site Scripting) Prevention Cheat Sheet]]
 
* [[SQL Injection Prevention Cheat Sheet]]
 
* [[Transport Layer Protection Cheat Sheet]]
 
  
 
= References =
 
= References =
Line 153: Line 179:
 
= Authors and Primary Editors  =
 
= Authors and Primary Editors  =
  
Paul Petefish - paulpetefish@solutionary.com
+
Paul Petefish - paulpetefish[at]solutionary.com<br/>
 
+
Eric Sheridan - eric[at]infraredsecurity.com<br/>
Eric Sheridan - eric.sheridan@aspectsecurity.com
+
Dave Wichers - dave.wichers[at]aspectsecurity.com  
 
+
Dave Wichers - dave.wichers@aspectsecurity.com  
+
  
[[Category:How_To]] [[Category:Cheatsheets]] [[Category:OWASP_Document]] [[Category:OWASP_Top_Ten_Project]]
+
= Other Cheatsheets =
 +
{{Cheatsheet_Navigation}}
 +
[[Category:Cheatsheets]]

Revision as of 15:08, 25 September 2013

Contents

Introduction

Cross-Site Request Forgery (CSRF) is a type of attack that occurs when a malicious Web site, email, blog, instant message, or program causes a user’s Web browser to perform an unwanted action on a trusted site for which the user is currently authenticated. The impact of a successful cross-site request forgery attack is limited to the capabilities exposed by the vulnerable application. For example, this attack could result in a transfer of funds, changing a password, or purchasing an item in the user's context. In effect, CSRF attacks are used by an attacker to make a target system perform a function (funds Transfer, form submission etc.) via the target's browser without knowledge of the target user, at least until the unauthorized function has been committed.

Impacts of successful CSRF exploits vary greatly based on the role of the victim. When targeting a normal user, a successful CSRF attack can compromise end-user data and their associated functions. If the targeted end user is an administrator account, a CSRF attack can compromise the entire Web application. The sites that are more likely to be attacked are community Websites (social networking, email) or sites that have high dollar value accounts associated with them (banks, stock brokerages, bill pay services). This attack can happen even if the user is logged into a Web site using strong encryption (HTTPS). Utilizing social engineering, an attacker will embed malicious HTML or JavaScript code into an email or Website to request a specific 'task url'. The task then executes with or without the user's knowledge, either directly or by utilizing a Cross-site Scripting flaw (ex: Samy MySpace Worm).

For more information on CSRF, please see the OWASP Cross-Site Request Forgery (CSRF) page.

Prevention Measures That Do NOT Work

Using a Secret Cookie

Remember that all cookies, even the secret ones, will be submitted with every request. All authentication tokens will be submitted regardless of whether or not the end-user was tricked into submitting the request. Furthermore, session identifiers are simply used by the application container to associate the request with a specific session object. The session identifier does not verify that the end-user intended to submit the request.

Only Accepting POST Requests

Applications can be developed to only accept POST requests for the execution of business logic. The misconception is that since the attacker cannot construct a malicious link, a CSRF attack cannot be executed. Unfortunately, this logic is incorrect. There are numerous methods in which an attacker can trick a victim into submitting a forged POST request, such as a simple form hosted in an attacker's Website with hidden values. This form can be triggered automatically by JavaScript or can be triggered by the victim who thinks the form will do something else.

Multi-Step Transactions

Multi-Step transactions are not an adequate prevention of CSRF. As long as an attacker can predict or deduce each step of the completed transaction, then CSRF is possible.

URL Rewriting

This might be seen as a useful CSRF prevention technique as the attacker can not guess the victim's session ID. However, the user’s credential is exposed over the URL.

General Recommendation: Synchronizer Token Pattern

In order to facilitate a "transparent but visible" CSRF solution, developers are encouraged to adopt the Synchronizer Token Pattern (http://www.corej2eepatterns.com/Design/PresoDesign.htm). The synchronizer token pattern requires the generating of random "challenge" tokens that are associated with the user's current session. These challenge tokens are then inserted within the HTML forms and links associated with sensitive server-side operations. When the user wishes to invoke these sensitive operations, the HTTP request should include this challenge token. It is then the responsibility of the server application to verify the existence and correctness of this token. By including a challenge token with each request, the developer has a strong control to verify that the user actually intended to submit the desired requests. Inclusion of a required security token in HTTP requests associated with sensitive business functions helps mitigate CSRF attacks as successful exploitation assumes the attacker knows the randomly generated token for the target victim's session. This is analogous to the attacker being able to guess the target victim's session identifier. The following synopsis describes a general approach to incorporate challenge tokens within the request.

When a Web application formulates a request (by generating a link or form that causes a request when submitted or clicked by the user), the application should include a hidden input parameter with a common name such as "CSRFToken". The value of this token must be randomly generated such that it cannot be guessed by an attacker. Consider leveraging the java.security.SecureRandom class for Java applications to generate a sufficiently long random token. Alternative generation algorithms include the use of 256-bit BASE64 encoded hashes. Developers that choose this generation algorithm must make sure that there is randomness and uniqueness utilized in the data that is hashed to generate the random token.

  <form action="/transfer.do" method="post">
  <input type="hidden" name="CSRFToken" value="OWY4NmQwODE4ODRjN2Q2NTlhMmZlYWEwYzU1YWQwMTVhM2JmNGYxYjJiMGI4MjJjZDE1ZDZjMTVi
  MGYwMGEwOA==">
  …
  </form>

In general, developers need only generate this token once for the current session. After initial generation of this token, the value is stored in the session and is utilized for each subsequent request until the session expires. When a request is issued by the end-user, the server-side component must verify the existence and validity of the token in the request as compared to the token found in the session. If the token was not found within the request or the value provided does not match the value within the session, then the request should be aborted, token should be reset and the event logged as a potential CSRF attack in progress.

To further enhance the security of this proposed design, consider randomizing the CSRF token parameter name and or value for each request. Implementing this approach results in the generation of per-request tokens as opposed to per-session tokens. Note, however, that this may result in usability concerns. For example, the "Back" button browser capability is often hindered as the previous page may contain a token that is no longer valid. Interaction with this previous page will result in a CSRF false positive security event at the server. Regardless of the approach taken, developers are encouraged to protect the CSRF token the same way they protect authenticated session identifiers, such as the use of SSLv3/TLS.

Disclosure of Token in URL

Many implementations of this control include the challenge token in GET (URL) requests as well as POST requests. This is often implemented as a result of sensitive server-side operations being invoked as a result of embedded links in the page or other general design patterns. These patterns are often implemented without knowledge of CSRF and an understanding of CSRF prevention design strategies. While this control does help mitigate the risk of CSRF attacks, the unique per-session token is being exposed for GET requests. CSRF tokens in GET requests are potentially leaked at several locations: browser history, HTTP log files, network appliances that make a point to log the first line of an HTTP request, and Referrer headers if the protected site links to an external site.

In the latter case (leaked CSRF token due to the Referer header being parsed by a linked site), it is trivially easy for the linked site to launch a CSRF attack on the protected site, and they will be able to target this attack very effectively, since the Referer header tells them the site as well as the CSRF token. The attack could be run entirely from javascript, so that a simple addition of a script tag to the HTML of a site can launch an attack (whether on an originally malicious site or on a hacked site). This attack scenario is easy to prevent, the referer will be omitted if the origin of the request is HTTPS. Therefore this attack does not affect web applications that are HTTPS only.

The ideal solution is to only include the CSRF token in POST requests and modify server-side actions that have state changing affect to only respond to POST requests. This is in fact what the RFC 2616 requires for GET requests. If sensitive server-side actions are guaranteed to only ever respond to POST requests, then there is no need to include the token in GET requests.

In most JavaEE web applications, however, HTTP method scoping is rarely ever utilized when retrieving HTTP parameters from a request. Calls to "HttpServletRequest.getParameter" will return a parameter value regardless if it was a GET or POST. This is not to say HTTP method scoping cannot be enforced. It can be achieved if a developer explicitly overrides doPost() in the HttpServlet class or leverages framework specific capabilities such as the AbstractFormController class in Spring.

For these cases, attempting to retrofit this pattern in existing applications requires significant development time and cost, and as a temporary measure it may be better to pass CSRF tokens in the URL. Once the application has been fixed to respond to HTTP GET and POST verbs correctly, CSRF tokens for GET requests should be turned off.

Viewstate (ASP.NET)

ASP.NET has an option to maintain your ViewState. The ViewState indicates the status of a page when submitted to the server. The status is defined through a hidden field placed on each page with a <form runat="server"> control. Viewstate can be used as a CSRF defense, as it is difficult for an attacker to forge a valid Viewstate. It is not impossible to forge a valid Viewstate since it is feasible that parameter values could be obtained or guessed by the attacker. However, if the current session ID is added to the ViewState, it then makes each Viewstate unique, and thus immune to CSRF.

To use the ViewStateUserKey property within the Viewstate to protect against spoofed post backs. Add the following in the OnInit virtual method of the Page-derived class (This property must be set in the Page.Init event)

  protected override OnInit(EventArgs e) {
     base.OnInit(e); 
     if (User.Identity.IsAuthenticated)
        ViewStateUserKey = Session.SessionID; }

The following keys the Viewstate to an individual using a unique value of your choice.

   (Page.ViewStateUserKey)

This must be applied in Page_Init because the key has to be provided to ASP.NET before Viewstate is loaded. This option has been available since ASP.NET 1.1.

However, there are limitations on this mechanism. Such as, ViewState MACs are only checked on POSTback, so any other application requests not using postbacks will happily allow CSRF.

Double Submit Cookies

Double submitting cookies is defined as sending the session ID cookie in two different ways for every form request. First as a traditional header value, and again as a hidden form value. When a user visits a site, the site should generate a (cryptographically strong) pseudorandom value and set it as a cookie on the user's machine. This is typically referred to as the session ID. The site should require every form submission to include this pseudorandom value as a hidden form value and also as a cookie value. When a POST request is sent to the site, the request should only be considered valid if the form value and the cookie value are the same. When an attacker submits a form on behalf of a user, he can only modify the values of the form. An attacker cannot read any data sent from the server or modify cookie values, per the same-origin policy. This means that while an attacker can send any value he wants with the form, the attacker will be unable to modify or read the value stored in the cookie. Since the cookie value and the form value must be the same, the attacker will be unable to successfully submit a form unless he is able to guess the session ID value.

While this approach is effective in mitigating the risk of cross-site request forgery, including authenticated session identifiers in HTTP parameters may increase the overall risk of session hijacking. Architects and developers must ensure that no network appliances or custom application code or modules explicitly log or otherwise disclose HTTP POST parameters. An attacker that is able to obtain access to repositories or channels that leak HTTP POST parameters will be able to replay the tokens and perform session hijacking attacks. Note, however, that transparently logging all HTTP POST parameters is a rare occurrence across network systems and web applications as doing so will expose significant sensitive data aside from session identifiers including passwords, credit card numbers, and or social security numbers. Inclusion of the session identifier within HTML can also be leveraged by cross-site scripting attacks to bypass HTTPOnly protections. Most modern browsers prevent client-side script from accessing HTTPOnly cookies. However, this protection is lost if HTTPOnly session identifiers are placed within HTML as client-side script can easily traverse and extract the identifier from the DOM. Developers are still encouraged to implement the synchronizer token pattern as described in this article.

Direct Web Remoting (DWR) Java library version 2.0 has CSRF protection built in as it implements the double cookie submission transparently.

Encrypted Token Pattern

Overview

The Encrypted Token Pattern leverages an encryption, rather than comparison, method of Token-validation. After successful authentication, the server generates a unique Token comprised of the user's ID, a timestamp value and a nonce, using a unique key available only on the server. This Token is returned to the client and embedded in a hidden field. Subsequent AJAX requests include this Token in the request-header, in a similar manner to the Double-Submit pattern. Non-AJAX form-based requests will implicitly persist the Token in its hidden field, although I recommend persisting this data in a custom HTTP header in such cases. On receipt of this request, the server reads and decrypts the Token value with the same key used to create the Token.

Validation

On successful Token-decryption, the server has access to parsed values, ideally in the form of claims. These claims are processed by comparing the UserId claim to any potentially stored UserId (in a Cookie or Session variable, if the site already contains a means of authentication). The Timestamp is validated against the current time, preventing replay attacks. Alternatively, in the case of a CSRF attack, the server will be unable to decrypt the poisoned Token, and can block and log the attack.

This pattern exists primarily to allow developers and architects protect against CSRF without session-dependency. It also addresses some of the shortfalls in other stateless approaches, such as the need to store data in a Cookie, circumnavigating the Cookie-subdomain and HTTPONLY issues.

Please refer to the following resources for more information:

CSRF Prevention without a Synchronizer Token

CSRF can be prevented in a number of ways. Using a Synchronizer Token is one way that an application can rely upon the Same-Origin Policy to prevent CSRF by maintaining a secret token to authenticate requests. This section details other ways that an application can prevent CSRF by relying upon similar rules that CSRF exploits can never break.

Checking The Referer Header

Although it is trivial to spoof the referer header on your own browser, it is impossible to do so in a CSRF attack. Checking the referer is a commonly used method of preventing CSRF on embedded network devices because it does not require a per-user state. This makes a referer a useful method of CSRF prevention when memory is scarce. This method of CSRF mitigation is also commonly used with unauthenticated requests, such as requests made prior to establishing a session state which is required to keep track of a synchronization token.

However, checking the referer is considered to be a weaker from of CSRF protection. For example, open redirect vulnerabilities can be used to exploit GET-based requests that are protected with a referer check. It should be noted that GET requests should never incur a state change as this is a violation of the HTTP specification.

There are also common implementation mistakes with referer checks. For example if the CSRF attack originates from an HTTPS domain then the referer will be omitted. In this case the lack of a referer should be considered to be an attack when the request is performing a state change. Also note that the attacker has limited influence over the referer. For example, if the victim's domain is "site.com" then an attacker have the CSRF exploit originate from "site.com.attacker.com" which may fool a broken referer check implementation. XSS can be used to bypass a referer check.

Checking The Origin Header

The Origin HTTP Header standard was introduced as a method of defending against CSRF and other Cross-Domain attacks. Unlike the referer, the origin will be present in HTTP request that originates from an HTTPS url.

If the origin header is present, then it should be checked for consistency.

Challenge-Response

Challenge-Response is another defense option for CSRF. The following are some examples of challenge-response options.

  • CAPTCHA
  • Re-Authentication (password)
  • One-time Token

While challenge-response is a very strong defense to CSRF (assuming proper implementation), it does impact user experience. For applications in need of high security, tokens (transparent) and challenge-response should be used on high risk functions.

Prevention Frameworks

There are CSRF prevention modules available for J2EE, .Net, and PHP.

OWASP CSRF Guard (For Java)

The OWASP CSRFGuard Project makes use of a unique per-session token verification pattern using a JavaEE filter to mitigate the risk of CSRF attacks. When an HttpSession is first instantiated, CSRFGuard will generate a cryptographically random token using the SecureRandom class to be stored in the session.

Similar Projects

CSRFGuard has been implemented in other languages besides Java. They are:

Client/User Prevention

Since CSRF vulnerabilities are reportedly widespread, it is recommended to follow best practices to mitigate risk. Some mitigating include:

  • Logoff immediately after using a Web application
  • Do not allow your browser to save username/passwords, and do not allow sites to “remember” your login
  • Do not use the same browser to access sensitive applications and to surf the Internet freely (tabbed browsing).
  • The use of plugins such as No-Script makes POST based CSRF vulnerabilities difficult to exploit. This is because JavaScript is used to automatically submit the form when the exploit is loaded. Without JavaScript the attacker would have to trick the user into submitting the form manually.

Integrated HTML-enabled mail/browser and newsreader/browser environments pose additional risks since simply viewing a mail message or a news message might lead to the execution of an attack.

No Cross-Site Scripting (XSS) Vulnerabilities

Cross-Site Scripting is not necessary for CSRF to work. However, any cross-site scripting vulnerability can be used to defeat token, Double-Submit cookie, referer and origin based CSRF defenses. This is because an XSS payload can simply read any page on the site using a XMLHttpRequest and obtain the generated token from the response, and include that token with a forged request. This technique is exactly how the MySpace (Samy) worm defeated MySpace's anti CSRF defenses in 2005, which enabled the worm to propagate. XSS cannot defeat challenge-response defenses such as Captcha, re-authentication or one-time passwords. It is imperative that no XSS vulnerabilities are present to ensure that CSRF defenses can't be circumvented. Please see the OWASP XSS Prevention Cheat Sheet for detailed guidance on how to prevent XSS flaws.

Related Articles

Cross-Site Request Forgery (CSRF)

For more information on CSRF please see the OWASP Cross-Site Request Forgery (CSRF) page.

How to Review Code for CSRF Vulnerabilities

See the OWASP Code Review Guide article on how to Reviewing code for Cross-Site Request Forgery issues.

How to Test for CSRF Vulnerabilities

See the OWASP Testing Guide article on how to Test for CSRF Vulnerabilities.

CSRF Testing Tool

Check out the OWASP CSRF Tester tool which allows you to test for CSRF vulnerabilities. This tool is also written in Java.

References

Cross Site Reference Forgery: An introduction to a common web application weakness

Cross-Site Request Forgeries: Exploitation and Prevention

Authors and Primary Editors

Paul Petefish - paulpetefish[at]solutionary.com
Eric Sheridan - eric[at]infraredsecurity.com
Dave Wichers - dave.wichers[at]aspectsecurity.com

Other Cheatsheets

OWASP Cheat Sheets Project Homepage

Developer Cheat Sheets (Builder)

Assessment Cheat Sheets (Breaker)

Mobile Cheat Sheets

OpSec Cheat Sheets (Defender)

Draft Cheat Sheets