Chapter 9 Spring Security CSRF defense

Keywords: Spring server Spring Security csrf

Spring Security has enabled CSRF defense by default.

What is CSRF

CSRF is a browser cross site forged request. Hackers can induce users to perform some unexpected behaviors, which allows attackers to partially bypass the homologous strategy.

For example, after the user logs in to system A, the user can modify his mailbox, and then the browser submits the request as follows

POST /email/change HTTP/1.1
Host: vulnerable-website.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 30
Cookie: session=yvthwsztyeQkAPzeQ5gHgTvlyxHfsAfE

email=wiener@normal-user.com

Then, at this time, the hacker constructs his own web site and constructs a form.

    <form action="http://www.test.com/dfasd/email/change" method="post" id="myForm">
        <input type="hidden" value="test@normal-user.com" name="email">
        <input type="button" value="Point me" id="submitBtn">
    </form>

When the user browses the web site B (the user does not log out of system A), clicking A link of the web site B is actually submitting A form request, and then the hacker modifies the user's mailbox. The request is as follows

POST /email/change HTTP/1.1
Host: vulnerable-website.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 30
Cookie: session=yvthwsztyeQkAPzeQ5gHgTvlyxHfsAfE

email=test@normal-user.com

This is because when you click this link, you will access system A and bring the Cookie information related to system A.

CSRF defense

Spring proposes two ways to defend against CSRF:

  • Token synchronization
  • Specify the SameSite property on the Cookie.
Token synchronization

The principle of token synchronization is to generate a random string token on the server and save a copy on the server. After the current segment request arrives, compare the token carried by the request with the server. If it is equal, it passes; Or refuse.

SameSite

By specifying the SameSite attribute on the Cookie, the browser is required not to carry Cookie information when sending requests from external sites, so as to prevent CSRF attacks.

There are three SameSite attribute values:

  • Strict: only requests sent by the same site contain Cookie requests. Requests sent by different sites will not contain Cookie information.
  • Lax: the request sent by the same site or the GET request navigating to the target address automatically contains Cookie information, otherwise it does not contain Cookie information.
  • None: cookies will be sent in all contexts, that is, cross domain requests are allowed.

Spring Security CSRF defense source code

CsrfToken

CsrfToken is an interface used to provide token related information. It has two implementation classes:

  • SaveOnAccessCsrfToken: when accessing a token, determine whether to store the token.
  • DefaultCsrfToken: a simple implementation of the interface
public interface CsrfToken extends Serializable {

	String getHeaderName();


	String getParameterName();


	String getToken();

}
CsrfTokenRepository

CsrfTokenRepository is an interface used to store, generate and obtain tokens. Its interface has three default implementations:

  • Cookie csrftokenrepository: stores the information of the token in the cookie, which is based on the implementation of the cookie.
  • HttpSessionCsrfTokenRepository: stores the token information in Session based on the Session implementation.
  • LazyCsrfTokenRepository: This is a proxy class. It is stored only when the token is accessed.
public interface CsrfTokenRepository {

	CsrfToken generateToken(HttpServletRequest request);

	void saveToken(CsrfToken token, HttpServletRequest request,
			HttpServletResponse response);

	CsrfToken loadToken(HttpServletRequest request);
}
Questions not understood

Spring Security enables csrf defense by default, and POST submission will report errors. The default LazyCsrfTokenRepository does not understand the token logic. Here is an alternative solution: configure CookieCsrfTokenRepository to replace LazyCsrfTokenRepository class.

CsrfFilter filter

CsrfFilter filter is used to verify tokens, and throw exceptions for failed tokens. CsrfFilter processing logic: first, load the token information carried in the request through the token repository. If there is no token, a new token is generated and stored in a Cookie or Session (depending on your configuration). Then match the request once (the default is to judge whether the request method is "GET", "HEAD", "TRACE" and "OPTIONS"). If the request method is POST, the token information needs to be verified.

to configure

.csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())

Here is the process of configuring cookies.

Here is a key point: when obtaining a token through the request. Getparameter (parametername) method, you need to know the defined parametername name. If an attacker constructs a form in his own website, he does not know this value. This protects against CSRF attacks.

CsrfAuthenticationStrategy

CsrfAuthenticationStrategy authentication is called when the user logs in successfully. The approximate call chain is abstractauthenticationprocessingfilter - > CsrfAuthenticationStrategy

CsrfAuthenticationStrategy processing logic is as follows:

@Override
public void onAuthentication(Authentication authentication,
                             HttpServletRequest request, HttpServletResponse response)
    throws SessionAuthenticationException {
    boolean containsToken = this.csrfTokenRepository.loadToken(request) != null;
    if (containsToken) {
        this.csrfTokenRepository.saveToken(null, request, response);

        CsrfToken newToken = this.csrfTokenRepository.generateToken(request);
        this.csrfTokenRepository.saveToken(newToken, request, response);

        request.setAttribute(CsrfToken.class.getName(), newToken);
        request.setAttribute(newToken.getParameterName(), newToken);
    }
}

reference resources

remarks
This series is all notes for learning Spring Security in simple terms

Posted by upnxwood16 on Fri, 22 Oct 2021 17:44:39 -0700