X-Content-Type-Options in Spring Boot
Spring Security setzt nosniff automatisch -- verifizieren Sie den Default, konfigurieren Sie korrekte Content-Types und schuetzen Sie auch Actuator-Endpoints.
MIME-Sniffing-Schutz in Spring Boot
X-Content-Type-Options: nosniff verhindert, dass Browser den MIME-Type einer Ressource erraten (MIME-Sniffing). Ohne diesen Header koennten Angreifer eine als Bild getarnte JavaScript-Datei einschleusen. Der Header ist mit 10 von 166 Punkten im Wolf-Agents Web Security Check bewertet.
Spring Security setzt X-Content-Type-Options: nosniff automatisch als Default. Das bedeutet: Ihre Spring-Boot-Anwendung ist standardmaessig geschützt. Trotzdem sollten Sie den Header verifizieren und sicherstellen, dass alle Responses korrekte Content-Type-Header setzen -- denn nosniff erzwingt den deklarierten MIME-Type.
Spring Security Default verifizieren
Spring Security setzt X-Content-Type-Options: nosniff automatisch für alle Responses, die durch die SecurityFilterChain laufen. Verifizieren Sie den Header per curl. Wenn Sie den Default explizit machen wollen, verwenden Sie contentTypeOptions(Customizer.withDefaults()).
// SecurityConfig.java -- X-Content-Type-Options (Default)
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http)
throws Exception {
// Spring Security setzt X-Content-Type-Options: nosniff
// automatisch -- keine explizite Konfiguration noetig.
// Falls Sie den Default explizit machen wollen:
http.headers(headers -> headers
.contentTypeOptions(Customizer.withDefaults())
);
return http.build();
}
// WARNUNG: Header NIEMALS deaktivieren!
// http.headers(h -> h.contentTypeOptions(cto -> cto.disable()));Im Gegensatz zu anderen Security-Headern gibt es keinen legitimen Grund, nosniff zu deaktivieren. Die disable()-Methode existiert, sollte aber niemals verwendet werden.
Content-Types korrekt konfigurieren
Da nosniff den Browser zwingt, den deklarierten MIME-Type zu verwenden, müssen alle Responses den korrekten Content-Type Header setzen. Falsche Content-Types fuehren dazu, dass Ressourcen nicht geladen werden.
// Controller mit korrektem Content-Type
@RestController
public class ApiController {
@GetMapping(value = "/api/data",
produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<Map<String, Object>> getData() {
return ResponseEntity.ok()
.contentType(MediaType.APPLICATION_JSON)
.body(Map.of("status", "ok"));
}
// Datei-Downloads mit korrektem MIME-Type
@GetMapping("/download/{filename}")
public ResponseEntity<byte[]> download(
@PathVariable String filename) {
byte[] content = loadFile(filename);
String mimeType = detectMimeType(filename);
return ResponseEntity.ok()
.header("Content-Type", mimeType)
.header("Content-Disposition",
"attachment; filename="" + filename + """)
.body(content);
}
}Actuator-Endpoints absichern
Spring Boot Actuator-Endpoints liefern JSON-Daten mit sensiblen Informationen. Stellen Sie sicher, dass auch diese Endpoints den nosniff-Header setzen. Bei separaten SecurityFilterChains muss jede Chain die Header-Konfiguration enthalten.
// application.yml -- Actuator mit Security Headers
management:
endpoints:
web:
exposure:
include: health,info,metrics
// Separate SecurityFilterChain fuer Actuator
@Bean
@Order(1)
public SecurityFilterChain actuatorSecurity(HttpSecurity http)
throws Exception {
http.securityMatcher("/actuator/**")
.authorizeHttpRequests(auth -> auth
.requestMatchers("/actuator/health").permitAll()
.anyRequest().hasRole("ADMIN"))
.headers(headers -> headers
.contentTypeOptions(Customizer.withDefaults()));
return http.build();
}Header verifizieren
Prüfen Sie den X-Content-Type-Options-Header mit curl. Der Wert muss nosniff sein -- es gibt nur diesen einen gueltigen Wert.
# X-Content-Type-Options pruefen
curl -sI http://localhost:8080 | grep -i x-content-type-options
# Erwartete Ausgabe (Spring Security Default):
x-content-type-options: nosniffHäufige Fehler bei X-Content-Type-Options in Spring Boot
nosniff deaktiviert wegen Content-Type-Problemen
Wenn Ressourcen nach Aktivierung von nosniff nicht laden, ist der Content-Type falsch konfiguriert -- nicht der Security-Header. Korrigieren Sie den MIME-Type statt nosniff zu deaktivieren.
Separate SecurityFilterChain ohne Header-Config
Wenn Sie mehrere SecurityFilterChain-Beans definieren (z.B. für Actuator und API), erbt jede Chain nur die Header, die Sie explizit konfigurieren. Vergessene Chains liefern keine Security-Header.
Statische Ressourcen per web.ignoring() ausgeschlossen
Wenn Sie web.ignoring().requestMatchers("/static/**") verwenden, umgehen diese Requests die gesamte SecurityFilterChain -- inklusive nosniff. Verwenden Sie stattdessen permitAll().
Actuator-Endpoints ohne Security Headers
Actuator-Endpoints unter /actuator/** können bei falscher Konfiguration ohne Security-Header ausgeliefert werden. Definieren Sie eine eigene SecurityFilterChain mit @Order(1) für Actuator.
Compliance-Relevanz
X-Content-Type-Options ist ein grundlegender Security-Header, der in verschiedenen Compliance-Frameworks gefordert wird.
Wie steht Ihre Domain bei X-Content-Type-Options?
Prüfen Sie es jetzt — kostenlos, ohne Registrierung, mit 166 Prüfpunkte.