Skip to content

CSRF

CSRF (Cross-Site Request Forgery)

CSRF (Cross-Site Request Forgery) is an attack method where an attacker tricks a logged-in user's browser into making unauthorized requests to a target website, allowing the attacker to perform unwanted actions on behalf of the user. In simple terms, CSRF attacks impersonate the user’s request to exploit the user's trust for malicious purposes.

Basic Principles of CSRF Attacks

  1. User Login: The user logs into an account on a website (e.g., a banking site).

  2. Attacker's Site: The attacker creates a malicious site and tricks the user into visiting it.

  3. Malicious Request: When the user visits the attacker’s site, the site automatically sends a request to the site where the user is already logged in (e.g., a bank transfer request). These requests are treated by the site as legitimate actions from the user and are executed.

Example of CSRF Attack

Suppose a user is logged into a banking site and visits a malicious site. The code on the malicious site might send a transfer request to the bank site in the background:

<form action="https://bank.com/transfer" method="POST" style="display:none;">
    <input type="hidden" name="account" value="attackerAccount">
    <input type="hidden" name="amount" value="1000">
</form>
<script>
    document.forms[0].submit();
</script>

The user is unaware that this request has been submitted, and the bank site performs the transfer due to lack of additional security validation (like a CSRF token).

Defending Against CSRF Attacks

  1. CSRF Token

CSRF Token is a protective mechanism used to ensure that the request is made by a legitimate user. Each time a user requests a page, the server generates a unique token and sends it to the client. The client must include this token with every form submission, and the server validates the token’s validity.

In Spring Boot, the CSRF Token is usually included in forms via . Spring Security handles this process automatically.

Example Code:


@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .csrf().and()
            .authorizeRequests()
            .anyRequest().authenticated()
            .and()
            .formLogin().permitAll();
    }
}

  1. SameSite Cookie Attribute

Setting the SameSite attribute can restrict third-party sites from sending cross-site requests in the user’s browser. The SameSite attribute has three values:

  - **Strict**: Completely prevents third-party sites from sending cookies.
  - **Lax**: Allows some safe third-party requests (e.g., GET requests).
  - **None**: Allows all third-party requests but must be used with the Secure attribute.

Example Configuration:


@Bean
public CookieSerializer cookieSerializer() {
    CookieSerializer serializer = new DefaultCookieSerializer();
    serializer.setSameSite("Strict");
    return serializer;
}

  1. Referer Header Check

Checking the HTTP Referer header can help identify whether the request comes from a legitimate source. Although this method is not as secure as CSRF Tokens and SameSite attributes, it can serve as an additional layer of protection.

  1. Use GET Requests for Read Operations and POST Requests for Changes

Preferably use POST requests for all state-changing operations (e.g., submitting forms, executing commands) and GET requests for reading operations (e.g., retrieving data). GET requests should have no side effects.

  1. Ensure Every Protected Operation in the Web Application Has Explicit Security Checks

Ensure all critical actions require validation of user permissions and intent.

Default CSRF Configuration in Spring Boot

CSRF protection is enabled by default in Spring Boot. When using Spring Security, it automatically generates and validates CSRF Tokens.

  • Enable CSRF: By default, CSRF is enabled. You can customize the configuration using the csrf() method in the configuration class.
  • Disable CSRF: It is not recommended to disable CSRF in production environments, but if needed, it can be disabled via configuration:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .csrf().disable()
            .authorizeRequests()
            .anyRequest().authenticated()
            .and()
            .formLogin().permitAll();
    }
}