X-Content-Type-Options für Nginx konfigurieren
Schritt-für-Schritt-Anleitung: nosniff-Header setzen, MIME-Types korrekt konfigurieren und Upload-Verzeichnisse gegen MIME-Sniffing absichern.
X-Content-Type-Options auf Nginx
Nginx setzt den Header mit der Direktive add_header X-Content-Type-Options "nosniff" always;. Das Schlüsselwort always ist entscheidend — ohne es fehlt der Header bei Fehlerantworten (4xx, 5xx). Wichtig: Bei mehreren add_header-Direktiven in verschachtelten Blöcken werden Header aus übergeordneten Blöcken nicht vererbt. Den Header in jedem Block explizit setzen, der eigene Header definiert.
Diese Anleitung zeigt die Konfiguration in vier Schritten: Header global setzen, MIME-Types prüfen, Upload-Pfade absichern und verifizieren.
Header setzen
Fügen Sie add_header X-Content-Type-Options "nosniff" always; in den http-Block Ihrer nginx.conf ein. Das always-Keyword erzwingt den Header auch bei Fehlerantworten — ohne es fehlt er bei 404- und 500-Seiten.
# /etc/nginx/nginx.conf oder /etc/nginx/conf.d/security.conf
http {
# Globaler Security-Header — gilt für alle Server-Blöcke
add_header X-Content-Type-Options "nosniff" always;
include /etc/nginx/mime.types;
default_type application/octet-stream;
# Weitere empfohlene Security-Header
add_header X-Frame-Options "SAMEORIGIN" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
} location-Block eigene add_header-Direktiven enthält, werden Header aus übergeordneten Blöcken nicht automatisch vererbt. Den X-Content-Type-Options-Header in jedem solchen Block explizit wiederholen. sudo nginx -t && sudo systemctl reload nginx MIME-Types korrekt konfigurieren
nosniff blockiert Ressourcen mit falschem Content-Type. Stellen Sie sicher, dass Nginx die richtigen MIME-Typen deklariert — besonders für JavaScript (text/javascript per RFC 9239) und CSS. Die Datei /etc/nginx/mime.types sollte für moderne Browser aktuell sein.
# /etc/nginx/mime.types — Auszug der kritischen Typen
types {
# JavaScript — RFC 9239 Standard
text/javascript js mjs;
# Stylesheets
text/css css;
# JSON
application/json json;
# Bilder
image/svg+xml svg svgz;
image/png png;
image/jpeg jpg jpeg;
# Fonts
font/woff2 woff2;
font/woff woff;
} curl -sI https://ihre-domain.de/app.js | grep content-type, ob JavaScript als text/javascript ausgeliefert wird. Ältere Nginx-Versionen verwenden noch application/javascript — das funktioniert, aber text/javascript ist der aktuelle Standard. Upload-Verzeichnisse absichern
Upload-Verzeichnisse sind das primäre Ziel von MIME-Sniffing-Angriffen. Erzwingen Sie für alle Dateien in diesen Pfaden Content-Disposition: attachment (Download statt Browser-Rendering) und deaktivieren Sie PHP-Ausführung im Upload-Verzeichnis.
# Upload-Verzeichnis absichern — Script-Ausführung verhindern
server {
listen 443 ssl;
server_name ihre-domain.de;
# Globaler Header
add_header X-Content-Type-Options "nosniff" always;
location /uploads/ {
# Header auch hier explizit setzen (Vererbung greift nicht bei eigenem add_header)
add_header X-Content-Type-Options "nosniff" always;
# Download erzwingen statt Browser-Rendering
add_header Content-Disposition 'attachment' always;
# PHP / CGI-Ausführung in Upload-Pfad verbieten
location ~ .php$ {
deny all;
return 404;
}
}
} Für maximale Isolation liefern Sie user-generierte Inhalte auf einer separaten Domain (z.B. cdn.ihre-domain.de) aus. Damit ist auch der Same-Origin-Schutz aktiv — Scripts aus der Upload-Domain können nicht auf Cookies der Hauptdomain zugreifen.
Verifizierung
Nach dem Reload prüfen Sie den Header mit curl. Testen Sie sowohl die Hauptseite als auch statische Assets und das Upload-Verzeichnis — besonders wenn Sie verschachtelte location-Blöcke verwenden.
# 1. Nginx-Konfiguration prüfen
sudo nginx -t
# 2. Nginx neu laden (ohne Downtime)
sudo systemctl reload nginx
# 3. Header verifizieren
curl -sI https://ihre-domain.de | grep -i x-content-type
# Erwartete Ausgabe:
# x-content-type-options: nosniff
# 4. Upload-Verzeichnis prüfen
curl -sI https://ihre-domain.de/uploads/test.jpg | grep -i content-disposition
# Erwartete Ausgabe: content-disposition: attachment Der Wolf-Agents Scanner prüft automatisch, ob X-Content-Type-Options: nosniff auf Ihrer Domain gesetzt ist — inklusive Punktabzug bei fehlenden oder falschen Werten.
Wie steht Ihre Domain bei X-Content-Type-Options?
Prüfen Sie es jetzt — kostenlos, ohne Registrierung, mit 166 Prüfpunkte.
Häufig gestellte Fragen
Wo soll ich add_header X-Content-Type-Options in Nginx platzieren?
Am besten im http-Block der nginx.conf, damit der Header für alle Server gilt. Alternativ in jedem server-Block. Wichtig: Das Schlüsselwort always sorgt dafür, dass der Header auch bei Fehlerantworten (4xx, 5xx) gesendet wird — ohne always fehlt er bei Fehlerseiten.
Muss ich die MIME-Types in Nginx manuell konfigurieren?
Nginx lädt standardmäßig mime.types aus /etc/nginx/mime.types. Diese Datei enthält für .js bereits text/javascript und für .css text/css. Sie müssen nur prüfen, ob Ihre nginx.conf include /etc/nginx/mime.types; enthält und ob die Datei aktuell ist.
Wie verhindere ich Script-Ausführung in Upload-Verzeichnissen?
Erstellen Sie einen location-Block für Ihr Upload-Verzeichnis mit: location /uploads/ { add_header Content-Disposition "attachment"; add_header X-Content-Type-Options "nosniff" always; } — das erzwingt Download statt Browser-Rendering für alle Dateien in diesem Pfad.
Überschreibt ein innerer location-Block den äußeren add_header?
Ja — das ist ein häufiger Nginx-Fallstrick. add_header-Direktiven werden NICHT vererbt, wenn ein location-Block eigene add_header-Direktiven enthält. Setzen Sie X-Content-Type-Options daher in JEDEM location-Block, der eigene Header definiert, oder nutzen Sie map-Direktiven.
Wie teste ich, ob nosniff korrekt gesetzt ist?
Mit curl -sI https://ihre-domain.de | grep -i x-content-type. Sie sollten X-Content-Type-Options: nosniff in der Ausgabe sehen. Alternativ: Browser DevTools → Network → Response Headers für eine beliebige Ressource.