HTTP bezpečnostné hlavičky: Jednoduchý spôsob, ako posilniť vaše webové aplikácie

Moderné prehliadače a servery poskytujú účinné bezpečnostné mechanizmy prostredníctvom HTTP hlavičiek. Nastavíte ich raz a prehliadač bude politiku vynucovať pri každej požiadavke. Zablokujete celé triedy útokov ešte pred spustením aplikačného kódu. Patrí sem clickjacking, cross-site scripting, MIME sniffing, nezabezpečený prenos, úniky údajov medzi odlišnými pôvodmi a slabé spracovanie relácií. Hlavičky dopĺňajú validáciu vstupov, kódovanie výstupov a autentifikáciu. Sú v súlade s rizikami OWASP Top 10 a znižujú odchýlky spôsobené nesprávnou konfiguráciou naprieč stackmi.
Čo pre vás tieto hlavičky robia
- Vynucujú HTTPS a zastavujú downgrade útoky pomocou HSTS.
- Obmedzujú, odkiaľ sa môžu načítať skripty, štýly a iné zdroje, pomocou Content-Security-Policy (CSP).
- Blokujú clickjacking riadením, kde sa môže váš web vkladať do rámcov, pomocou direktívy
frame-ancestors(je súčasťou CSP a nahrádza staršiu hlavičkuX-Frame-Options). - Vypínajú MIME sniffing pomocou X-Content-Type-Options.
- Obmedzujú odosielanie údajov o odkazujúcej stránke pomocou Referrer-Policy.
- Riadiace prístup k výkonným funkciám prehliadača pomocou Permissions-Policy.
- Dosahujú izoláciu medzi pôvodmi pomocou COOP, COEP a CORP, keď to vyžaduje súbor funkcií.
- Riadiace legitímny prístup k API z iných pôvodov pomocou CORS a overenie zámeru cez Fetch Metadata.
- Chránia relácie pomocou súborov cookie Secure, HttpOnly a SameSite.
- Overujú prostriedky CDN pomocou Subresource Integrity.
Ako s nimi pracovať
- Vnímajte hlavičky ako konfiguráciu v kóde. Majte ich vo verziovacom systéme.
- Nasadzujte najprv s report-only a kanárikovými trasami, potom vynucujte.
- Validujte v CI pomocou kontrol cez curl a dôveryhodných skenerov.
- Použite DAST na potvrdenie správania v stagingu a produkcii.
- Revídujte politiky pri pridávaní nových skriptov tretích strán, nových API alebo funkcií.
TLDR
- Začnite s CSP v režime Report-Only. Použite
default-src 'self', nonce pre vložené skripty aframe-ancestors 'self'. Nechajte reportovanie zapnuté. - Zapnite HTTP Strict Transport Security po náprave HTTPS. Použite
max-age=31536000; includeSubDomains.preloadpridajte až vtedy, keď ste pripravení na každý subdomén. - Prestaňte používať HPKP, X-XSS-Protection a Expect-CT. Namiesto toho používajte HSTS a CSP.
- Nastavte
Referrer-Policy: strict-origin-when-cross-origin.no-referrerpoužite pri práci s citlivými údajmi. - Izoláciu medzi pôvodmi zapínajte len v prípade potreby. Použite
COOP: same-originaCOEP: require-corpalebo credentialless. Pridajte CORP na svoje prostriedky. - Vždy posielajte
X-Content-Type-Options: nosniff. - Uzamknite súbory cookie pomocou
Secure; HttpOnly; SameSite=LaxaleboStrict.SameSite=None; Securepoužívajte iba pre súbory cookie tretích strán. - Používajte allowlisty CORS. Nikdy nekombinujte
*s povereniami. Preflight cacheujte s krátkymAccess-Control-Max-Age. - Pridajte kontroly Fetch Metadata na koncové body meniacie stav. Rýchlo odmietajte nebezpečné metódy
cross-site. - Používajte Subresource Integrity pre skripty a štýly z CDN.
Hlavné hlavičky, bezpečné predvolené hodnoty a príklady
Content-Security-Policy (CSP)
Účel: obmedziť, odkiaľ môže vaša stránka načítať skripty, štýly, obrázky, rámce a ďalšie. Zmierňuje XSS a vkladanie údajov.
Bezpečný východiskový bod
Content-Security-Policy: default-src 'self'; base-uri 'self'; object-src 'none';
script-src 'self' 'nonce-{RANDOM}';
style-src 'self';
img-src 'self' data:;
frame-ancestors 'self';
upgrade-insecure-requestsReport-Only počas ladenia
Reporting-Endpoints: csp="https://example.com/csp-reports"
Content-Security-Policy-Report-Only: default-src 'self'; base-uri 'self'; object-src 'none'; script-src 'self' 'nonce-{RANDOM}'; style-src 'self'; img-src 'self' data:; frame-ancestors 'self'; upgrade-insecure-requests; report-to csp; report-uri https://example.com/csp-legacyNastavenie Reporting API
Report-To: {"group":"csp-endpoint","max_age":10886400,"endpoints":[{"url":"https://example.com/csp-reports"}],"include_subdomains":true}Poznámka: Použite report-to (moderné Reporting API) ako primárne. report-uri ponechajte iba kvôli podpore starších prehliadačov počas prechodu.
Tipy
- Uprednostnite nonce pre vložené bootstrap skripty. Generujte náhodný nonce pre každú odpoveď.
- Nahraďte X-Frame-Options direktívou
frame-ancestors. report-urisi ponechajte pre staršie prehliadače.- Použite
report-topre moderné Reporting API. Hodnota csp-endpoint musí zodpovedať názvu skupiny definovanému v samostatnej HTTP hlavičke Report-To.
Kontrolný zoznam nasadenia
- Začnite s
Content-Security-Policy-Report-Onlyna všetkých stránkach. - Generujte nový kryptograficky náhodný nonce pre každú odpoveď. Neopakujte ho medzi požiadavkami.
- Odstráňte vložené obsluhy udalostí a
eval. Nahraďte ich skriptmi, ktoré používajú nonce stránky. - Explicitne uveďte hostiteľov skriptov tretích strán. Vyhnite sa zástupným znakom a
data:pre skripty. - Pridajte
frame-ancestors 'self'aj vtedy, ak si myslíte, že rámce nepoužívate. - Ponechajte
object-src 'none'. Zásuvné moduly by v roku 2025 nemali byť potrebné. - Prepnite na vynucovanie CSP, keď sa porušenia stabilizujú, a ponechajte reportovanie zapnuté.
Stratégia pre skripty tretích strán
- Ak je to možné, uprednostnite serverové alebo tag managerom hostované zrkadlá prvej strany.
- Pre analytiku povoľte iba presné pôvody a potrebné direktívy. Blokujte
connect-srcna neznámych hostiteľov. - Rotujte nonce a nepovoľujte
'unsafe-inline'ani'unsafe-eval'.
CSP porovnanie
| Názov | Účel | Kritické direktívy | Príklad hodnoty | Podpora v prehliadačoch | Riziko nefunkčnosti | Poznámky k nástrojom |
|---|---|---|---|---|---|---|
| Content-Security-Policy | Politika izolácie obsahu na strane klienta, ktorá obmedzuje sťahovanie zdrojov a vykonávacie kontexty na deklarované pôvody, čím zmierňuje odrazené, uložené a DOM-založené XSS, vkladanie aktívneho obsahu a UI útoky pomocou frame-ancestors | default-src, script-src s nonce, frame-ancestors, object-src 'none', upgrade-insecure-requests | Pozri politiku vyššie | Chrome 25+, Edge 12+, Firefox 23+, Safari 7+, Opera 15+, iOS Safari 6+, IE 10–11 čiastočne cez X-Content-Security-Policy | Stredné až vysoké. Vložené skripty bez nonce alebo hashu sú blokované, nedeklarovaní hostitelia tretích strán sa nenačítajú, konštrukcie typu eval prestanú fungovať a staršie tag managery či vložené obsluhy udalostí nebudú pracovať | Použite Reporting API a počas migrácie ponechajte report-uri |
HTTP Strict-Transport-Security (HSTS)
Účel: vynútiť HTTPS. Blokovať HTTP a pokusy o obchádzanie neplatným TLS.
Odporúčaná hodnota
Strict-Transport-Security: max-age=31536000; includeSubDomainsPreload
preloadpridajte iba vtedy, keď každá subdoména používa HTTPS a bude ho používať aj naďalej. Keď ste si istí, môžete svoj doménový názov odoslať do oficiálneho zoznamu preload na hstspreload.org (otvorí sa v novom okne).- Vrátenie späť je pomalé a rizikové.
Upozornenie: HSTS preload je z praktického hľadiska trvalý. Odstránenie zo zoznamov preload v prehliadačoch môže trvať 6–12 mesiacov a vyžaduje koordináciu so všetkými hlavnými prehliadačmi. Odosielajte na hstspreload.org (otvorí sa v novom okne) až po splnení:
- Všetky subdomény majú platné HTTPS (vrátane interných nástrojov)
- Nikde neexistuje HTTP fallback
- Máte zdokumentované obchodné schválenie trvalého vynucovania HTTPS
Kontrolný zoznam pripravenosti na preload
- Každá subdoména poskytuje HTTPS s platnými certifikátmi.
- Trvalé 301 presmerovanie z HTTP na HTTPS je nastavené pre všetkých hostiteľov.
- Žiadne interné ani zdedené systémy nevyžadujú čisté HTTP.
- Nastavte
max-ageaspoň na 31536000 a zapniteincludeSubDomainsna dva týždne pred odoslaním. - Zdokumentujte plán návratu. Odstránenie z preloadu trvá čas a nedá sa urobiť okamžite.
HSTS porovnanie
| Názov | Účel | Kritické direktívy | Príklad hodnoty | Podpora v prehliadačoch | Riziko nefunkčnosti | Poznámky k nástrojom |
|---|---|---|---|---|---|---|
| HSTS | Politika bezpečnosti prenosu, ktorá inštruuje používateľské agenty, aby automaticky upgradovali HTTP na HTTPS a fixovali len HTTPS pre pôvod, čím bránia downgrade protokolu a SSL stripping | max-age, includeSubDomains, voliteľne preload | max-age=31536000; includeSubDomains | Chrome 4+, Edge 12+, Firefox 4+, Safari 7+, Opera 12+, IE 11 na Windows 8.1 alebo Windows 7 s KB3058515 | Vysoké, ak akákoľvek subdoména alebo zdedený endpoint stále poskytuje HTTP alebo prezentuje neplatné TLS, pretože prehliadač tieto navigácie tvrdohlavo zlyhá | Najprv otestujte presmerovania a certifikáty |
Referrer-Policy
Účel: riadiť, koľko informácií o odkazujúcej stránke odosielate.
Predvolené
Referrer-Policy: strict-origin-when-cross-originPre maximálne súkromie použite no-referrer.
Referrer-Policy porovnanie
| Názov | Účel | Kritické direktívy | Príklad hodnoty | Podpora v prehliadačoch | Riziko nefunkčnosti | Poznámky k nástrojom |
|---|---|---|---|---|---|---|
| Referrer-Policy | Kontrola súkromia požiadaviek, ktorá obmedzuje granularitu hlavičky Referer pri navigáciách v rámci rovnakého aj odlišného pôvodu a pri sťahovaní podzdrojov, čím znižuje únik informácií o pôvode a ceste | Jeden token, napríklad no-referrer, strict-origin-when-cross-origin | strict-origin-when-cross-origin | Chrome 61+, Edge 79+, Firefox 52+, Safari 11.1+, Opera 48+, iOS Safari 12+ | Nízke. Niektoré analytiky, A/B smerovanie alebo platobné callbacky spoliehajúce sa na plnú cestu v referreroch môžu mať zníženú viditeľnosť | Skontrolujte analytiky závislé od plných referrerov |
Permissions-Policy
Účel: riadiť prístup k funkciám, ako sú geolokácia, kamera a mikrofón.
Prísne predvolené nastavenie
Permissions-Policy: geolocation=(), camera=(), microphone=()Kroky auditu
- Prehľadajte svoj kód na API funkcionalít.
- Použite DevTools na zobrazenie výziev a blokovaných funkcií.
- Otvorené politiky aplikujte na trasy, ktoré ich potrebujú.
Bežne obmedzované funkcie
geolocation=(),camera=(),microphone=()pre stránky, ktoré ich nikdy nepoužívajú.payment=()ausb=()pre verejné marketingové stránky.fullscreen=(self)pre aplikácie používajúce prehliadače médií.
Permissions-Policy porovnanie
| Názov | Účel | Kritické direktívy | Príklad hodnoty | Podpora v prehliadačoch | Riziko nefunkčnosti | Poznámky k nástrojom |
|---|---|---|---|---|---|---|
| Permissions-Policy | Politika obmedzovania funkcií, ktorá povoľuje alebo zamieta výkonné schopnosti prehliadača podľa pôvodu a kontextu vkladania, a presadzuje princíp najmenších práv pre API ako geolokácia, kamera a mikrofón | Zoznamy povolených podľa funkcií | geolocation=(), camera=(), microphone=() | Chrome 88+, Edge 88+, Opera 74+, Firefox nepodporované, Safari nepodporované | Nízke až stredné. Stránky alebo iframy, ktoré sa implicitne spoliehali na výzvy, uvidia zamietnutie schopností, kým nebudú explicitne povolené | Nastavujte podľa potreby na úrovni trasy |
X-Content-Type-Options
Účel: zastaviť MIME sniffing. Zabraňuje tomu, aby prehliadač hádal typ obsahu, čo môže byť nebezpečné (napr. ak súbor vyzerá ako skript, môže vykonať textový súbor nahraný používateľom).
Hodnota
X-Content-Type-Options: nosniffX-Content-Type-Options porovnanie
| Názov | Účel | Kritické direktívy | Príklad hodnoty | Podpora v prehliadačoch | Riziko nefunkčnosti | Poznámky k nástrojom |
|---|---|---|---|---|---|---|
| X-Content-Type-Options | Direktíva presadzovania MIME, ktorá vypína sniffing obsahu pre odpovede skriptov a štýlov, a vyžaduje správny Content-Type na vykonanie | nosniff | nosniff | Chrome 64+, Edge 12+, Firefox 50+, Safari 11+, Opera 51+, IE 8+ | Nízke, ak sú všetky prostriedky poskytované so správnymi MIME typmi. Nesprávne typované zdroje budú zablokované | Poskytujte správny Content-Type |
COOP, COEP, CORP
Účel: izolovať vašu aplikáciu od iných pôvodov a blokovať úniky medzi stránkami. Vyžadované pre niektoré pokročilé funkcie, ako je SharedArrayBuffer.
Odporúčaný set, keď potrebujete izoláciu
Clear-Site-Data: "cache", "cookies", "storage" # Use on logout endpoints
Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp
Cross-Origin-Resource-Policy: same-originPoznámky
COEP: credentiallessmôže zjednodušiť načítanie zdrojov tretích strán bez poverení. Najprv overte podporu.- Pred nasadením auditujte vloženia a použitie postMessage.
Kedy použiť izoláciu medzi pôvodmi
- Potrebujete SharedArrayBuffer alebo výkonnostné API, ktoré vyžadujú izoláciu.
- Chcete silnejšiu ochranu proti únikom medzi stránkami a komunikácii v popup oknách.
Riešenie problémov
- Zlyhanie načítania obrázkov, písiem alebo WASM zvyčajne znamená chýbajúce CORP. Pridajte
Cross-Origin-Resource-Policy: same-originna svoje prostriedky alebo ich servujte z rovnakého pôvodu. - Widgety tretích strán sa nemusia dať vkladať pri COEP. Hostujte ich ako prvá strana alebo použite
credentialless, ak je podporované.
COOP, COEP, CORP porovnanie
| Názov | Účel | Kritické direktívy | Príklad hodnoty | Podpora v prehliadačoch | Riziko nefunkčnosti | Poznámky k nástrojom |
|---|---|---|---|---|---|---|
| COOP | Izolácia skupiny prehliadacích kontextov, ktorá umiestni stránku do samostatnej skupiny od dokumentov iného pôvodu, čím zmierňuje úniky údajov medzi oknami a niektoré XS-Leaks | same-origin | same-origin | Chrome 83+, Edge 83+, Firefox 79+, Safari 15.2+, Opera 69+ | Stredné. Referencie na okná iného pôvodu, vzťahy opener a toky postMessage predpokladajúce rovnakú skupinu môžu prestať fungovať | Auditujte postMessage a window.open |
| COEP | Politika vkladania, ktorá vyžaduje, aby zdroje iného pôvodu explicitne povolili vloženie cez CORP alebo CORS, čím umožňuje izoláciu medzi pôvodmi a blokuje nepriehľadné no-cors vloženia | require-corp alebo credentialless | require-corp | Chrome 83+, Edge 83+, Opera 69+, Firefox nepodporované, Safari nepodporované | Stredné až vysoké. Zdroje tretích strán bez hlavičiek CORP alebo CORS sa nenačítajú, vrátane písiem, obrázkov a WASM | Pridajte CORP na svoje prostriedky |
| CORP | Politika ochrany zdrojov, ktorá deklaruje, ktoré pôvody môžu zdroj vkladať v no-cors kontextoch, čím bráni neautorizovanému využitiu z iného pôvodu | same-origin, same-site, cross-origin | same-origin | Chrome 73+, Edge 79+, Firefox 74+, Safari nepodporované, iOS Safari nepodporované | Nízke až stredné. Odberatelia z iného webu bez povoleného vzťahu nenačítajú chránené zdroje | Nastavujte na statické zdroje |
Cross-Origin Resource Sharing (CORS)
Účel: povoliť špecifické požiadavky medzi odlišnými pôvodmi.
Bezpečný príklad
# Preflight (OPTIONS)
Access-Control-Allow-Origin: https://example.com
Access-Control-Allow-Methods: GET, POST, OPTIONS
Access-Control-Allow-Headers: Content-Type
Access-Control-Allow-Credentials: true
Access-Control-Max-Age: 600
Vary: Origin, Access-Control-Request-Method, Access-Control-Request-Headers
# Simple/actual response
Access-Control-Allow-Origin: https://example.com
Access-Control-Allow-Credentials: true
Vary: Origin
Access-Control-Expose-Headers: Content-Length, X-Request-ID
Cross-Origin-Resource-Policy: same-originPreflight
- Prehliadače posielajú OPTIONS na kontrolu politiky.
- Cacheujte s krátkym Access-Control-Max-Age.
Pravidlá pre požiadavky s povereniami
- Nepoužívajte
*s povereniami. Odozvite povolený pôvod zo zoznamu povolených. - Vždy nastavte
Vary: Origin, keď sa odpovede líšia podľa pôvodu. - Povoľte iba nevyhnutné metódy a hlavičky. Vyhnite sa širokému
Access-Control-Allow-Headers: *.
Úskalia cacheovania preflight
- V produkcii držte
Access-Control-Max-Agestriedmo, napríklad 600 sekúnd, aby sa zmeny politík prejavili rýchlo. - CDN môžu cachovať OPTIONS. Obíďte alebo ohraničte cache pre preflight cesty.
CORS porovnanie
| Názov | Účel | Kritické direktívy | Príklad hodnoty | Podpora v prehliadačoch | Riziko nefunkčnosti | Poznámky k nástrojom |
|---|---|---|---|---|---|---|
| CORS hlavičky | Rámec autorizácie požiadaviek medzi pôvodmi, ktorý určuje, ktoré pôvody, metódy a hlavičky môžu pristupovať k chráneným zdrojom cez fetch/XHR, vrátane preflight vyjednávania | Access-Control-Allow-Origin, Access-Control-Allow-Methods, Access-Control-Allow-Headers, Access-Control-Allow-Credentials, Access-Control-Max-Age | Pozri príklad | Chrome 4+, Edge 12+, Firefox 3.5+, Safari 4+, Opera 12.1+, IE 10+ | Stredné. Nesprávne zoznamy povolených, chýbajúce Vary alebo zle ohraničené povolené hlavičky blokujú legitímnych klientov alebo umožnia nesúlad cacheovaných politík | Vždy nastavte Vary: Origin |
Fetch Metadata
Účel: identifikovať kontext požiadavky a blokovať zneužitie naprieč stránkami. Použite na posilnenie obrany proti CSRF.
Náčrt kontroly na serveri
# Pseudocode: reject unsafe, non-navigational cross-site requests
site = get_header("Sec-Fetch-Site")
mode = get_header("Sec-Fetch-Mode")
is_unsafe_method = (method in [POST, PUT, PATCH, DELETE])
is_cross_site = (site == "cross-site")
is_navigational = (mode == "navigate")
# Block requests that are cross-site, unsafe, AND not a top-level navigation
if (is_cross_site && is_unsafe_method && !is_navigational) {
reject()
}Príklad middleware pre Express
function fetchMetadataGuard(req, res, next) {
const site = req.get("Sec-Fetch-Site") || "";
const mode = req.get("Sec-Fetch-Mode") || "";
const dest = req.get("Sec-Fetch-Dest") || "";
const unsafe = ["POST", "PUT", "PATCH", "DELETE"].includes(req.method);
const allowedSameSite = site === "" || site === "same-origin" || site === "same-site";
const isNavigation = mode === "navigate" && dest === "document";
if (unsafe && !allowedSameSite && !isNavigation) return res.sendStatus(403);
next();
}Fetch Metadata porovnanie
| Názov | Účel | Kritické direktívy | Príklad hodnoty | Podpora v prehliadačoch | Riziko nefunkčnosti | Poznámky k nástrojom |
|---|---|---|---|---|---|---|
| Fetch Metadata | Validácia kontextu požiadavky, ktorá skúma hlavičky Sec-Fetch-* na rozlíšenie požiadaviek rovnakého pôvodu, rovnakého webu a iného webu, čo umožňuje serverové spevnenie proti CSRF a XS-Leaks | Sec-Fetch-Site, Sec-Fetch-Mode, Sec-Fetch-Dest, Sec-Fetch-User | Odmietnuť nebezpečné metódy pri cross-site | Chrome 76+, Edge 79+, Opera 63+, Firefox nepodporované, Safari nepodporované | Nízke pri zameraní na nebezpečné metódy. Príliš prísne pravidlá môžu blokovať legitímne navigácie medzi webmi alebo OAuth presmerovania | Logujte odmietnutia na doladenie |
Subresource Integrity (SRI)
Účel: zabezpečiť, aby CDN zdroje neboli pozmenené.
Príklad
<script src="https://cdn.example.com/app.js" integrity="sha384-BASE64HASH" crossorigin="anonymous"></script>Poznámky
- Pripnite verzie alebo automaticky aktualizujte hash hodnoty.
- Používajte pre skripty a štýly.
Generovanie a overovanie hashov
- Generovanie:
openssl dgst -sha384 -binary app.js | openssl base64 -A - Overenie: SRI vždy otestujte v stagingu pred produkciou. Neplatné hashe = nefunkčný web.
- Automatizácia: použite build nástroje na generovanie hashov počas nasadzovania
SRI porovnanie
| Názov | Účel | Kritické direktívy | Príklad hodnoty | Podpora v prehliadačoch | Riziko nefunkčnosti | Poznámky k nástrojom |
|---|---|---|---|---|---|---|
| SRI | Overenie integrity podzdrojov, ktoré viaže externé skripty a štýly na kryptografické odtlačky, čím bráni spusteniu pozmenených CDN aktív | integrity, crossorigin | Pozri príklad | Chrome 45+, Edge 79+, Firefox 43+, Safari 11+, Opera 32+, iOS Safari 11.3+ | Stredné. Akákoľvek zmena upstream aktíva bez zodpovedajúcej aktualizácie hash spôsobí tvrdé zlyhanie | Automatizujte aktualizácie hashov |
Bezpečné súbory cookie
Účel: chrániť relácie.
Bezpečný príklad
Set-Cookie: session=abc...; Path=/; Secure; HttpOnly; SameSite=LaxPoznámky
- Moderné prehliadače pri chýbajúcom SameSite používajú predvolene Lax. Buďte explicitní.
SameSite=None; Securepoužívajte iba pre cookie tretích strán.
Tipy k rozsahu cookie
- Nastavte
Path=/len keď je to potrebné. Užšie cesty znižujú vystavenie. - Rozsah
Domainobmedzte na čo najmenej hostiteľov. Vyhnite sa cookie na superdoméne vo veľkých prostrediach. - Rotujte ID relácie pri prihlásení a zmene oprávnení. Pri odhlásení invalidujte.
- Používajte krátke expirácie pre reláčne cookie. Preferujte serverové úložiská relácií s možnosťou odvolania.
Porovnanie cookie
| Názov | Účel | Kritické direktívy | Príklad hodnoty | Podpora v prehliadačoch | Riziko nefunkčnosti | Poznámky k nástrojom |
|---|---|---|---|---|---|---|
| Set-Cookie | Ochrana dôvernosti relácie a viacvrstvová obrana proti CSRF cez Secure prenos, neprístupnosť zo skriptu s HttpOnly a cross-site sémantiku so SameSite | Secure, HttpOnly, SameSite | Secure; HttpOnly; SameSite=Lax | HttpOnly a Secure podporované všetkými modernými prehliadačmi. SameSite=None vyžaduje Chrome 67+, Edge 16+, Firefox 60+, Safari 13+, iOS Safari 13+ | Nízke až stredné. Cross-site toky, vložené SSO alebo staršie integrácie tretích strán môžu zlyhať bez SameSite=None; Secure tam, kde je potrebné | Pred sprísnením auditujte cross-site toky |
Zastaralé alebo neodporúčané hlavičky
| Hlavička | Odstránené/Zastarané a odkedy | Dôvod | Náhrada |
|---|---|---|---|
| HTTP Public-Key-Pins (HPKP) | Odstránené, 2018-05-29, riziko denial-of-service a nepriateľského pripinovania | Vysoké riziko samospôsobenej uzávery | Nahraďte Public-Key-Pins pomocou HSTS preload a Certificate Transparency |
| X-XSS-Protection | Zastarané, 2019-10, prehliadače ho zrušili, môže vytvárať XSS zraniteľnosti a koliduje s CSP | Neúčinné a zavádzajúce | Nahraďte X-XSS-Protection politikou Content-Security-Policy bez vložených skriptov |
| Expect-CT | Zastarané, 2022-11, CT vymáhané Chromiom, hlavička je zastaraná | CT je dnes súčasťou ekosystému | Namiesto Expect-CT sa spoliehajte na Certificate Transparency a hlavičku odstráňte |
| X-Frame-Options | Nahradené moderným mechanizmom, referencia z 2016-12-15 pre adopciu CSP frame-ancestors, obmedzené direktívy a interoperabilita | Obmedzená syntax a ovládanie | Nahraďte X-Frame-Options hlavičkou Content-Security-Policy: frame-ancestors |
Konfiguračné postupy
Nginx
# /etc/nginx/conf.d/security.conf
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Permissions-Policy "geolocation=(), camera=(), microphone=()" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Cross-Origin-Opener-Policy "same-origin" always;
add_header Cross-Origin-Embedder-Policy "require-corp" always;
add_header Cross-Origin-Resource-Policy "same-origin" always;
location / {
set_by_lua_block $csp_nonce {
local rand = require("resty.random").bytes(16, true)
return ngx.encode_base64(rand)
}
add_header Content-Security-Policy
"default-src 'self'; base-uri 'self'; object-src 'none'; \
script-src 'self' 'nonce-$csp_nonce'; style-src 'self'; img-src 'self' data:; \
frame-ancestors 'self'; upgrade-insecure-requests" always;
}
# CORS example for API
location /api/ {
if ($request_method = 'OPTIONS') {
add_header Access-Control-Allow-Origin "https://example.com";
add_header Access-Control-Allow-Methods "GET, POST, OPTIONS";
add_header Access-Control-Allow-Headers "Content-Type";
add_header Access-Control-Allow-Credentials "true";
add_header Access-Control-Max-Age 600;
return 204;
}
add_header Access-Control-Allow-Origin "https://example.com";
add_header Access-Control-Allow-Credentials "true";
add_header Vary "Origin";
proxy_pass http://backend;
}Apache httpd
# In <VirtualHost> or .htaccess with AllowOverride All
# e.g., SetEnvIfNoCase Request_URI ".*" CSP_NONCE=%{UNIQUE_ID}e
Header always set Content-Security-Policy "default-src 'self'; base-uri 'self'; object-src 'none'; script-src 'self' 'nonce-%{CSP_NONCE}e'; style-src 'self'; img-src 'self' data:; frame-ancestors 'self'; upgrade-insecure-requests"
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
Header always set Referrer-Policy "strict-origin-when-cross-origin"
Header always set Permissions-Policy "geolocation=(), camera=(), microphone=()"
Header always set X-Content-Type-Options "nosniff"
Header always set Cross-Origin-Opener-Policy "same-origin"
Header always set Cross-Origin-Embedder-Policy "require-corp"
Header always set Cross-Origin-Resource-Policy "same-origin"
# CORS example
<Location /api/>
Header always set Access-Control-Allow-Origin "https://example.com"
Header always set Access-Control-Allow-Credentials "true"
Header always set Vary "Origin"
RewriteEngine On
RewriteCond %{REQUEST_METHOD} OPTIONS
RewriteRule ^ - [R=204,L]
Header always set Access-Control-Allow-Methods "GET, POST, OPTIONS"
Header always set Access-Control-Allow-Headers "Content-Type"
Header always set Access-Control-Max-Age "600"
</Location>Node.js Express
import express from "express";
import crypto from "crypto";
const app = express();
// CSP nonce per response
app.use((req, res, next) => {
res.locals.cspNonce = crypto.randomBytes(16).toString("base64");
next();
});
app.use((req, res, next) => {
const nonce = res.locals.cspNonce;
res.setHeader("Content-Security-Policy",
"default-src 'self'; base-uri 'self'; object-src 'none'; " +
"script-src 'self' 'nonce-" + nonce + "'; style-src 'self'; img-src 'self' data:; " +
"frame-ancestors 'self'; upgrade-insecure-requests");
res.setHeader("Strict-Transport-Security", "max-age=31536000; includeSubDomains");
res.setHeader("Referrer-Policy", "strict-origin-when-cross-origin");
res.setHeader("Permissions-Policy", "geolocation=(), camera=(), microphone=()");
res.setHeader("X-Content-Type-Options", "nosniff");
res.setHeader("Cross-Origin-Opener-Policy", "same-origin");
res.setHeader("Cross-Origin-Embedder-Policy", "require-corp");
res.setHeader("Cross-Origin-Resource-Policy", "same-origin");
next();
});
// Fetch Metadata guard
app.use((req, res, next) => {
const site = req.get("Sec-Fetch-Site");
const unsafe = ["POST","PUT","PATCH","DELETE"].includes(req.method);
if (site === "cross-site" && unsafe) return res.status(403).end();
next();
});
// CORS allowlist example
app.use("/api", (req, res, next) => {
const origin = req.get("Origin");
if (origin === "https://example.com") {
res.setHeader("Access-Control-Allow-Origin", origin);
res.setHeader("Access-Control-Allow-Credentials", "true");
res.setHeader("Vary", "Origin");
}
if (req.method === "OPTIONS") {
res.setHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
res.setHeader("Access-Control-Allow-Headers", "Content-Type");
res.setHeader("Access-Control-Max-Age", "600");
return res.status(204).end();
}
next();
});
app.get("/", (req, res) => {
res.send(`<script nonce="${res.locals.cspNonce}">console.log("ok")</script>`);
});
app.listen(3000);Cloudflare Workers
export default {
async fetch(req, env, ctx) {
const headers = new Headers({
"Content-Security-Policy":
"default-src 'self'; base-uri 'self'; object-src 'none'; " +
"script-src 'self'; style-src 'self'; img-src 'self' data:; " +
"frame-ancestors 'self'; upgrade-insecure-requests",
"Strict-Transport-Security": "max-age=31536000; includeSubDomains",
"Referrer-Policy": "strict-origin-when-cross-origin",
"Permissions-Policy": "geolocation=(), camera=(), microphone=()",
"X-Content-Type-Options": "nosniff",
"Cross-Origin-Opener-Policy": "same-origin",
"Cross-Origin-Embedder-Policy": "require-corp",
"Cross-Origin-Resource-Policy": "same-origin"
});
if (req.method === "OPTIONS") {
headers.set("Access-Control-Allow-Origin", "https://example.com");
headers.set("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
headers.set("Access-Control-Allow-Headers", "Content-Type");
headers.set("Access-Control-Allow-Credentials", "true");
headers.set("Access-Control-Max-Age", "600");
return new Response(null, { status: 204, headers });
}
headers.set("Access-Control-Allow-Origin", "https://example.com");
headers.set("Access-Control-Allow-Credentials", "true");
headers.append("Vary", "Origin");
return new Response("OK", { headers });
}
};Poznámka k nonce v Edge Workers
Tento príklad pre jednoduchosť poskytuje statickú CSP. Zavedenie nonce (podľa odporúčania) v edge workerovi, ako je Cloudflare, je zložitejšie. Vyžaduje, aby ste:
- vygenerovali náhodný nonce, napríklad pomocou
crypto.randomUUID(), - načítali odpoveď z originu,
- použili HTML prepisovač, napríklad
HTMLRewriterv Cloudflare, na streamovanie odpovede, vložili atribútnoncedo vašich značiek<script>a<style>, a potom - pridali hlavičku
Content-Security-Policydo finálnej odpovede, vrátane vygenerovanej hodnoty'nonce-...'.
Overenie
# Show all response headers
curl -s -D - https://example.com/ -o /dev/null
# Check a single header
curl -s -D - https://example.com/ -o /dev/null | grep -i strict-transport-security
# Check CORS preflight
curl -s -D - -X OPTIONS https://api.example.com/endpoint \
-H "Origin: https://example.com" \
-H "Access-Control-Request-Method: POST" -o /dev/nullSkript na validáciu bezpečnostných hlavičiek
#!/bin/bash
# Comprehensive security header check
URL="https://example.com"
echo "Testing security headers for $URL"
CRITICAL_HEADERS=(
"Content-Security-Policy"
"Strict-Transport-Security"
"X-Content-Type-Options"
"Referrer-Policy"
"Permissions-Policy"
)
# Fail if any required header is missing
for h in "${CRITICAL_HEADERS[@]}"; do
curl -s -D - https://example.com/ -o /dev/null | grep -iq "^$h:" || { echo "Missing $h"; exit 1; }
done
# Ensure CSP contains frame-ancestors
CSP_VALUE=$(curl -s -D - https://example.com/ -o /dev/null | awk 'BEGIN{IGNORECASE=1}/^Content-Security-Policy:/{print substr($0,index($0,$2))}')
echo "$CSP_VALUE" | grep -iq "frame-ancestors" || { echo "CSP missing frame-ancestors"; exit 1; }
# Test HSTS preload readiness
echo "HSTS Preload Check:"
curl -s "https://hstspreload.org/api/v2/status?domain=$(echo $URL | sed 's|https://||')" | jq .Očakávané výsledky
- Požiadavka na dokument zobrazuje CSP, HSTS, Referrer-Policy, COOP, COEP, CORP a
X-Content-Type-Options. - Preflight zobrazuje CORS hlavičky, ktoré ste nastavili.
grepnájde presnú hlavičku a hodnotu.
Nástroje vývojára v prehliadači
- Otvorte kartu Network, načítajte stránku, vyberte požiadavku na dokument a skontrolujte odpoveďové hlavičky.
- Majte otvorenú konzolu, aby ste zachytili porušenia CSP v režime Report-Only.
- Skontrolujte panel Application pre súbory cookie a ich príznaky.
Rýchle kroky
- Chrome: karta Network, potom vyberte dokument a Response Headers. Filtrovať pomocou
csp,strict-transport,referrer-policy. - Otvorte konzolu a obnovte načítanie, aby ste videli porušenia
Content Security Policyv režime Report-Only. - Firefox: panel Storage, potom Cookies. Skontrolujte príznaky
Secure,HttpOnlyaSameSite.
Nasadzovanie a monitorovanie
- Inventarizácia a východiskový stav (týždeň 1)
- Zmapujte všetky domény a subdomény
- Zadokumentujte aktuálny stav hlavičiek
- Identifikujte všetky závislosti tretích strán
- CSP Report-Only (týždne 2–3)
- Nasaďte CSP v režime report-only
- Monitorujte porušenia 14 a viac dní
- Opravte legitímne porušenia v kóde
- Základné hlavičky (týždeň 4)
- Nasadiť `X-Content-Type-Options: nosniff`
- Nasadiť `Referrer-Policy: strict-origin-when-cross-origin`
- Nasadiť `Permissions-Policy` s bezpečnými predvolenými hodnotami
- HSTS postupne (týždne 5–8)
- Začnite s `max-age=300` na nekritickej subdoméne
- Postupne zvýšte na `max-age=31536000`
- `includeSubDomains` pridajte až po overení všetkých subdomén
- CSP vynucovanie (týždeň 9+)
- Prepnite CSP do režimu vynucovania
- Ponechajte zapnuté reportovanie
- Monitorujte nové porušenia
- Pokročilá izolácia (voliteľné)
- Nasaďte COOP/COEP/CORP iba ak je to potrebné
- Otestujte požiadavky na izoláciu medzi pôvodmi
Bežné chyby
- Použitie
Access-Control-Allow-Origin: *s povereniami. Je to neplatné a nebezpečné. Použite zoznam povolených aVary: Origin. - Posielanie iba X-Frame-Options. Použite
frame-ancestorsv CSP. - Zabudnutie na
X-Content-Type-Options: nosniff. - Nenastavené príznaky cookie. Použite
Secure; HttpOnly; SameSite. - Preload HSTS skôr, než ste pripravení.
- Rozbitie widgetov tretích strán pomocou COEP alebo CORP. Urobte audit a pridajte explicitné povolenia.
- Vnímanie CSP ako jedinej záchrany. Stále potrebujete kódovanie výstupov a validáciu vstupov.
Ďalšie úskalia a rýchle opravy
- CSP povoľuje
'unsafe-inline'. Opravte použitím nonce alebo hashov a odstránením vložených obslúh. - Chýbajúce
frame-ancestorsv CSP. Pridajte ho aj vtedy, ak posielate X-Frame-Options. - COEP
require-corpnasadené bez CORP na statických zdrojoch. PridajteCross-Origin-Resource-Policyna obrázky, písma a WASM. - CORS
Access-Control-Allow-Headersnastavené na*. Nahraďte presnými používanými hlavičkami. - Cookies s
SameSite=None, ale chýbaSecure. Vždy párujteNonesoSecure.
Otázky
Uprednostnite frame-ancestors. Niektoré tímy nechávajú obe kvôli kompatibilite, ale CSP je moderný mechanizmus.
Povoľte iba potrebné pôvody. Pre svoje vložené bootstrappy použite nonce. Vyhnite sa zástupným znakom.
Nie. Použite ho iba vtedy, keď každá subdoména používa HTTPS a pri ňom aj zostane.
strict-origin-when-cross-origin vyhovuje väčšine webov. Pre prísnejšie súkromie použite no-referrer.
Použite oboje. Tokeny zostávajú primárne. Fetch Metadata poskytuje rýchlu cestu na odmietnutie.
Rozširuje prístup k dátam. Nikdy nekombinujte s povereniami. Použite zoznamy povolených pôvodov.
Len ak potrebujete izoláciu medzi pôvodmi alebo silnejšiu ochranu proti únikom naprieč stránkami. Najprv otestujte vkladania.
Nie. Je zastaraný.
Väčšina prehliadačov považuje cookie bez SameSite za Lax. Atribúty nastavte explicitne.
Použite curl s OPTIONS, odošlite Origin a Access-Control-Request-Method.
Áno. Pripnite verzie a používajte SRI. Pokrýva manipuláciu na CDN.
Áno. Edge je vhodné miesto. Pre trasy s inými politikami ponechajte prepisy na úrovni aplikácie.
Záver
HTTP hlavičky prinášajú rýchle, merateľné prínosy s nízkym rizikom. Najprv nasadzujte bezpečné predvolené hodnoty, potom pridávajte prísnejšie kontroly podľa správania aplikácie. Politiky držte v kóde, testujte ich v CI a pravidelne ich revidujte.
Referencie
- MDN referenčná príručka HTTP hlavičiek (otvorí sa v novom okne)
- MDN sprievodca k CSP (otvorí sa v novom okne)
- W3C Content Security Policy Level 3 (otvorí sa v novom okne)
- MDN HSTS (otvorí sa v novom okne)
- OWASP HSTS Cheat Sheet (otvorí sa v novom okne)
- MDN Referrer-Policy (otvorí sa v novom okne)
- MDN Permissions-Policy (otvorí sa v novom okne)
- MDN X-Content-Type-Options (otvorí sa v novom okne)
- MDN COOP (otvorí sa v novom okne)
- MDN COEP (otvorí sa v novom okne)
- MDN CORP (otvorí sa v novom okne)
- MDN sprievodca CORS (otvorí sa v novom okne)
- WICG Fetch Metadata (otvorí sa v novom okne)
- MDN prehľad CSRF (otvorí sa v novom okne)
- MDN SRI (otvorí sa v novom okne)
- W3C SRI (otvorí sa v novom okne)
- OWASP Secure Headers Project (otvorí sa v novom okne)
- OWASP HTTP Headers Cheat Sheet (otvorí sa v novom okne)
- Mozilla HTTP Observatory (otvorí sa v novom okne)
- SecurityHeaders.com (otvorí sa v novom okne)
- OWASP ZAP (otvorí sa v novom okne)
Spoločne posuňme váš úspech na vyššiu úroveň!
Vyžiadajte si bezplatnú cenovú ponukuSúvisiace články

Podrobný návod na vytvorenie vášho prvého Python balíka
Vytvorenie Python modulu si vyžaduje viac než len písanie kódu. Moderný vývoj si žiada vhodné nástroje, štandardizované pracovné postupy a automatizáciu. Prečítajte si viaco Podrobný návod na vytvorenie vášho prvého Python balíka

Zvládnutie formátovania reťazcov v jazyku JavaScript pomocou sprintf()
Formátovanie reťazcov je základným aspektom programovania, ktorý vývojárom umožňuje vytvárať dynamický a čitateľný textový výstup vkladaním premenných a aplikovaním špecifických pravidiel formátovania. Prečítajte si viaco Zvládnutie formátovania reťazcov v jazyku JavaScript pomocou sprintf()

Ako implementovať režim súhlasu Google v2?
Súkromné predpisy, ako je Všeobecné nariadenie o ochrane údajov (GDPR) a Kalifornský zákon o ochrane súkromia spotrebiteľov (CCPA), zásadne zmenili spôsob, akým podniky pristupujú k údajom používateľov. Prečítajte si viaco Ako implementovať režim súhlasu Google v2?
