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.

PHP · Schritt für Schritt

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.

1 Schritt 1 von 3

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.

security-headers.php Variante A: Direkt
<?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 Variante B: Auto-Prepend
; .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
src/Middleware/NosniffMiddleware.php Variante C: PSR-15
<?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'
        );
    }
}
auto_prepend_file empfohlen

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.

2 Schritt 2 von 3

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.

Terminal Verifizierung
# 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
Statische Dateien: PHP 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.
Nutzen Sie den Wolf-Agents Web Security Check für eine vollständige Prüfung aller 10 Punkte dieses Headers.
3 Schritt 3 von 3

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

OWASP ASVS — V14.4.4 fordert X-Content-Type-Options: nosniff als Pflicht-Header für alle Webanwendungen.
BSI — APP.3.1 — Webserver-Absicherung mit Security Headern als Basis-Maßnahme.
NIS2 — Art. 21(e) — Sicherheit bei Entwicklung und Wartung von Informationssystemen.
PCI DSS 4.0 — Anforderung 6.2.4 — Schutz vor bekannten Angriffsvektoren in Webanwendungen.

Wie steht Ihre Domain bei X-Content-Type-Options?

Prüfen Sie es jetzt — kostenlos, ohne Registrierung, mit 166 Prüfpunkte.