The Java security: csrf protective actual analysis

Summarized above, the csrf attacks and some common mode protection, csrf full name Cross-site request forgery (CSRF), it is a registered certificate for a class using the trust users have acquired the background to bypass user authentication, send to the attack site a cross-site request user is not authorized to perform an action on the malicious Web site was attacked attacks.

The above definition of abstract, let’s take a simple example to explain in detail csrf attack, help to understand.

Suppose you log on the bank website through a computer for transfer, the general type of transfer is actually a form page form, click the transfer is actually submit the form, http request to initiate the background, the requested format probably looks something like this:

POST /transfer HTTP/1.1
Cookie: JSESSIONID=randomid;; Secure; HttpOnly
Content-Type: application/x-www-form-urlencoded


Well, now turn to their own account finishing up, but then you generally will not immediately withdraw to your bank’s website, you can immediately go surfing other web pages, when you happen to see some very attractive Internet eyeball advertising (such as part-time at home relaxing … a monthly income of tens of thousands like), you click on a bit, but found nothing, maybe you will turn off this page to Why did not happen. However, the background may have a series of things, if it is a phishing site, and you just click on the page contains a form just another form, as follows:

<form action="" method="post">
  <input type="hidden"
  <input type="hidden"
  <input type="hidden"
  <input type="submit"
      value="Win Money!"/>

Here as long as you click on the page will automatically submit the form, leading you to transfer 100 yuan a strange account (which can be realized through automation js), but has not been without your authorization, which is csrf attack, although it Do not know your login information, but using its own mechanisms to impersonate the user browser to bypass user authentication in order to attack back.

csrf is a common web attacks, some of the existing security framework provides support for the protection of the attack, such as spring security, from 4.0, CSRF protection is enabled by default, will be against PATCH, POST, PUT and DELETE methods of protection. This article will provide a combination of spring security protection methods, combined with its source code to learn about its internal protection principles, this paper comes to the source Spring Security version 5.1.5.

This article directory is as follows:

CSRF attacks using Spring Security Protection

CSRF protection philosophy of Spring Security

to sum up


1. Use Spring Security Protection CSRF attacks

To protect CSRF attack by Spring Security What needs to be done to configure it, are summarized as follows:

    Suitable HTTP request method using

    Configuration CSRF protection

    Use CSRF Token

1.1 using the appropriate HTTP request method

The first step is to ensure that the interface you want to protect the exposed site suitable HTTP request methods, that is not yet open to ensure that all required interfaces only support the use PATCH, POST, PUT, DELETE four requests of the way before the Security of CSRF a modified back-end data.

This is not Spring Security CSRF attacks in the protection of their restrictions, but CSRF attacks reasonable protection must be done, because it is easy to transfer data via GET private way leading to its disclosure, use POST to pass sensitive data more reasonable.

1.2 Configuration CSRF protection

The next step is the introduction of your background Spring Security application. Some frameworks by allowing the user session fails to handle invalid CSRF Token, but this approach is problematic, instead, Spring Security default return a 403 HTTP status code is not valid to refuse access can be achieved by configuring their refusal logic AccessDeniedHandler .

If the project is the use of XML configuration, it must show the use tag element to open CSRF protection, see .

By the way Java configuration will open CSRF protection by default, if you want to disable this feature, you need to manually configure, see example below, a more detailed configuration refer csrf () method of official documents.

public class WebSecurityConfig extends
   WebSecurityConfigurerAdapter {

  protected void configure(HttpSecurity http) throws Exception {

1.3 Use CSRF Token

The next step is to bring each time a request CSRF Token, there will be different depending on how the request in different ways:

1.3.1 Form form submission

CSRF Token will submit a form attached by _csrf Http request attribute, the background interface to get token from the request, the following is an example (JSP):

<c:url var="logoutUrl" value="/logout"/>
<form action="${logoutUrl}"
  <input type="submit"
    value="Log out" />
  <input type="hidden"

In fact, the background while rendering the page, Mr. into a CSRF Token, into the form; then when the user submits the form will be included with this CSRF Token, the background to remove it and check, then refused this request is inconsistent. Here is the background because this Token generation, which is to obtain third-party site can not achieve protection in this way.

1.3.2 Ajax and JSON requests

If JSON used, then no CSRF Token submitted as HTTP parameters, but on the HTTP request header. A typical approach is to CSRF Token included in the meta tags of the page. The following is an example of the JSP:

    <meta name="_csrf" content="${_csrf.token}"/>
    <meta name="_csrf_header" content="${_csrf.headerName}"/>

Then all of the requests need to bring Ajax CSRF Token, the following is achieved in jQuery:

$(function () {
  var token = $("meta[name='_csrf']").attr("content");
  var header = $("meta[name='_csrf_header']").attr("content");
  $(document).ajaxSend(function(e, xhr, options) {
    xhr.setRequestHeader(header, token);

Configuring here all configurations have been good, including the invocation interface design, configuration framework, the front page earlier in talking about a series of protective manner, Spring Security, what is the way the use of it, the most direct way It is to see the source code.

2. Spring Security CSRF protection principles of

Spring Security is based Filter (filter) to achieve its security features, on the main logic CsrfFilter CSRF protection in this filter, inherited from OncePerRequestFilter, and rewrite doFilterInternal Method:

    protected void doFilterInternal(HttpServletRequest request,
            HttpServletResponse response, FilterChain filterChain)
                    throws ServletException, IOException {
        request.setAttribute(HttpServletResponse.class.getName(), response);

Get csrf token from the request by tokenRepository

CsrfToken csrfToken = this.tokenRepository.loadToken(request); final boolean missingToken = csrfToken == null;      //

If you do not get the token newly generated token and save

if (missingToken) { csrfToken = this.tokenRepository.generateToken(request); this.tokenRepository.saveToken(csrfToken, request, response); } request.setAttribute(CsrfToken.class.getName(), csrfToken); request.setAttribute(csrfToken.getParameterName(), csrfToken);      //

Determine the need for csrf token verification

if (!this.requireCsrfProtectionMatcher.matches(request)) { filterChain.doFilter(request, response); return; }      //

The front end to get the actual token pass over

String actualToken = request.getHeader(csrfToken.getHeaderName()); if (actualToken == null) { actualToken = request.getParameter(csrfToken.getParameterName()); }      //

Checking whether the token is equal to two

if (!csrfToken.getToken().equals(actualToken)) { if (this.logger.isDebugEnabled()) { this.logger.debug("Invalid CSRF token found for " + UrlUtils.buildFullRequestUrl(request)); }        //

If the token is missing lead, an exception is thrown MissingCsrfTokenException

if (missingToken) { this.accessDeniedHandler.handle(request, response, new MissingCsrfTokenException(actualToken)); }        //

If the same token is not an exception is thrown InvalidCsrfTokenException

else { this.accessDeniedHandler.handle(request, response, new InvalidCsrfTokenException(csrfToken, actualToken)); } return; }      //

To the next filter

filterChain.doFilter(request, response); }

The entire process is very clear, we summarize:

    To obtain csrf token from the request by tokenRepository;

    If you do not get the token newly generated token and save it;

    Determine the need for check csrf token need not directly execute the next filter;

    The call request getHeader () method or getParameter () method to get the actual token pass over the distal end;

    Two verification token are equal, not equal, then an exception is thrown, then the check is passed equal, perform the next filter;

May know, Spring Security is implemented by means of CSRF Token protection, we talked about above, you can choose to store the cookie through a token way session can also choose the way that Spring Security provides what way, the answer just get token the tokenRepository, we look at this tokenRepository type is CsrfTokenRepository (which is an interface), Spring Security provides three achieved, namely HttpSessionCsrfTokenRepository, CookieCsrfTokenRepository, LazyCsrfTokenRepository, we focused look at the first two, as the name suggests, is through a session and the other is through cookie, we’ll look at each of their respective implementation loadToken () method to test.


The realization CookieCsrfTokenRepository

public CsrfToken loadToken(HttpServletRequest request) { Cookie cookie = WebUtils.getCookie(request, this.cookieName); if (cookie == null) { return null; } String token = cookie.getValue(); if (!StringUtils.hasLength(token)) { return null; } return new DefaultCsrfToken(this.headerName, this.parameterName, token); } //

The realization HttpSessionCsrfTokenRepository

public CsrfToken loadToken(HttpServletRequest request) { HttpSession session = request.getSession(false); if (session == null) { return null; } return (CsrfToken) session.getAttribute(this.sessionAttributeName); }

Here we are clear, Spring Security offers a variety of strategies to save token, both can be saved in a cookie can also be stored in the session, this can be manually specified. So when it comes to the two earlier token of protection on the way, Spring Security supports. Now here, we’ll look at how Spring Security token is generated and saved, where only achieve CookieCsrfTokenRepository example:


Generate a token

public CsrfToken generateToken(HttpServletRequest request) { return new DefaultCsrfToken(this.headerName, this.parameterName, createNewToken()); } private String createNewToken() { return UUID.randomUUID().toString(); } //

Save token

public void saveToken(CsrfToken token, HttpServletRequest request, HttpServletResponse response) { String tokenValue = token == null ? "" : token.getToken(); Cookie cookie = new Cookie(this.cookieName, tokenValue); cookie.setSecure(request.isSecure()); if (this.cookiePath != null && !this.cookiePath.isEmpty()) { cookie.setPath(this.cookiePath); } else { cookie.setPath(this.getRequestContext(request)); } if (token == null) { cookie.setMaxAge(0); } else { cookie.setMaxAge(-1); } if (cookieHttpOnly && setHttpOnlyMethod != null) { ReflectionUtils.invokeMethod(setHttpOnlyMethod, cookie, Boolean.TRUE); } response.addCookie(cookie); }

You can see, in fact, generated token is essentially a uuid, and then save is stored in a cookie, it comes to cookie operations, many of the details, it would not elaborate.


3. Summary

This article first explains the basic example of a csrf attack, and then describes the configuration using Spring Security to protect csrf attack needed, and finally learned a bit from Spring Security source point of view of how it is achieved csrf protection, basic principles or by token to achieve, can be achieved by means of a specific session cookie and ways.

Note: This article source involved are from the Spring Security 5.1.5.



Cross Site Request Forgery (CSRF)

Spring Security Architecture

Leave a Reply