Appearance
CSRF Protection (Spring) β
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:
- Server generiert Token und sendet es zum Client
- Client inkludiert Token in HTML-Form oder Request-Header
- Bei Submit validiert Server den Token
- 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 π