Jak zaimplementować bezpieczne nagłówki przy użyciu Cloudflare Workers?

Przewodnik krok po kroku dotyczący implementacji bezpiecznych nagłówków HTTP w witrynach obsługiwanych przez Cloudflare przy użyciu Cloudflare Workers.

Istnieje wiele sposobów implementacji nagłówków odpowiedzi HTTP w celu zabezpieczenia witryn przed typowymi lukami w zabezpieczeniach, takimi jak XSS, Clickjacking, sniffing MIMI, wstrzykiwanie między witrynami i wiele innych. Jego powszechnie przyjęta praktyka i zalecana przez OWASP.

Wcześniej pisałem o implementacji nagłówków na serwerze WWW, takim jak Apache, Nginx i IIS. Jeśli jednak używasz Cloudflare do ochrony i doładowania swoich witryn, możesz z tego skorzystać Pracownicy Cloudflare do manipulowania nagłówkami odpowiedzi HTTP.

Cloudflare Workers to platforma bezserwerowa, na której można uruchamiać kod JavaScript, C, C++, Rust. Jest wdrażany w każdym centrum danych Cloudflare, którego jest ponad 200 na całym świecie.

Implementacja jest bardzo prosta i elastyczna. Zapewnia elastyczność stosowania nagłówków w całej witrynie, w tym w subdomenie lub określonym URI z rozszerzeniem pasujący wzórn za pomocą wyrażenia regularnego.

Do tej demonstracji użyję kod przez Scotta Helme’a.

Zacznijmy…👨‍💻

  • Skopiuj kod worker.js z GitHub i wklej do edytora skryptów
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)));

Nie zapisuj jeszcze; możesz dostosować następujące nagłówki, aby spełnić wymagania.

Content-Security-Policy – ​​jeśli chcesz zastosować swoją politykę dotyczącą aplikacji, możesz to zrobić tutaj.

Np. jeśli chcesz pozyskiwać treści przez iFrame pod wieloma adresami URL, możesz skorzystać z przodków ramek, jak poniżej.

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

Powyższe pozwoli na załadowanie treści z gf.dev, newsblog.pl.com i self site.

X-Frame-Options – możesz zmienić na SAMEORIGIN, jeśli zamierzasz wyświetlać zawartość swojej witryny na jakiejś stronie w tej samej witrynie przy użyciu elementu iframe.

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

Serwer – tutaj możesz wyczyścić nagłówek serwera. Umieść, co chcesz.

"Server" : "newsblog.pl Server",

RemoveHeaders – czy musisz usunąć niektóre nagłówki, aby ukryć wersje, aby złagodzić podatność na wyciek informacji?

Możesz to zrobić tutaj.

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

Dodawanie nowych nagłówków – jeśli chcesz przekazać niestandardowe nagłówki do swoich aplikacji, możesz je dodać w sekcji securityHeaders, jak poniżej.

let securityHeaders = {
	"Content-Security-Policy" : "frame-ancestors 'self' gf.dev newsblog.pl.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",
}

Po zakończeniu dostosowywania wszystkich wymaganych nagłówków nazwij pracownika i kliknij przycisk Zapisz i wdróż.

Świetny! worker jest gotowy, a następnie musimy dodać go do witryny, w której chcesz zastosować nagłówki. Zastosuję to do mojego laboratorium.

  • Przejdź do strony głównej/panelu Cloudflare i wybierz witrynę.
  • Przejdź do karty Pracownicy >> Dodaj trasę.
  • Wprowadź adres URL w Trasie; możesz zastosować Regex tutaj.
  • Wybierz nowo utworzonych pracowników i Zapisz

To wszystko; w ciągu sekundy zauważysz, że wszystkie nagłówki zostały zaimplementowane na stronie.

Oto jak to wygląda z Chrome Dev Tools. Możesz także przetestować nagłówek za pomocą narzędzia nagłówka HTTP.

Nie wiem, dlaczego nagłówek serwera nie jest odzwierciedlany. Myślę, że Cloudflare to zastępuje.

Widzisz, ogólna implementacja zajmuje około 15 minut i nie są wymagane żadne przestoje ani ponowne uruchamianie, jak Apache lub Nginx. Jeśli planujesz zastosować to w miejscu produkcyjnym, sugerowałbym najpierw przetestowanie na niższym środowisku lub za pomocą trasy, którą możesz zastosować na stronach testowych, aby zweryfikować wyniki. Po usatysfakcjonowaniu pchaj tam, gdzie chcesz.

To jest niesamowite!

Dzięki Scotta dla kodu.