CSRF protection (cross-request protection) in spring MVC

I got a little confused about this CSRF protection (fake cross-site request requests) in spring. No. I have my jsp and my controller and web service. What I want to do is check the token at the web service level, and if the token matches, start the web service (in my case, do the db tab)

Jsp file

<form:input type="text" class="form-control" path="mName" /> <input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" /> <div class="form-action"> <input type="submit" value="Save" class="btn btn-primary" /> </div> </form:form> 

I also added a hidden tag. Now, what should I do to check this token. I got a little lost there.

In the controller class, I get the values ​​from the form for the object and call web ervise to save the data

 @RequestMapping(method = RequestMethod.POST) public String processForm(@ModelAttribute(value = "userForm") @Valid UserForm userForm, BindingResult result, ModelMap model) { //call the web service } 
+6
source share
2 answers

Apparently I used spring security 3.1.4.RELEASE . here you do it manually. Then I changed it to 3.2.2.RELEASE , and then I just had to use

 <input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" /> 

Refer to this link to find out what's new in spring 3.2 security.

http://docs.spring.io/spring-security/site/docs/3.2.0.RELEASE/reference/htmlsingle/#new

Be careful when you switch from 3.1.4.RELEASE to 3.2.2.RELEASE, there are many confusing repeated factoring. Especially in the web.xml and spring -security.xml files

+1
source

The OWASP Enterprise Security API is a very good option, offering robust CSRF protection. CSRF is actually quite easy to solve. OWASP ESAPI provides specifications for implementing CSRF protection, as shown below.

1. Create a new CSRF token and add it to the user once at login and save the user in the http session.

This is done by default in the ESAPI implementation and is stored as a member variable of the User object, which is stored in session .

 /this code is in the DefaultUser implementation of ESAPI /** This user CSRF token. */ private String csrfToken = resetCSRFToken(); ... public String resetCSRFToken() { csrfToken = ESAPI.randomizer().getRandomString(8, DefaultEncoder.CHAR_ALPHANUMERICS); return csrfToken; } 

2. On any forms or URLs that should be protected, add the token as a parameter / hidden field.

The following is the addCSRFToken method for any URL that will be displayed that needs CSRF protection. Alternatively, if you are creating a form or using another way to display URLs (for example, c:url ), be sure to add a parameter or hidden field with the name " ctoken " and the value DefaultHTTPUtilities.getCSRFToken() .

 //from HTTPUtilitiles interface final static String CSRF_TOKEN_NAME = "ctoken"; //this code is from the DefaultHTTPUtilities implementation in ESAPI public String addCSRFToken(String href) { User user = ESAPI.authenticator().getCurrentUser(); if (user.isAnonymous()) { return href; } // if there are already parameters append with &, otherwise append with ? String token = CSRF_TOKEN_NAME + "=" + user.getCSRFToken(); return href.indexOf( '?') != -1 ? href + "&" + token : href + "?" + token; } ... public String getCSRFToken() { User user = ESAPI.authenticator().getCurrentUser(); if (user == null) return null; return user.getCSRFToken(); } 

3. On the server side, for these protected actions, make sure that the supplied token matches the token from the user object in the session.

Make sure you call this method from your servlet or spring or jsf controller or any other server-side mechanism that you use to process requests. This should be triggered by any request that needs to be checked to protect CSRF. Please note that when tokens do not match, he considers it possible forged request.

 //this code is from the DefaultHTTPUtilities implementation in ESAPI public void verifyCSRFToken(HttpServletRequest request) throws IntrusionException { User user = ESAPI.authenticator().getCurrentUser(); // check if user authenticated with this request - no CSRF protection required if( request.getAttribute(user.getCSRFToken()) != null ) { return; } String token = request.getParameter(CSRF_TOKEN_NAME); if ( !user.getCSRFToken().equals( token ) ) { throw new IntrusionException("Authentication failed", "Possibly forged HTTP request without proper CSRF token detected"); } } 

4. When you exit the system and the session timeout, the user object is deleted from the session and the session is destroyed.

At this point, logout is called. When this happens, note that the session is invalid and the current user reset object is an anonymous user, thereby removing the link to the current user and, accordingly, the csrf token.

 //this code is in the DefaultUser implementation of ESAPI public void logout() { ESAPI.httpUtilities().killCookie( ESAPI.currentRequest(), ESAPI.currentResponse(), HTTPUtilities.REMEMBER_TOKEN_COOKIE_NAME ); HttpSession session = ESAPI.currentRequest().getSession(false); if (session != null) { removeSession(session); session.invalidate(); } ESAPI.httpUtilities().killCookie(ESAPI.currentRequest(), ESAPI.currentResponse(), "JSESSIONID"); loggedIn = false; logger.info(Logger.SECURITY_SUCCESS, "Logout successful" ); ESAPI.authenticator().setCurrentUser(User.ANONYMOUS); } 

Source: http://www.jtmelton.com/2010/05/16/the-owasp-top-ten-and-esapi-part-6-cross-site-request-forgery-csrf/

Hope this helps you.

Shishir

+8
source

All Articles