Search code examples
javajsonsecuritycsrf-protection

How can i securely implement CSRF tokens in java


Problem Behind the question : I was trying to prevent csrf attack in my java web application,In order to implement it i have tried with implementation of X-CSRF-Token,whenever the request was made the request would be transmitted through like this :

POST /sessions HTTP/1.1
Host: sample.com
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:42.0) Gecko/20100101 Firefox/42.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
X-CSRF-Token: Ma7g2c5tpeJGcenBa0S4rGtPaHLe2o+kO5AXz+Uk2WnpaTp1J9jdZMPcE1mMSLxZ/7BA1nCBxvLKiZwtepKdoA==
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
X-Requested-With: XMLHttpRequest
Referer: https://sample.com
Content-Length: 67

now as a attacker what i have tried to achieve this was,i intercepted the post request,instead of attacking token ,i tried to attack the parameter for example see the below request :

POST /sessions HTTP/1.1
Host: sample.com
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:42.0) Gecko/20100101 Firefox/42.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
testX-CSRF-Token: Ma7g2c5tpeJGcenBa0S4rGtPaHLe2o+kO5AXz+Uk2WnpaTp1J9jdZMPcE1mMSLxZ/7BA1nCBxvLKiZwtepKdoA==
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
X-Requested-With: XMLHttpRequest
Referer: https://sample.com
Content-Length: 67

while i tried the above request the CSRF token implementation gets failed ,i was able to successfully bypass csrf injection ,

What would be the best method to mitigate this kind of attack?is it valid csrf injection?how can i optimize my java webapplication for preventing this kind of attacks?

How i implemented java code :

In my xml :

<http>
    <!-- ... -->
    <csrf disabled="true"/>
</http>

And at my code :

@EnableWebSecurity
public class WebSecurityConfig extends
WebSecurityConfigurerAdapter {

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

At form submissions :

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

also i followed the recommended methods provided over here ,on the above scenario the csrf fails ,what might be the mitigations?


Solution

  • As per spring's documentation, you can inject your custom RequestMatcher to validate HTTP request for CSRF token. Spring provides you the feature to override the defaults.

    See section 16.6 http://docs.spring.io/spring-security/site/docs/current/reference/html/csrf.html

    class CSRFRequestMatcher implements RequestMatcher{
        public boolean matches (HttpServletRequest req){
            //Check if request contains valid header name & header value
        }
    }