Како имплементирати безбедна заглавља користећи Цлоудфларе Воркерс?

Sigurnosni HTTP Headeri putem Cloudflare Workers

Ovaj vodič korak po korak objašnjava kako implementirati sigurne HTTP headere na web stranicama koje koriste Cloudflare, koristeći Cloudflare Workers.

Postoji mnogo načina za implementaciju HTTP response headera radi zaštite web lokacija od uobičajenih ranjivosti, kao što su XSS (Cross-site scripting), Clickjacking, MIME sniffing, ubrizgavanje na više lokacija i druge. To je široko prihvaćena praksa koju preporučuje OWASP.

Ranije sam pisao o implementaciji headera na web serverima kao što su Apache, Nginx i IIS. Međutim, ako koristite Cloudflare za zaštitu i ubrzanje svojih web stranica, možete iskoristiti Cloudflare Workers za manipulaciju HTTP response headerima.

Cloudflare Workers je serverless platforma na kojoj možete pokretati JavaScript, C, C++ i Rust kod. Raspoređena je u svim Cloudflare data centrima, kojih ima više od 200 širom sveta.

Implementacija je vrlo jednostavna i fleksibilna. Pruža vam mogućnost primene headera na celoj web lokaciji, uključujući poddomene ili određene URI-je, koristeći odgovarajuće regularne izraze, kao što je objašnjeno u dokumentaciji.

Za ovu demonstraciju koristićemo kod Scott Helmea.

Započnimo… 👨‍💻

  • Prijavite se na Cloudflare i kliknite na Workers ( direktna veza).

  • Kopirajte worker.js kod sa GitHub-a i zalepite ga u editor skripti.
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)));

Ne čuvajte još; možda ćete želeti da prilagodite sledeće headere kako bi odgovarali vašim potrebama.

Content-Security-Policy – ako trebate da implementirate sopstvenu politiku, možete to uraditi ovde.

Na primer – ako trebate da dopustite prikaz sadržaja u iFrame-u sa više URL-ova, možete iskoristiti frame-ancestors opciju, kao u nastavku:

"Content-Security-Policy" : "frame-ancestors 'self' gf.dev techblog.co.rs.com",

Gore navedeno će omogućiti učitavanje sadržaja sa gf.dev, techblog.co.rs.com i sa samog sajta ('self').

X-Frame-Options – možete promeniti na SAMEORIGIN ako nameravate da prikažete sadržaj svoje web lokacije na nekoj stranici unutar iste web lokacije koristeći iFrame.

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

Server – ovde možete maskirati header servera. Stavite šta god želite.

"Server" : "techblog.co.rs Server",

removeHeaders – da li treba da uklonite neke headere da biste sakrili informacije o verzijama i smanjili rizik curenja informacija?

Možete to učiniti ovde.

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

Dodavanje novih headera – ako trebate da prosledite neke prilagođene headere svojim aplikacijama, možete ih dodati u sekciju securityHeaders, kao u nastavku.

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

Kada završite sa prilagođavanjem svih potrebnih headera, dajte ime workeru i kliknite na „Save and Deploy“.

Odlično! Worker je spreman. Sada ga moramo dodati na sajt gde želite da primenite headere. Ja ću ovo primeniti na svoju laboratoriju.

  • Idite na Cloudflare početnu kontrolnu tablu i izaberite sajt.
  • Idite na karticu „Workers“ >> „Add route“.
  • Unesite URL u polje „Route“; možete primeniti i regularne izraze.
  • Izaberite novo kreiranog worker-a i sačuvajte.

To je sve; u roku od nekoliko sekundi primetićete da su svi headeri implementirani na web stranici.

Evo kako to izgleda iz Chrome Dev Tools. Takođe možete testirati headere koristeći alate za testiranje HTTP headera.

Ne znam zašto se header servera ne prikazuje. Pretpostavljam da ga Cloudflare premošćuje.

Kao što vidite, cela implementacija traje ~15 minuta i ne zahteva vreme zastoja ili ponovno pokretanje kao kod Apache ili Nginx. Ako planirate da primenite ovo na produkcijskoj lokaciji, predlažem da prvo testirate na razvojnom okruženju, ili uz pomoć rute, možete primeniti na stranicama za testiranje da proverite rezultate. Kada budete zadovoljni, primenite svuda.

Ovo je super!

Hvala Scottu za kod.