Skip to content

CSRF Protection (Spring) ​

🟑 MittelBearbeitet β˜‘οΈ15.03.2026

Zusammenfassung ​

CSRF (Cross-Site Request Forgery) Protection verhindert, dass Angreifer unbefugte Aktionen im Namen eines authentifizierten Benutzers ausfΓΌhren. Spring bietet dafΓΌr integrierte Mechanismen basierend auf Token-Validierung.

Kernkonzept ​

CSRF-Angriff: Ein Angreifer trickst einen authentifizierten Benutzer dazu, eine unerwΓΌnschte Aktion auf einer anderen Website auszulΓΆsen (z.B. Geldtransfer, PasswortΓ€nderung). Der Browser sendet dabei automatisch die Session-Cookies mit.

Spring's LΓΆsung: Spring Security generiert fΓΌr jede Session einen eindeutigen CSRF-Token. Bei state-verΓ€ndernden Requests (POST, PUT, DELETE) muss dieser Token mitgesendet werden. Stimmt der Token nicht ΓΌberein, wird die Anfrage abgelehnt.

Token-Flow:

  1. Server generiert Token und sendet es zum Client
  2. Client inkludiert Token in HTML-Form oder Request-Header
  3. Bei Submit validiert Server den Token
  4. UngΓΌltige/fehlende Tokens β†’ 403 Forbidden

Code-Beispiel ​

java
// 1. Security-Konfiguration (Standard - CSRF ist enabled)
@Configuration
@EnableWebSecurity
public class SecurityConfig {
    
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
            .csrf(csrf -> csrf.disable())  // NUR fΓΌr APIs ohne Browser!
            // ODER: .csrf(Customizer.withDefaults())  // Standard: enabled
            .authorizeHttpRequests(auth -> auth
                .requestMatchers("/public/**").permitAll()
                .anyRequest().authenticated()
            )
            .formLogin(Customizer.withDefaults());
        
        return http.build();
    }
}

// 2. HTML-Form (Thymeleaf - Token wird automatisch eingefΓΌgt)
<form method="post" action="/transfer">
    <input type="hidden" name="_csrf" th:value="${_csrf.token}"/>
    <input type="text" name="amount" placeholder="Betrag"/>
    <button type="submit">Überweisen</button>
</form>

// 3. Manual Token in Header (z.B. fΓΌr AJAX)
fetch('/api/transfer', {
    method: 'POST',
    headers: {
        'X-CSRF-TOKEN': document.querySelector('meta[name="_csrf"]').content,
        'Content-Type': 'application/json'
    },
    body: JSON.stringify({ amount: 100 })
});

// 4. REST-Controller
@PostMapping("/transfer")
public ResponseEntity<?> transfer(@RequestParam int amount) {
    // Token wird automatisch validiert - kein zusΓ€tzlicher Code nΓΆtig
    return ResponseEntity.ok("Transfer erfolgreich");
}

Wichtige Punkte ​

  • CSRF ist standardmÀßig in Spring Security enabled β€” muss bewusst deaktiviert werden
  • Nur bei Browser-basierten Anfragen notwendig β€” APIs ohne Cookies kΓΆnnen CSRF ignorieren
  • Token-Namen: _csrf (Thymeleaf), X-CSRF-TOKEN (Header-Standard)
  • Stateless APIs sollten CSRF deaktivieren β€” z.B. Token-basierte Auth (JWT) ist nicht anfΓ€llig
  • SameSite Cookie-Attribute verstΓ€rken den Schutz β€” verhindert automatisches Mitsenken von Cookies

Klassische Fragen ​

Warum CSRF deaktivieren bei REST APIs? ​

REST-APIs mit Token-Auth (JWT, OAuth) sind nicht anfΓ€llig fΓΌr CSRF, da der Token nicht automatisch mitgesendet wird. CSRF ist nur ein Problem bei Cookie-basierter Session-Auth. UnnΓΆtiges Deaktivieren erhΓΆht aber das Risiko β€” besser: gezielt nur fΓΌr /api/** deaktivieren.


Wo bekomme ich den CSRF-Token in der HTML-Seite her? ​

Spring injiziert den Token automatisch ins Modell als _csrf-Objekt. In Thymeleaf: th:value="${_csrf.token}". Alternativ in einem <meta>-Tag speichern und per JavaScript auslesen fΓΌr AJAX-Requests.


Was passiert, wenn der Token falsch oder fehlend ist? ​

Spring antwortet mit HTTP 403 Forbidden und loggt die fehlgeschlagene Validierung. Der Request wird nicht verarbeitet. Das ist das gewΓΌnschte Verhalten β€” es schΓΌtzt vor unbefugten Requests.


Wusstest du schon? ​

Der Begriff CSRF wurde 2001 von Peter W geprΓ€gt, aber das Problem existierte schon lΓ€nger. Lustig: Viele Entwickler deaktivieren CSRF aus "Performance-GrΓΌnden", obwohl ein Token nur ein paar Bytes kostet. Das ist oft nur Faulheit πŸ˜„