X-Content-Type-Options in PHP konfigurieren
Schritt-für-Schritt-Anleitung: MIME-Sniffing in PHP verhindern — mit header()-Code zum Kopieren, auto_prepend_file und PSR-15-Middleware.
X-Content-Type-Options in PHP
X-Content-Type-Options: nosniff verhindert MIME-Sniffing — Browser raten dann nicht mehr den Content-Type anhand des Inhalts. Ohne diesen Header können Angreifer Textdateien als JavaScript ausführen lassen. Mit 10 von 166 Punkten im Wolf-Agents Web Security Check ist dieser Header ein Pflicht-Header für jede PHP-Anwendung.
In PHP setzen Sie den Header mit einem einzigen header()-Aufruf. Der einzige gültige Wert ist nosniff. Dieser Header ist ein Quick-Win — eine Zeile Code, keine Nebenwirkungen, sofortige Verbesserung. Die wichtigste Voraussetzung: header() muss vor jeder Ausgabe aufgerufen werden, sonst erhalten Sie den berüchtigten "Headers already sent"-Fehler.
Für Projekte ohne Framework empfehlen wir die auto_prepend_file-Methode in der .user.ini. Damit wird Ihre Security-Headers-Datei automatisch vor jedem PHP-Script geladen — garantiert vor jeder Ausgabe. Frameworks wie Laravel, Symfony oder Slim nutzen stattdessen PSR-15-Middleware.
X-Content-Type-Options in PHP konfigurieren
Es gibt drei Wege, den Header in PHP zu setzen. Variante A ist der direkte header()-Aufruf — ideal für schnelle Integration. Variante B nutzt auto_prepend_file in der .user.ini, um den Header automatisch für alle PHP-Dateien zu setzen. Variante C ist eine PSR-15-Middleware für Framework-basierte Projekte.
<?php
// security-headers.php — MIME-Sniffing verhindern
if (!headers_sent()) {
header('X-Content-Type-Options: nosniff');
}
// Wichtig: Korrekte Content-Types setzen
// Fuer JSON-APIs:
header('Content-Type: application/json; charset=utf-8');
// Fuer Downloads:
// header('Content-Type: application/octet-stream'); ; .user.ini — Auto-Prepend fuer Security Headers
; Wird vor jedem PHP-Script automatisch geladen
auto_prepend_file = "/var/www/html/security-headers.php"
; Hinweis: .user.ini wird von PHP-FPM gecached
; user_ini.cache_ttl = 300 (5 Minuten Default)
; Nach Aenderung bis zu 5 Min warten oder FPM neustarten <?php
// src/Middleware/NosniffMiddleware.php — PSR-15
namespace App\Middleware;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;
class NosniffMiddleware implements MiddlewareInterface
{
public function process(
ServerRequestInterface $request,
RequestHandlerInterface $handler
): ResponseInterface {
$response = $handler->handle($request);
return $response->withHeader(
'X-Content-Type-Options',
'nosniff'
);
}
} Die .user.ini-Methode garantiert, dass Header vor jeder Ausgabe gesetzt werden — der häufigste Fehler ("Headers already sent") ist damit ausgeschlossen. Der Pfad in auto_prepend_file muss absolut sein.
Konfiguration verifizieren
Prüfen Sie den Header mit curl oder dem Wolf-Agents Web Security Check. Wichtig: header() in PHP setzt den Header nur für PHP-Dateien. Statische Dateien (CSS, JS, Bilder) werden direkt vom Webserver ausgeliefert und brauchen eine separate Konfiguration in Apache oder Nginx.
# X-Content-Type-Options pruefen
curl -sI https://ihre-domain.de | grep -i x-content-type-options
# Erwartete Ausgabe:
X-Content-Type-Options: nosniff
# Hinweis: header() setzt nur fuer PHP-Dateien.
# Statische Dateien (CSS, JS, Bilder) brauchen
# die Webserver-Konfiguration (Apache/Nginx).
# Testen Sie daher PHP- UND statische URLs:
curl -sI https://ihre-domain.de/style.css | grep -i x-content-type header() wirkt nur bei PHP-Dateien. Für statische Assets (CSS, JS, Bilder) muss der Header im Webserver gesetzt werden — siehe die Nginx- oder Apache-Anleitung. Häufige Fehler
Headers already sent
Der häufigste PHP-Fehler: header() nach einer Ausgabe aufrufen. Bereits ein Leerzeichen oder eine BOM vor <?php zählt als Ausgabe. Lösung: auto_prepend_file in der .user.ini nutzen — die Header-Datei wird garantiert vor jeder Ausgabe geladen.
auto_prepend_file vom Hoster blockiert
Einige Shared-Hosting-Anbieter erlauben keine .user.ini-Direktiven. Prüfen Sie mit phpinfo(), ob auto_prepend_file gesetzt wird. Alternative: Header direkt im ersten require der index.php setzen.
Falscher Content-Type bei Downloads
Mit nosniff vertraut der Browser dem Content-Type-Header. Wenn PHP Dateien mit falschem MIME-Type ausliefert (z.B. text/html statt application/pdf), werden Downloads fehlschlagen. Setzen Sie immer den korrekten Content-Type.
PHP-FPM cachet .user.ini
PHP-FPM cachet die .user.ini für 300 Sekunden (5 Minuten). Änderungen an auto_prepend_file werden erst nach Ablauf des Cache-TTL oder nach einem PHP-FPM-Restart wirksam. Starten Sie in der Produktion PHP-FPM neu: systemctl restart php-fpm.
Compliance-Relevanz
Wie steht Ihre Domain bei X-Content-Type-Options?
Prüfen Sie es jetzt — kostenlos, ohne Registrierung, mit 166 Prüfpunkte.