diff --git a/docs/manual/src/docbook/csrf.xml b/docs/manual/src/docbook/csrf.xml
new file mode 100644
index 0000000000..f229bb0373
--- /dev/null
+++ b/docs/manual/src/docbook/csrf.xml
@@ -0,0 +1,203 @@
+
+
+ Cross Site Request Forgery (CSRF)
+
+ This section discusses Spring Security's
+ Cross Site Request Forgery (CSRF) support.
+
+ CSRF Attacks
+ Before we discuss how Spring Security can protect applications from CSRF attacks, we will explain what a CSRF
+ attack is. Let's take a look at a concrete example to get a better understanding.
+ Assume that your bank's website provides a form that allows transferring money from the currently logged in user
+ to another bank account. For example, the HTTP request might look like:
+
+ Now pretend you authenticate to your bank's website and then, without logging out, visit an evil website. The evil
+ website contains an HTML page with the following form:
+
+
+
+
+ Synchronizer
+ Token Pattern. This solution is to ensure that each request requires, in addition to our session cookie, a randomly
+ generated token as an HTTP parameter. When a request is submitted, the server must look up the expected value for the parameter
+ and compare it against the actual value in the request. If the values do not match, the request should fail.
+ We can relax the expectations to only require the token for each HTTP request that updates state. This can be safely done
+ since the same origin policy ensures the evil site cannot read the response. Additionally, we do not want to include the random
+ token in HTTP GET as this can cause the tokens to be leaked.
+ Let's take a look at how our example would change. Assume the randomly generated token is present in an HTTP parameter named
+ _csrf. For example, the request to transfer money would look like this:
+
+]]>
+ You will notice that we added the _csrf parameter with a random value. Now the evil website will not be able to guess the
+ correct value for the _csrf parameter (which must be explicitly provided on the evil website) and the transfer will fail when the
+ server compares the actual token to the expected token.
+
+
+ Using Spring Security CSRF Support
+ So what are the steps necessary to use Spring Security's to protect our site against CSRF attacks? The steps to using Spring
+ Security's CSRF protection are outlined below:
+
+
+ Use proper HTTP verbs
+
+
+ Configure CSRF Protection
+
+
+ Include the CSRF Token
+
+
+
+ Use proper HTTP verbs
+ The first step to protecting against CSRF attacks is to ensure your website uses proper HTTP verbs. Specifically, before Spring
+ Security's CSRF support can be of use, you need to be certain that your application is using PATCH, POST, PUT, and/or DELETE for anything
+ that modifies state. This is not a limitation of Spring Security's support, but instead a general requirement for proper CSRF prevention.
+
+
+ Configure CSRF Protection
+ The next step is to include Spring Security's CSRF protection within your application. If you are using the XML configuration, this can be done
+ using the <csrf /> element:
+
+ ...
+
+
+]]>
+ CSRF protection is enabled by default with Java configuration. If you would like to disable CSRF, the corresponding Java configuration can be
+ seen below:
+
+
+
+ Include the CSRF Token
+
+ Form Submissions
+ The last step is to ensure that you include the CSRF token in all PATCH, POST, PUT, and DELETE methods. This can be done using
+ the _csrf request attribute to obtain the current CsrfToken. An example of doing this with a JSP is shown below:
+
+]]>
+
+ If you are using Spring MVC <form:form> tag, the CsrfToken is automatically included for you using the CsrfRequestDataValueProcessor.
+
+
+
+ Ajax Requests
+ If you using JSON, then it is not possible to submit the CSRF token within an HTTP parameter. Instead you can submit the token within a HTTP header.
+ A typical pattern would be to include the CSRF token within your meta tags. An example with a JSP is shown below:
+
+
+
+
+
+ ...
+
+ ...]]>
+ You can then include the token within all your AJAX requests. If you were using JQuery, this could be done with the following:
+
+
+
+
+
+ CSRF Caveats
+ There are a few caveats when implementing CSRF.
+
+ Timeouts
+ One issue is that the expected CSRF token is stored in the HttpSession, so as soon as the HttpSession expires your configured
+ AccessDeniedHandler will receive a InvalidCsrfTokenException. If you are using the default
+ AccessDeniedHandler, the browser will get an HTTP 403 and display a poor error message.
+
+ One might ask why the CsrfToken isn't stored in a cookie. This is because there are known exploits in which headers
+ (i.e. specify the cookies) can be set by another domain. Another disadvantage is that by removing the state (i.e. the timeout) you lose the ability
+ to forcibly terminate the token if something got compromised.
+
+ A simple way to mitigate an active user experiencing a timeout is to have some JavaScript that lets the user know their session is about to expire.
+ The user can click a button to continue and refresh the session.
+ Alternatively, specifying a custom AccessDeniedHandler allows you to process the InvalidCsrfTokenException
+ anyway you like. For an example of how to customize the AccessDeniedHandler refer to the provided links for both xml and Java
+ configuration.
+
+
+ Logging In
+ In order to protect against forging log in requests the log in form should be protected against CSRF attacks too. Since the CsrfToken is stored in
+ HttpSession, this means an HttpSession will be created as soon as CsrfToken token attribute is accessed. While this sounds bad in
+ a RESTful / stateless architecture the reality is that state is necessary to implement practical security. Without state, we have nothing we can do if a token is
+ compromised. Practically speaking, the CSRF token is quite small in size and should have a negligible impact on our architecture.
+
+
+ Logging Out
+ Adding CSRF will update the LogoutFilter to only use HTTP POST. This ensures that log out requires a CSRF token and that a malicious user cannot forcibly
+ log out your users.
+ One approach is to use a form for log out. If you really want a link, you can use JavaScript to have the link perform a POST (i.e. maybe on a hidden form). For
+ browsers with JavaScript that is disabled, you can optionally have the link take the user to a log out confirmation page that will perform the POST.
+
+
+ HiddenHttpMethodFilter
+ The HiddenHttpMethodFilter should be placed before the Spring Security filter. In general this is true, but it could have additional implications when
+ protecting against CSRF attacks.
+ Note that the HiddenHttpMethodFilter only overrides the HTTP method on a POST, so this is actually unlikely to cause any real problems. However, it is still
+ best practice to ensure it is placed before Spring Security's filters.
+
+
+
+ Overriding Defaults
+ Spring Security's goal is to provide defaults that protect your users from exploits. This does not mean that you are forced to accept all of its defaults.
+ For example, you can provide a custom CsrfTokenRepository to override the way in which the CsrfToken is stored.
+ You can also specify a custom RequestMatcher to determine which requests are protected by CSRF (i.e. perhaps you don't care if log out is exploited). In short, if
+ Spring Security's CSRF protection doesn't behave exactly as you want it, you are able to customize the behavior. Refer to the <csrf />
+ documentation for details on how to make these customizations with XML and the CsrfConfigurer javadoc for details on how to make these
+ customizations when using Java configuration.
+
+
diff --git a/docs/manual/src/docbook/index.xml b/docs/manual/src/docbook/index.xml
index dd0af05bbe..422427d29b 100644
--- a/docs/manual/src/docbook/index.xml
+++ b/docs/manual/src/docbook/index.xml
@@ -130,6 +130,7 @@
+