Home/Learn/Spring Boot/CSRF Protection & Session Management

CSRF Protection & Session Management

Intermediate
Security

Spring Security enables CSRF protection by default for stateful apps; stateless REST APIs typically disable it and rely on JWT or API-key schemes instead.

Overview

Cross-Site Request Forgery (CSRF) is an attack where a malicious site tricks an authenticated user's browser into sending a request to your API using their session cookie. Spring Security enables CSRF protection by default for stateful (session-based) applications. For stateless REST APIs secured with JWT Bearer tokens — where the token is in the Authorization header, not a cookie — CSRF is not relevant and should be disabled. Session management controls how Spring Security creates and uses HTTP sessions: stateless APIs should use SessionCreationPolicy.STATELESS to prevent session creation entirely, saving memory and avoiding session fixation vulnerabilities.

Disabling CSRF for stateless REST APIs

CSRF protection is only needed when authentication state is carried in a cookie. A JWT Bearer token in the Authorization header is not automatically sent by browsers on cross-origin requests, so CSRF is irrelevant. Disable CSRF and set session policy to STATELESS for all REST APIs secured with JWT.

Java — CSRF disabled + STATELESS session for JWT REST APIs
@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        return http
            // Stateless REST API — no session, no CSRF needed
            .sessionManagement(session -> session
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS))
            .csrf(AbstractHttpConfigurer::disable)
            // JWT resource server — validates Bearer token
            .oauth2ResourceServer(oauth2 -> oauth2
                .jwt(Customizer.withDefaults()))
            .authorizeHttpRequests(auth -> auth
                .requestMatchers("/actuator/health").permitAll()
                .anyRequest().authenticated())
            .build();
    }
}

CSRF for stateful (session-based) apps

For server-rendered apps or SPAs that authenticate via session cookies, keep CSRF enabled. Spring Security uses the Synchronizer Token Pattern: it stores a CSRF token in the session and requires it in a header or form field on state-changing requests (POST, PUT, DELETE). Modern SPAs use the CookieCsrfTokenRepository with HttpOnly=false so JavaScript can read and send the token in a header.

Java — CSRF with CookieCsrfTokenRepository for SPAs and session management
// Stateful app — keep CSRF enabled with cookie-based token
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    return http
        .sessionManagement(session -> session
            .sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
            .maximumSessions(1)                         // prevent session duplication
            .maxSessionsPreventsLogin(false))           // new login kicks out old session
        .csrf(csrf -> csrf
            // SPA reads token from cookie, sends in X-XSRF-TOKEN header
            .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
            // Exclude public endpoints from CSRF (e.g. login form POST)
            .ignoringRequestMatchers("/api/auth/login"))
        .authorizeHttpRequests(auth -> auth
            .requestMatchers(HttpMethod.GET, "/**").permitAll()
            .anyRequest().authenticated())
        .formLogin(Customizer.withDefaults())
        .build();
}

// Frontend (JavaScript): read XSRF-TOKEN cookie, send in header
// fetch('/api/orders', {
//   method: 'POST',
//   headers: { 'X-XSRF-TOKEN': getCookie('XSRF-TOKEN') },
//   body: JSON.stringify(order)
// })

Session fixation and concurrent session control

Session fixation attacks set a known session ID before login, then use it after the victim authenticates. Spring Security mitigates this by creating a new session after login (SessionFixationProtectionStrategy). Concurrent session control limits how many simultaneous sessions a user can have — useful for single-device login requirements.

Java — session fixation protection and concurrent session control
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    return http
        .sessionManagement(session -> session
            // Rotate session ID after authentication (default MIGRATE strategy)
            .sessionFixation().migrateSession()   // NEW_SESSION or NONE also available
            // Single active session per user
            .maximumSessions(1)
            .maxSessionsPreventsLogin(true)        // reject new login if session limit reached
            .expiredUrl("/login?expired"))         // redirect if session expired/kicked out
        .build();
}

// Required for concurrent session control
@Bean
public HttpSessionEventPublisher httpSessionEventPublisher() {
    return new HttpSessionEventPublisher();        // notifies Spring Security of session destroy
}

// application.yml — session timeout
server:
  servlet:
    session:
      timeout: 30m     # expire sessions after 30 min of inactivity

Key Points to Remember

  • 1CSRF is only relevant for cookie-based authentication — disable it for JWT Bearer token REST APIs
  • 2SessionCreationPolicy.STATELESS prevents Spring Security from creating or using HTTP sessions — mandatory for JWTs
  • 3CookieCsrfTokenRepository.withHttpOnlyFalse() allows JavaScript SPAs to read the CSRF token from a cookie
  • 4Session fixation: migrateSession() (default) creates a new session after login, copying attributes — prevents fixation attacks
  • 5maximumSessions(1) + maxSessionsPreventsLogin(true) enforces single-device login, rejecting new logins when limit is reached
  • 6HttpSessionEventPublisher bean is required for concurrent session control to receive session destruction notifications

Interview Questions

Sign in to ask Aria
1

Why should CSRF be disabled for a REST API secured with JWT Bearer tokens?

EasyThoughtworks
2

What is a CSRF attack and how does the Synchronizer Token Pattern prevent it?

MediumAmazon
3

What is session fixation and how does Spring Security mitigate it?

MediumOkta
4

How would you configure a Spring Security app to allow only one active session per user?

MediumFlipkart
5

How does CookieCsrfTokenRepository work and why does the cookie need HttpOnly=false for SPAs?

HardNetflix

Ask Aria about CSRF Protection & Session Management

Your personal AI tutor — ask anything about this concept

Revision Status

Personal Notes

Sign in to save personal notes for this topic.

Discussion

Sign in to join the discussion.

Loading discussion…