Wie implementiert man sichere Header mit Cloudflare-Workern?

Sichere HTTP-Header mit Cloudflare Workers implementieren: Eine detaillierte Anleitung

Die Implementierung von HTTP-Antwortheadern ist eine entscheidende Maßnahme, um Webseiten vor einer Vielzahl von Sicherheitsbedrohungen zu schützen. Dazu gehören unter anderem Cross-Site-Scripting (XSS), Clickjacking, MIME-Sniffing und Cross-Site-Injection. Diese Praxis wird von vielen Sicherheitsexperten, einschließlich OWASP, ausdrücklich empfohlen.

Während es etablierte Methoden zur Header-Implementierung auf Webservern wie Apache, Nginx und IIS gibt, bietet Cloudflare mit seinen Cloudflare Workers eine flexible Alternative. Diese ermöglicht es, HTTP-Antwortheader direkt zu manipulieren.

Cloudflare Workers fungiert als serverlose Plattform, auf der Sie JavaScript-, C-, C++- und Rust-Code ausführen können. Diese Plattform ist in über 200 Rechenzentren von Cloudflare weltweit verfügbar.

Die Implementierung ist unkompliziert und äußerst anpassbar. Sie können Header für die gesamte Webseite, einschließlich Subdomains, oder für bestimmte URIs über Regex-basierte Muster festlegen.

In dieser Anleitung verwenden wir den Code von Scott Helme, der auf GitHub bereitgestellt wird.

Legen wir los! 👨‍💻

  • Melden Sie sich bei Cloudflare an und wählen Sie „Workers“ aus. (Direktlink: Cloudflare Workers)
  • Kopieren Sie den worker.js-Code von GitHub und fügen Sie ihn in den Skripteditor ein.
    const securityHeaders = {
            "Content-Security-Policy": "upgrade-insecure-requests",
            "Strict-Transport-Security": "max-age=1000",
            "X-Xss-Protection": "1; mode=block",
            "X-Frame-Options": "DENY",
            "X-Content-Type-Options": "nosniff",
            "Referrer-Policy": "strict-origin-when-cross-origin"
        },
        sanitiseHeaders = {
            Server: ""
        },
        removeHeaders = [
            "Public-Key-Pins",
            "X-Powered-By",
            "X-AspNet-Version"
        ];

    async function addHeaders(req) {
        const response = await fetch(req),
            newHeaders = new Headers(response.headers),
            setHeaders = Object.assign({}, securityHeaders, sanitiseHeaders);

        if (newHeaders.has("Content-Type") && !newHeaders.get("Content-Type").includes("text/html")) {
            return new Response(response.body, {
                status: response.status,
                statusText: response.statusText,
                headers: newHeaders
            });
        }

        Object.keys(setHeaders).forEach(name => newHeaders.set(name, setHeaders[name]));

        removeHeaders.forEach(name => newHeaders.delete(name));

        return new Response(response.body, {
            status: response.status,
            statusText: response.statusText,
            headers: newHeaders
        });
    }

    addEventListener("fetch", event => event.respondWith(addHeaders(event.request)));
  

Speichern Sie das Skript noch nicht. Es ist ratsam, die Header gemäß Ihren Anforderungen anzupassen.

Content-Security-Policy: Hier können Sie Ihre spezifische Inhaltsrichtlinie implementieren. Beispielsweise können Sie mit frame-ancestors festlegen, von welchen URLs Inhalte per iFrame eingebunden werden dürfen.

"Content-Security-Policy" : "frame-ancestors 'self' gf.dev wdzwdz.com",

Dieser Code erlaubt es, Inhalte von gf.dev, wdzwdz.com und der eigenen Webseite einzubinden.

X-Frame-Options: Verwenden Sie SAMEORIGIN, wenn Sie die Inhalte Ihrer Webseite innerhalb der gleichen Domain per iFrame anzeigen möchten.

"X-Frame-Options": "SAMEORIGIN",

Server: Hier können Sie den Server-Header anpassen oder bereinigen, um Informationen zu verbergen.

"Server" : "wdzwdz Server",

RemoveHeaders: Hier können Sie Header entfernen, um die Offenlegung von Versionsinformationen und damit verbundene Sicherheitsrisiken zu minimieren.

    let removeHeaders = [
        "Public-Key-Pins",
        "X-Powered-By",
        "X-AspNet-Version",
    ]
  

Neue Header hinzufügen: Im Abschnitt „securityHeaders“ können Sie benutzerdefinierte Header definieren, die an Ihre Anwendung übergeben werden.

    let securityHeaders = {
        "Content-Security-Policy" : "frame-ancestors 'self' gf.dev wdzwdz.com",
        "Strict-Transport-Security" : "max-age=1000",
        "X-Xss-Protection" : "1; mode=block",
        "X-Frame-Options" : "SAMEORIGIN",
        "X-Content-Type-Options" : "nosniff",
        "Referrer-Policy" : "strict-origin-when-cross-origin",
            "Custom-Header"  : "Success",
    }
  

Nachdem Sie alle benötigten Header angepasst haben, geben Sie dem Worker einen Namen und klicken Sie auf „Save and Deploy“.

Der Worker ist nun bereit. Als nächstes müssen Sie ihn der gewünschten Webseite zuweisen.

  • Gehen Sie zum Cloudflare Dashboard und wählen Sie die entsprechende Seite aus.
  • Navigieren Sie zum Tab „Workers“ und klicken Sie auf „Route hinzufügen“.
  • Geben Sie die URL oder ein Regex-basiertes Muster an.
  • Wählen Sie den erstellten Worker aus und speichern Sie die Route.

Das war’s! Die Header sind nun auf der Webseite implementiert. Sie können die Änderungen sofort überprüfen.

Hier ist ein Beispiel aus den Chrome Dev Tools. Sie können die Header auch mit einem HTTP-Header-Tool Ihrer Wahl überprüfen.

Es scheint, dass der Server-Header in diesem Fall von Cloudflare überschrieben wird.

Die gesamte Implementierung ist in etwa 15 Minuten erledigt und erfordert keine Ausfallzeiten oder Neustarts wie bei Apache oder Nginx. Wenn Sie dies auf einer Produktionsseite einsetzen möchten, ist es empfehlenswert, die Änderungen zuerst in einer Testumgebung oder mit einer Route auf Testseiten zu überprüfen. Sobald Sie mit den Ergebnissen zufrieden sind, können Sie die Header für die Produktionsumgebung aktivieren.

Fantastisch!

Vielen Dank an Scott für die Bereitstellung des Codes.