Subresource Integrity (SRI) in PHP konfigurieren

Schritt-für-Schritt-Anleitung: SRI in PHP einrichten — Hash-Generierung mit hash_file(), SriHelper-Klasse und Build-Integration für CDN-Ressourcen.

PHP · Schritt für Schritt

Subresource Integrity in PHP

Subresource Integrity (SRI) stellt sicher, dass extern geladene Scripts und Stylesheets nicht manipuliert wurden. Der Browser vergleicht einen Hash im HTML mit dem tatsächlichen Inhalt der Datei. Stimmt der Hash nicht überein, wird die Ressource blockiert. Mit 15 von 166 Punkten im Wolf-Agents Web Security Check ist SRI besonders relevant für PCI DSS 4.0 Compliance.

In PHP generieren Sie SRI-Hashes mit hash_file() für lokale Dateien oder hash() für Remote-Inhalte. Für statische CDN-Ressourcen berechnen Sie den Hash einmalig, für dynamische Builds integrieren Sie die Hash-Generierung in den Build-Prozess. Der header()-Aufruf ist bei SRI nicht nötig — die Hashes werden als HTML-Attribute gesetzt, nicht als HTTP-Header.

Anders als andere Security-Header ist SRI kein HTTP-Header, sondern ein integrity-Attribut auf <script>- und <link>-Tags. Das bedeutet: auto_prepend_file hilft hier nicht. Stattdessen brauchen Sie eine Helper-Funktion, die den Hash berechnet und im Template ausgibt.

1 Schritt 1 von 3

SRI-Hashes in PHP generieren

Berechnen Sie den SHA-384-Hash der externen Ressource und geben Sie ihn als integrity-Attribut im HTML aus. Das crossorigin="anonymous"-Attribut ist bei Cross-Origin-Ressourcen Pflicht. Für Produktionsanwendungen empfehlen wir die wiederverwendbare SriHelper-Klasse mit integriertem Caching.

helpers/sri.php Direkte Methode
<?php
// helpers/sri.php — SRI-Hash generieren

// Variante A: Hash fuer lokale Datei berechnen
$hash = base64_encode(hash_file('sha384', './assets/vendor.js', true));
$integrity = 'sha384-' . $hash;

// Variante B: Hash fuer Remote-Ressource
$content = file_get_contents('https://cdn.example.com/lib.js');
$remoteHash = 'sha384-' . base64_encode(hash('sha384', $content, true));

// Im HTML-Template:
// <script src="https://cdn.example.com/lib.js"
//   integrity="<?= htmlspecialchars($integrity) ?>"
//   crossorigin="anonymous"></script>
helpers/SriHelper.php Wiederverwendbar
<?php
// helpers/SriHelper.php — Wiederverwendbare SRI-Klasse

class SriHelper
{
    private static array $cache = [];

    public static function hash(string $filePath): string
    {
        if (isset(self::$cache[$filePath])) {
            return self::$cache[$filePath];
        }

        if (!file_exists($filePath)) {
            throw new \RuntimeException(
                "SRI: Datei nicht gefunden: $filePath"
            );
        }

        $hash = 'sha384-' . base64_encode(
            hash_file('sha384', $filePath, true)
        );

        self::$cache[$filePath] = $hash;
        return $hash;
    }

    public static function script(
        string $src, string $localPath
    ): string {
        $integrity = self::hash($localPath);
        return sprintf(
            '<script src="%s" integrity="%s" crossorigin="anonymous"></script>',
            htmlspecialchars($src),
            htmlspecialchars($integrity)
        );
    }
}
Middleware/SriMiddleware.php PSR-15 Middleware
<?php
// Middleware/SriMiddleware.php — PSR-15
// Injiziert SRI-Hashes in HTML-Responses

namespace App\Middleware;

use Psr\Http\Message\ResponseInterface;
use Psr\Http\Server\MiddlewareInterface;

class SriMiddleware implements MiddlewareInterface
{
    private array $manifest;

    public function __construct(string $manifestPath)
    {
        // sri-manifest.json vom Build-Prozess laden
        $this->manifest = json_decode(
            file_get_contents($manifestPath), true
        );
    }
}
SHA-384 als Standard

SHA-384 bietet den besten Kompromiss zwischen Sicherheit und Performance. SHA-256 ist ebenfalls erlaubt, SHA-512 ist optional. Verwenden Sie immer den true-Parameter in hash_file() für binäre Ausgabe — base64_encode() erwartet binäre Daten, keinen Hex-String.

2 Schritt 2 von 3

Konfiguration verifizieren

Prüfen Sie die SRI-Attribute im generierten HTML. Anders als bei HTTP-Headern prüfen Sie hier nicht die Response-Header, sondern den HTML-Quelltext. Der Hash muss exakt mit dem Dateiinhalt übereinstimmen — ein einziges geändertes Byte invalidiert den Hash.

Terminal Verifizierung
# SRI-Attribute im HTML pruefen
curl -s https://ihre-domain.de | grep -i integrity

# Erwartete Ausgabe:
<script src="..." integrity="sha384-..." crossorigin="anonymous">

# Hash manuell verifizieren:
curl -s https://cdn.example.com/lib.js | \
  openssl dgst -sha384 -binary | openssl base64 -A

# Der Wert muss mit dem integrity-Attribut uebereinstimmen
Nutzen Sie den Wolf-Agents Web Security Check für eine vollständige Prüfung aller 15 Punkte dieses Headers.
3 Schritt 3 von 3

Häufige Fehler

Hash stimmt nicht nach CDN-Update

Wenn der CDN-Anbieter die Datei aktualisiert, ändert sich der Hash. Der Browser blockiert die Ressource. Lösung: Version in der URL pinnen (z.B. /lib@2.1.0/dist/lib.min.js) und Hash und URL gemeinsam aktualisieren.

crossorigin-Attribut fehlt

SRI erfordert das crossorigin="anonymous"-Attribut bei Cross-Origin-Ressourcen. Ohne dieses Attribut prüft der Browser den Hash nicht und blockiert die Ressource mit einem CORS-Fehler in der Konsole.

hash_file() ohne binäre Ausgabe

Der dritte Parameter von hash_file() muss true sein für binäre Ausgabe. Ohne true gibt PHP einen Hex-String zurück, und base64_encode() produziert einen falschen SRI-Hash.

SRI bei dynamisch generierten Assets

SRI funktioniert nicht mit dynamisch generierten Inhalten, deren Hash sich pro Request ändert. Verwenden Sie SRI nur für statische, versionierte Dateien. Inline-Scripts und Inline-Styles unterstützen kein SRI — verwenden Sie dafür CSP-Nonces.

Compliance-Relevanz

PCI DSS 4.0 — Anforderung 6.4.3 — Integritätskontrolle externer Scripts auf Zahlungsseiten ist ab April 2025 Pflicht.
OWASP ASVS — V14 — Integritätsprüfung für extern geladene Ressourcen als Teil der Supply-Chain-Security.
NIS2 — Art. 21(d) — Sicherheit der Lieferkette, insbesondere bei externen Abhängigkeiten.

Wie steht Ihre Domain bei Subresource Integrity?

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