CSRF / XSRF Cross site Request Forgery, What it is ? and prevention using Spring Security

 

 Cross-site request forgery CSRF 

 

Cross-site request forgery(CSRF or XSRF) is a type of malicious exploit of a web site. By sending a request to the server, without the user's notice, i.e an unauthorized request(action) is made behalf of the authorized user. For which the action is not verified, that the action was performed by the user itself or not.

This happens, because the the server is verifying the BROWSER, and NOT the USER.

So we need to :
"Identify the user, and also the browser, from where the request came from".


 

 

 

 

So What is the solution ?? Synchronizer Token Pattern


Synchronizer Token pattern , ensures that each request needs a session cookie and also a HTTP parameter value (randomly generated token). 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 it fails to match, then you will have a HTTP Error 500 Internal server error.

These tokens are used for update requests (HTTP POST) usually, because they are the requests which makes changes. And the responses are not able to be accessed by the unauthenticated evil site.


So when do we need to provide CSRF Protection ?? For Web Sites

Usually for web sites accessed by humans (via browser), need CSRF protection. and If it is a web service accessed accessed by machines, then it wont be needed.


     1. CSRF protection and JSON

In many situations, we need to have protection for JSON request for javascript. CSRF exploits may be done from javascript.
<form action="https://bank.example.com/transfer" method="post" enctype="text/plain">  
    <input name='{"amount":100,"routingNumber":"evilsRoutingNumber","account":"evilsAccountNumber", "ignore_me":"' value='test"}' type='hidden'>
        <input type="submit"      value="Win Money!"/>
</form>

If the server side application is not validating the Content-Type, then it could be exploited.

<form action="https://bank.example.com/transfer.json" method="post" enctype="text/plain">
    <input name='{"amount":100,"routingNumber":"evilsRoutingNumber","account":"evilsAccountNumber", "ignore_me":"' value='test"}' type='hidden'>
    <input type="submit" value="Win Money!"/>
</form>

So always remember to add content-type, which can increase the security measures.

    2. CSRF and Stateless Browser Applications

Is  the stateless applications safe from CSRF ? Nope

Even Basic Authentication can be fooled using CSRF, since the user name and password is send along with the request, in the same way JSESSIONID  cookie is send.


Spring security for CSRF protection

There are 3 steps for achieving CSRF / XSRF protection using Spring Security : 

  1. Use proper HTTP verbs
  2. Configure CSRF Protection
  3. Include the CSRF Token

   1. Use proper HTTP verbs

The first this is to use the correct HTTP verbs, like HTTP  PATCH, PUT, POST and delete for the requests which makes changes to the state of the system(any updates).
Sending private information in HTTP GET request is not secure.

   2. Configure CSRF Protection  

Next is to configure the Spring Security, by adding the code snippets to the applications code.
If the CSRF is disabled, then the Spring Security will throw a HTTP 403 access denied.
AccessDeniedHandler can also be configured to handle InvalidCsrfTokenException.

XML Configuration :

<http>
    <!-- ... -->
    <csrf>
    <csrf />
</http>


With attributes :
  • token-repository-ref : 
     Which CsrfTokenRepository to use. HttpSessionCsrfTokenRepository is the default one.
  • request-matcher-ref : 
    Which request matcher instance to be used, to determined CSRF is used?
Java programmatic Configuration :
You can use the following code to programatically disable CSRF

@EnableWebSecurity
@Configuration
public class WebSecurityConfig extends
   WebSecurityConfigurerAdapter {

  @Override
  protected void configure(HttpSecurity http) throws Exception {
    http.csrf().disable();
  }
}

   3. Include the CSRF Token

And the final step is to add CSRF token, for all the update requests(such as, PATCH, POST, PUT, and DELETE ). 

<c:url var="logoutUrl" value="/logout"/>
<form action="${logoutUrl}"
    method="post">
  <input type="submit"
    value="Log out" />
  <input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>
</form>

In Spring MVC , if you are using JSTL form tag then the CsrfToken is automatically using the CsrfRequestDataValueProcessor.


References :

  1. http://docs.spring.io/spring-security/site/docs/3.2.0.CI-SNAPSHOT/reference/html/csrf.html
  2. http://blog.codinghorror.com/preventing-csrf-and-xsrf-attacks/
  3. http://www.opensourceforu.com/2010/11/securing-apache-part-3-xsrf-csrf/
  4. http://blog.opensecurityresearch.com/2012/02/json-csrf-with-parameter-padding.html 
  5. http://docs.spring.io/spring-security/site/docs/3.2.0.CI-SNAPSHOT/reference/html/appendix-namespace.html#nsa-csrf
Image credits to its corresponding authors.

No comments

Thanks for viewing the blog post. Follow the blog to receive the updates.. Powered by Blogger.