This site is the archived OWASP Foundation Wiki and is no longer accepting Account Requests.
To view the new OWASP Foundation website, please visit https://owasp.org

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

From OWASP
Jump to: navigation, search
m
m
Line 17: Line 17:
 
The most common defense of 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.
 
The most common defense of 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.
  
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 as a query parameter as an “Input” tag of type “hidden” with a name like: CSRFToken. It is important to note that the CSRFToken should not be included in the URL or in URL parameters as they may be leaked. The CSRFToken should have a value that is a randomly generated such as a 128-bit hash that has been base 64 encoded. For each request this token need only be generated randomly once, after that 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 its 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 Formulator is not the application, the request should be aborted and the event can be logged as a potential security incident.
+
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 as a query parameter as an “Input” tag of type “hidden” with a name like: CSRFToken. It is important to note that the CSRFToken should not be included in the URL or in URL parameters as they may be leaked. The CSRFToken should have a value that is a randomly generated such as a 128-bit hash that has been base 64 encoded.  
 +
 
 +
  <form action="/transfer.do" method="post">
 +
  <input type="hidden" name="CSRFToken" value="MDZhMWUxNjRlNDlhZDBjNGYyNjg0ZWExODIzZjI0OTE=">
 +
  …
 +
  </form>
 +
 
 +
For each request this token need only be generated randomly once, after that 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 its 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 Formulator is not the application, the request should be aborted and the event can be logged as a potential security incident.
  
 
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.
 
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.

Revision as of 15:14, 15 October 2009

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 users’ context.

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

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 users knowledge, either directly or by utilizing a Cross-site Scripting Flaw.

In effect, CSRF attacks are used by an attacker to make a target system perform a function (Funds Transfer, Form submission etc..) via the targets browser without knowledge of the target user, at least until the unauthorized function has been committed.

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

Prevention

Token Based

The most common defense of 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.

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 as a query parameter as an “Input” tag of type “hidden” with a name like: CSRFToken. It is important to note that the CSRFToken should not be included in the URL or in URL parameters as they may be leaked. The CSRFToken should have a value that is a randomly generated such as a 128-bit hash that has been base 64 encoded.

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

For each request this token need only be generated randomly once, after that 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 its 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 Formulator is not the application, the request should be aborted and the event can be logged as a potential security incident.

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.

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 though, since it is feasible that parameter values could be obtained or guessed by the attacker. However, if you add the current session ID to the ViewState, then it 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 (Note that you must set this property in the Page.Init event)

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

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.


Prevention Frameworks

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

OWASP CSRF Guard

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.

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.

Similar Projects There are a small number of other projects that implement the unique random request token concept similar to that of CSRFGuard. They are as follows:

http://www.owasp.org/index.php/PHP_CSRF_Guard

http://www.owasp.org/index.php/.Net_CSRF_Guard

Challenge-Response

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

  • CAPTCHA
  • Re-Authentication (password and or username)
  • 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.

Double Submit Cookies (DWR)

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, he 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.

If you are using Ajax or a significant amount of scripting then this solution is a simple fix once solution.

If you are using DWR version 2 then this CSRF protection is built in. DWR implements the double cookie submission pattern transparently.

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 attacker's Website with hidden values. This form can be triggered automatically by JavaScript or can be triggered by the victim who thinks form will do something else.

Checking Referer Header

An attacker can easily block the sending of the Referer header, and the HTTP RFC’s make it clear the this header is optional. Browsers also omit the referer header when they are being used over SSL.

Multi-Step Transactions

Multi-Step transactions are not an adequate prevention of CSRF. As long as an attacked 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

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

  • 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 freely the Internet; if you have to do both things at the same machine, do them with separate browsers.

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

Cross-Site Scripting (XSS)

Cross-Site Scripting is not necessary to for CSRF to work. However, any Cross-Site Scripting flaw can defeat most token based CSRF defenses that are available. XSS can not defeat challenge-response defenses such as re-authentication or one-time tokens. It is imperative that no XSS vulnerabilities are present to ensure that no CSRF vulnerabilities are present. Please see the XSS Prevention Cheat Sheet for more information.

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 CSRF Vulnerabilities.

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

Authors and Primary Editors

Paul Petefish - [email protected]

Eric Sheridan - [email protected]

Dave Wichers - [email protected]