Hur implementerar man säkra rubriker med Cloudflare Workers?

En steg-för-steg-guide för att implementera säkra HTTP-rubriker på webbplatser som drivs av Cloudflare med Cloudflare Workers.

Det finns många sätt att implementera HTTP-svarsrubriker för att säkra webbplatser från vanliga sårbarheter, som XSS, Clickjacking, MIMI sniffing, cross-site injection och många fler. Dess allmänt antagna praxis och rekommenderas av OWASP.

Tidigare skrev jag om att implementera headers i en webbserver som Apache, Nginx och IIS. Men om du använder Cloudflare för att skydda och överladda dina webbplatser kan du dra nytta av det Cloudflare-arbetare för att manipulera HTTP-svarshuvudena.

Cloudflare Workers är en serverlös plattform där du kan köra JavaScript, C, C++, Rust-kod. Den distribueras på alla Cloudflare-datacenter, som är fler än 200 över hela världen.

Implementeringen är mycket enkel och flexibel. Det ger dig flexibiliteten att tillämpa rubrikerna på hela webbplatsen, inklusive underdomänen eller specifik URI med en matchande mönstern använder Regex.

För den här demonstrationen kommer jag att använda koda av Scott Helme.

Låt oss sätta igång…👨‍💻

  • Logga in på Cloudflare och klicka på Workers (Direktlänk)

  • Kopiera worker.js-koden från GitHub och klistra in i Script editor
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)));

Spara inte ännu; du kanske vill justera följande rubriker för att uppfylla kravet.

Content-Security-Policy – ​​om du behöver tillämpa din ansökningspolicy kan du göra det här.

Ex – om du behöver hämta innehåll via iFrame på flera webbadresser, kan du dra fördel av frame-förfäder enligt nedan.

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

Ovanstående kommer att tillåta att ladda innehållet från gf.dev, adminvista.com.com och egen webbplats.

X-Frame-Options – du kan ändra till SAMEORIGIN om du har för avsikt att visa din webbplats innehåll på någon sida inom samma webbplats med iframe.

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

Server – du kan rensa serverhuvudet här. Lägg vad du vill.

"Server" : "adminvista.com Server",

RemoveHeaders – behöver du ta bort några rubriker för att dölja versionerna för att mildra sårbarheten för informationsläckage?

Du kan göra det här.

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

Lägga till nya rubriker – om du behöver skicka några anpassade rubriker till dina applikationer kan du lägga till dem under avsnittet securityHeaders enligt nedan.

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

När du är klar med att justera alla rubriker du behöver, namnge arbetaren och klicka på Spara och distribuera.

Bra! arbetaren är klar, och sedan måste vi lägga till detta på platsen där du vill använda rubrikerna. Jag applicerar detta på min labbplats.

  • Gå till Cloudflares hem/dashboard och välj webbplatsen.
  • Navigera till fliken Arbetare >> Lägg till rutt.
  • Ange URL:en i Route; du kan tillämpa Regex här.
  • Välj de nyskapade arbetarna och Spara

Det är allt; inom en sekund kommer du att märka att alla rubriker är implementerade på webbplatsen.

Så här ser det ut från Chrome Dev Tools. Du kan också testa rubriken genom ett HTTP-huvudverktyg.

Jag vet inte varför serverhuvudet inte återspeglas. Jag antar att Cloudflare åsidosätter detta.

Du förstår, den övergripande implementeringen tar ~15 minuter, och ingen driftstopp eller omstart krävs som Apache eller Nginx. Om du planerar att tillämpa detta på en produktionsplats, skulle jag föreslå att du först testar på en lägre miljö, eller med hjälp av en rutt kan du ansöka på testsidorna för att verifiera resultaten. När du är nöjd, tryck dit du vill.

Det här är häftigt!

Tack vare Scott för koden.