Komplexný sprievodca na posilnenie zabezpečenia frontendu pomocou Content Security Policy (CSP) a Cross-Origin Resource Sharing (CORS), ktorý chráni vaše webové aplikácie pred modernými hrozbami.
Posilnenie zabezpečenia frontendu: Content Security Policy a CORS
V dnešnom prepojenom digitálnom prostredí je zabezpečenie frontendu prvoradé. Webové aplikácie sú čoraz častejšie cieľom sofistikovaných útokov, vďaka čomu sú robustné bezpečnostné opatrenia nevyhnutné. Dve kritické zložky bezpečnej architektúry frontendu sú Content Security Policy (CSP) a Cross-Origin Resource Sharing (CORS). Tento komplexný sprievodca poskytuje podrobný pohľad na tieto technológie, ponúka praktické príklady a užitočné informácie, ktoré vám pomôžu posilniť vaše webové aplikácie proti moderným hrozbám.
Čo je Content Security Policy (CSP)?
Content Security Policy (CSP) je pridaná vrstva zabezpečenia, ktorá pomáha detekovať a zmierňovať určité typy útokov, vrátane Cross-Site Scripting (XSS) a útokov vkladania dát. CSP je implementovaná webovým serverom odosielaním hlavičky HTTP odpovede Content-Security-Policy do prehliadača. Táto hlavička definuje whitelist zdrojov, z ktorých môže prehliadač načítať zdroje. Obmedzením zdrojov obsahu, ktoré môže prehliadač načítať, CSP výrazne sťažuje útočníkom vloženie škodlivého kódu do vašej webovej stránky.
Ako CSP funguje
CSP funguje tak, že prehliadaču dáva pokyn, aby načítal iba zdroje (napr. skripty, štýly, obrázky, fonty) zo schválených zdrojov. Tieto zdroje sú špecifikované v hlavičke CSP pomocou direktív. Ak sa prehliadač pokúsi načítať zdroj zo zdroja, ktorý nie je explicitne povolený, zablokuje požiadavku a nahlási porušenie.
CSP Direktívy: Komplexný prehľad
CSP direktívy riadia typy zdrojov, ktoré je možné načítať z konkrétnych zdrojov. Tu je rozpis niektorých z najdôležitejších direktív:
- default-src: Špecifikuje predvolený zdroj pre všetky typy obsahu. Toto je záložná direktíva, ktorá sa používa, keď iné, špecifickejšie direktívy nie sú prítomné.
- script-src: Špecifikuje zdroje, z ktorých je možné načítať skripty. Toto je rozhodujúce pre prevenciu útokov XSS.
- style-src: Špecifikuje zdroje, z ktorých je možné načítať štýly.
- img-src: Špecifikuje zdroje, z ktorých je možné načítať obrázky.
- font-src: Špecifikuje zdroje, z ktorých je možné načítať fonty.
- media-src: Špecifikuje zdroje, z ktorých je možné načítať audio a video.
- object-src: Špecifikuje zdroje, z ktorých je možné načítať pluginy (napr. Flash). Toto sa často nastavuje na 'none', aby sa pluginy úplne zakázali kvôli ich inherentným bezpečnostným rizikám.
- frame-src: Špecifikuje zdroje, z ktorých je možné načítať rámce (napr. <iframe>).
- connect-src: Špecifikuje adresy URL, ku ktorým sa môže používateľský agent pripojiť pomocou skriptovacích rozhraní, ako sú XMLHttpRequest, WebSocket a EventSource.
- base-uri: Špecifikuje adresy URL, ktoré je možné použiť v elemente <base> dokumentu.
- form-action: Špecifikuje adresy URL, na ktoré je možné odosielať odoslané formuláre.
- upgrade-insecure-requests: Inštruuje používateľského agenta, aby automaticky upgradoval nezabezpečené požiadavky (HTTP) na zabezpečené požiadavky (HTTPS).
- report-uri: Špecifikuje adresu URL, kam má prehliadač odosielať správy o porušeniach CSP. Táto direktíva je zastaraná v prospech `report-to`.
- report-to: Špecifikuje názov reportingovej skupiny definovaný v hlavičke `Report-To`, kam má prehliadač odosielať správy o porušeniach CSP.
CSP Kľúčové slová zoznamu zdrojov
V rámci CSP direktív môžete použiť kľúčové slová zoznamu zdrojov na definovanie povolených zdrojov. Tu sú niektoré bežné kľúčové slová:
- 'self': Umožňuje zdroje z rovnakej domény (schéma a hostiteľ) ako dokument.
- 'none': Zakazuje zdroje zo všetkých zdrojov.
- 'unsafe-inline': Umožňuje používanie inline skriptov a štýlov (napr. <script> tagy a atribúty štýlu). Používajte s maximálnou opatrnosťou, pretože to výrazne oslabuje ochranu CSP proti XSS.
- 'unsafe-eval': Umožňuje používanie funkcií dynamického vyhodnocovania kódu, ako sú
eval()aFunction(). Používajte s maximálnou opatrnosťou, pretože to predstavuje významné bezpečnostné riziká. - 'unsafe-hashes': Umožňuje špecifické inline obslužné programy udalostí alebo <style> tagy, ktoré zodpovedajú zadanému hashu. Vyžaduje podporu prehliadača. Používajte s opatrnosťou.
- 'strict-dynamic': Špecifikuje, že dôvera explicitne udelená skriptu prítomnému v markup, sprevádzaním ho nonce alebo hash, sa prenesie na všetky skripty načítané týmto koreňovým skriptom.
- data: Umožňuje data: URI (napr. inline obrázky kódované ako base64). Používajte s opatrnosťou.
- https:: Umožňuje načítavanie zdrojov cez HTTPS z akejkoľvek domény.
- [hostname]: Umožňuje zdroje z konkrétnej domény (napr. example.com). Môžete tiež zadať číslo portu (napr. example.com:8080).
- [scheme]://[hostname]:[port]: Plne kvalifikované URI, ktoré umožňuje zdroje zo zadanej schémy, hostiteľa a portu.
Praktické CSP príklady
Pozrime sa na niektoré praktické príklady hlavičiek CSP:
Príklad 1: Základné CSP s 'self'
Táto politika umožňuje zdroje iba z rovnakej domény:
Content-Security-Policy: default-src 'self'
Príklad 2: Povolenie skriptov z konkrétnej domény
Táto politika umožňuje skripty z vašej vlastnej domény a dôveryhodného CDN:
Content-Security-Policy: default-src 'self'; script-src 'self' https://cdn.example.com
Príklad 3: Zakázanie inline skriptov a štýlov
Táto politika zakazuje inline skripty a štýly, čo je silná ochrana proti XSS:
Content-Security-Policy: default-src 'self'; script-src 'self'; style-src 'self'
Dôležité: Zakázanie inline skriptov vyžaduje refaktorovanie vášho HTML na presun inline skriptov do externých súborov.
Príklad 4: Používanie Nonces pre inline skripty
Ak musíte použiť inline skripty, použite nonces (kryptograficky náhodné, jednorazové tokeny) na whitelistovanie konkrétnych blokov inline skriptov. Toto je bezpečnejšie ako 'unsafe-inline'. Server musí vygenerovať jedinečný nonce pre každú požiadavku a zahrnúť ho do hlavičky CSP aj do <script> tagu.
Content-Security-Policy: default-src 'self'; script-src 'nonce-r4nd0mN0nc3'; style-src 'self'
<script nonce="r4nd0mN0nc3"> console.log('Inline script'); </script>
Poznámka: Nezabudnite vygenerovať nový nonce pre každú požiadavku. Nepoužívajte nonces opakovane!
Príklad 5: Používanie Hashov pre inline štýly
Podobne ako nonces, hashe sa môžu použiť na whitelistovanie špecifických inline <style> blokov. Toto sa robí generovaním SHA256, SHA384 alebo SHA512 hashu obsahu štýlu.
Content-Security-Policy: default-src 'self'; style-src 'sha256-HASHEDSTYLES'
<style sha256="HASHEDSTYLES"> body { background-color: #f0f0f0; } </style>
Poznámka: Hashe sú menej flexibilné ako nonces, pretože akákoľvek zmena obsahu štýlu zneplatní hash.
Príklad 6: Hlásenie porušení CSP
Na monitorovanie porušení CSP použite direktívu report-uri alebo report-to:
Content-Security-Policy: default-src 'self'; report-to csp-endpoint;
Budete tiež musieť nakonfigurovať hlavičku Report-To. Hlavička Report-To definuje jednu alebo viac reportingových skupín, ktoré špecifikujú, kam a ako sa majú správy odosielať.
Report-To: {"group":"csp-endpoint","max_age":10886400,"endpoints":[{"url":"https://example.com/csp-report"}]}
Testovanie a nasadzovanie CSP
Implementácia CSP vyžaduje starostlivé plánovanie a testovanie. Začnite s reštriktívnou politikou a postupne ju uvoľňujte podľa potreby. Použite hlavičku Content-Security-Policy-Report-Only na testovanie vašej politiky bez blokovania zdrojov. Táto hlavička hlási porušenia bez vynucovania politiky, čo vám umožňuje identifikovať a opraviť problémy pred nasadením politiky do produkcie.
Content-Security-Policy-Report-Only: default-src 'self'; report-to csp-endpoint;
Analyzujte správy generované prehliadačom, aby ste identifikovali akékoľvek porušenia a podľa toho upravte svoju politiku. Keď ste si istí, že vaša politika funguje správne, nasaďte ju pomocou hlavičky Content-Security-Policy.
Osvedčené postupy pre CSP
- Začnite s default-src: Vždy definujte
default-srcna vytvorenie základnej politiky. - Buďte konkrétni: Použite špecifické direktívy a kľúčové slová zoznamu zdrojov na obmedzenie rozsahu vašej politiky.
- Vyhnite sa 'unsafe-inline' a 'unsafe-eval': Tieto kľúčové slová výrazne oslabujú CSP a mali by ste sa im vyhnúť, kedykoľvek je to možné.
- Použite nonces alebo hashe pre inline skripty a štýly: Ak musíte použiť inline skripty alebo štýly, použite nonces alebo hashe na whitelistovanie špecifických blokov kódu.
- Monitorujte porušenia CSP: Použite direktívu
report-urialeboreport-tona monitorovanie porušení CSP a podľa toho upravte svoju politiku. - Dôkladne testujte: Použite hlavičku
Content-Security-Policy-Report-Onlyna testovanie vašej politiky pred jej nasadením do produkcie. - Opakujte a vylepšujte: CSP nie je jednorazová konfigurácia. Neustále monitorujte a vylepšujte svoju politiku, aby ste sa prispôsobili zmenám vo vašej aplikácii a v prostredí hrozieb.
Čo je Cross-Origin Resource Sharing (CORS)?
Cross-Origin Resource Sharing (CORS) je mechanizmus, ktorý umožňuje webovým stránkam z jedného pôvodu (domény) pristupovať k zdrojom z iného pôvodu. Prehliadače štandardne vynucujú Same-Origin Policy, ktorá zabraňuje skriptom vykonávať požiadavky na iný pôvod, ako je ten, z ktorého skript pochádza. CORS poskytuje spôsob, ako selektívne uvoľniť toto obmedzenie, čo umožňuje legitímne požiadavky medzi doménami a zároveň chráni pred škodlivými útokmi.
Pochopenie Same-Origin Policy
Same-Origin Policy je základný bezpečnostný mechanizmus, ktorý zabraňuje škodlivému skriptu z jednej webovej stránky pristupovať k citlivým údajom na inej webovej stránke. Pôvod je definovaný schémou (protokolom), hostiteľom (doménou) a portom. Dve adresy URL majú rovnaký pôvod, ak a len ak majú rovnakú schému, hostiteľa a port.
Napríklad:
https://www.example.com/app1/index.htmlahttps://www.example.com/app2/index.htmlmajú rovnaký pôvod.https://www.example.com/index.htmlahttp://www.example.com/index.htmlmajú rôzne pôvody (rôzna schéma).https://www.example.com/index.htmlahttps://sub.example.com/index.htmlmajú rôzne pôvody (rôzny hostiteľ).https://www.example.com:8080/index.htmlahttps://www.example.com:80/index.htmlmajú rôzne pôvody (rôzny port).
Ako CORS funguje
Keď webová stránka vykoná požiadavku medzi doménami, prehliadač najprv odošle požiadavku „preflight“ na server. Požiadavka preflight používa metódu HTTP OPTIONS a obsahuje hlavičky, ktoré označujú metódu HTTP a hlavičky, ktoré bude používať skutočná požiadavka. Server potom odpovie s hlavičkami, ktoré označujú, či je požiadavka medzi doménami povolená.
Ak server povolí požiadavku, zahrnie do odpovede hlavičku Access-Control-Allow-Origin. Táto hlavička špecifikuje pôvod(y), ktoré majú povolený prístup k zdroju. Prehliadač potom pokračuje so skutočnou požiadavkou. Ak server nepovolí požiadavku, nezahrnie hlavičku Access-Control-Allow-Origin a prehliadač zablokuje požiadavku.
CORS hlavičky: Podrobný pohľad
CORS sa spolieha na hlavičky HTTP na komunikáciu medzi prehliadačom a serverom. Tu sú kľúčové hlavičky CORS:
- Access-Control-Allow-Origin: Špecifikuje pôvod(y), ktoré majú povolený prístup k zdroju. Táto hlavička môže obsahovať špecifický pôvod (napr.
https://www.example.com), zástupný znak (*) alebonull. Používanie*umožňuje požiadavky z akéhokoľvek pôvodu, čo sa vo všeobecnosti neodporúča z bezpečnostných dôvodov. Používanie `null` je vhodné iba pre „nepriehľadné odpovede“, napríklad keď sa zdroj načíta pomocou protokolu `file://` alebo URI dát. - Access-Control-Allow-Methods: Špecifikuje metódy HTTP, ktoré sú povolené pre požiadavku medzi doménami (napr.
GET, POST, PUT, DELETE). - Access-Control-Allow-Headers: Špecifikuje hlavičky HTTP, ktoré sú povolené v požiadavke medzi doménami. Toto je dôležité pre spracovanie vlastných hlavičiek.
- Access-Control-Allow-Credentials: Označuje, či má prehliadač zahrnúť poverenia (napr. cookies, autorizačné hlavičky) do požiadavky medzi doménami. Táto hlavička musí byť nastavená na
true, aby sa povolili poverenia. - Access-Control-Expose-Headers: Špecifikuje, ktoré hlavičky môžu byť sprístupnené klientovi. Predvolene je sprístupnená iba obmedzená množina hlavičiek.
- Access-Control-Max-Age: Špecifikuje maximálny čas (v sekundách), počas ktorého môže prehliadač ukladať do vyrovnávacej pamäte požiadavku preflight.
- Origin: Toto je hlavička požiadavky odoslaná prehliadačom na označenie pôvodu požiadavky.
- Vary: Všeobecná hlavička HTTP, ale dôležitá pre CORS. Keď sa dynamicky generuje `Access-Control-Allow-Origin`, hlavička `Vary: Origin` by mala byť zahrnutá v odpovedi, aby sa inštruovali mechanizmy ukladania do vyrovnávacej pamäte, že odpoveď sa líši v závislosti od hlavičky požiadavky `Origin`.
Praktické CORS príklady
Pozrime sa na niektoré praktické príklady konfigurácií CORS:
Príklad 1: Povolenie požiadaviek z konkrétneho pôvodu
Táto konfigurácia umožňuje požiadavky iba z https://www.example.com:
Access-Control-Allow-Origin: https://www.example.com
Príklad 2: Povolenie požiadaviek z akéhokoľvek pôvodu (Neodporúča sa)
Táto konfigurácia umožňuje požiadavky z akéhokoľvek pôvodu. Používajte s opatrnosťou, pretože to môže predstavovať bezpečnostné riziká:
Access-Control-Allow-Origin: *
Príklad 3: Povolenie špecifických metód a hlavičiek
Táto konfigurácia umožňuje metódy GET, POST a PUT a hlavičky Content-Type a Authorization:
Access-Control-Allow-Origin: https://www.example.com
Access-Control-Allow-Methods: GET, POST, PUT
Access-Control-Allow-Headers: Content-Type, Authorization
Príklad 4: Povolenie poverení
Ak chcete povoliť poverenia (napr. cookies), musíte nastaviť Access-Control-Allow-Credentials na true a zadať špecifický pôvod (nemôžete použiť *, keď povolíte poverenia):
Access-Control-Allow-Origin: https://www.example.com
Access-Control-Allow-Credentials: true
Musíte tiež nastaviť credentials: 'include' vo vašej JavaScript fetch/XMLHttpRequest požiadavke.
fetch('https://api.example.com/data', {
credentials: 'include'
})
CORS Preflight Požiadavky
Pre určité typy požiadaviek medzi doménami (napr. požiadavky s vlastnými hlavičkami alebo metódami inými ako GET, HEAD alebo POST s Content-Type application/x-www-form-urlencoded, multipart/form-data alebo text/plain), prehliadač odošle požiadavku preflight pomocou metódy OPTIONS. Server musí odpovedať na požiadavku preflight s príslušnými hlavičkami CORS, aby označil, či je skutočná požiadavka povolená.
Tu je príklad požiadavky a odpovede preflight:
Preflight Požiadavka (OPTIONS):
OPTIONS /data HTTP/1.1
Origin: https://www.example.com
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: Content-Type, Authorization
Preflight Odpoveď (200 OK):
HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://www.example.com
Access-Control-Allow-Methods: GET, POST, PUT
Access-Control-Allow-Headers: Content-Type, Authorization
Access-Control-Max-Age: 86400
Hlavička Access-Control-Max-Age špecifikuje, ako dlho môže prehliadač ukladať do vyrovnávacej pamäte odpoveď preflight, čím sa znižuje počet požiadaviek preflight.
CORS a JSONP
JSON with Padding (JSONP) je staršia technika na obchádzanie Same-Origin Policy. JSONP má však významné bezpečnostné riziká a malo by sa mu vyhnúť v prospech CORS. JSONP sa spolieha na vkladanie <script> tagov do stránky, ktoré môžu spustiť ľubovoľný kód. CORS poskytuje bezpečnejší a flexibilnejší spôsob spracovania požiadaviek medzi doménami.
Osvedčené postupy pre CORS
- Vyhnite sa používaniu *: Vyhnite sa používaniu zástupného znaku (*) v hlavičke
Access-Control-Allow-Origin, pretože to umožňuje požiadavky z akéhokoľvek pôvodu. Namiesto toho zadajte konkrétny pôvod(y), ktoré majú povolený prístup k zdroju. - Buďte špecifickí s metódami a hlavičkami: Zadajte presné metódy a hlavičky HTTP, ktoré sú povolené v hlavičkách
Access-Control-Allow-MethodsaAccess-Control-Allow-Headers. - Používajte Access-Control-Allow-Credentials s opatrnosťou: Iba povoľte
Access-Control-Allow-Credentials, ak potrebujete povoliť poverenia (napr. cookies) v požiadavkách medzi doménami. Buďte si vedomí bezpečnostných dôsledkov povolenia poverení. - Zabezpečte svoje požiadavky preflight: Uistite sa, že váš server správne spracováva požiadavky preflight a vracia správne hlavičky CORS.
- Používajte HTTPS: Vždy používajte HTTPS pre pôvod aj zdroje, ku ktorým pristupujete medzi doménami. To pomáha chrániť pred útokmi man-in-the-middle.
- Vary: Origin: Ak dynamicky generujete hlavičku `Access-Control-Allow-Origin`, vždy zahrňte hlavičku `Vary: Origin`, aby ste predišli problémom s ukladaním do vyrovnávacej pamäte.
CSP a CORS v praxi: Kombinovaný prístup
Zatiaľ čo CSP a CORS sa zaoberajú bezpečnostnými obavami, fungujú na rôznych vrstvách a poskytujú komplementárnu ochranu. CSP sa zameriava na zabránenie prehliadaču v načítavaní škodlivého obsahu, zatiaľ čo CORS sa zameriava na riadenie toho, ktoré pôvody majú prístup k zdrojom na vašom serveri.
Kombináciou CSP a CORS môžete vytvoriť robustnejšie zabezpečenie pre vaše webové aplikácie. Môžete napríklad použiť CSP na obmedzenie zdrojov, z ktorých je možné načítať skripty, a CORS na riadenie toho, ktoré pôvody majú prístup k vašim API endpointom.
Príklad: Zabezpečenie API pomocou CSP a CORS
Povedzme, že máte API hostované na https://api.example.com, ktoré chcete, aby bolo prístupné iba z https://www.example.com. Môžete nakonfigurovať svoj server tak, aby vracal nasledujúce hlavičky:
API Hlavičky odpovede (https://api.example.com):
Access-Control-Allow-Origin: https://www.example.com
Content-Type: application/json
A môžete nakonfigurovať svoju webovú stránku (https://www.example.com) na používanie nasledujúcej hlavičky CSP:
Webová stránka CSP Hlavička (https://www.example.com):
Content-Security-Policy: default-src 'self'; script-src 'self'; connect-src 'self' https://api.example.com;
Táto politika CSP umožňuje webovej stránke načítať skripty a pripojiť sa k API, ale zabraňuje jej načítavaniu skriptov alebo pripojeniu k iným doménam.
Záver
Content Security Policy (CSP) a Cross-Origin Resource Sharing (CORS) sú základné nástroje na posilnenie zabezpečenia vašich frontend aplikácií. Starostlivou konfiguráciou CSP a CORS môžete výrazne znížiť riziko útokov XSS, útokov vkladania dát a iných bezpečnostných zraniteľností. Nezabudnite začať s reštriktívnou politikou, dôkladne testovať a neustále monitorovať a vylepšovať svoju konfiguráciu, aby ste sa prispôsobili zmenám vo vašej aplikácii a vyvíjajúcemu sa prostrediu hrozieb. Uprednostnením zabezpečenia frontendu môžete chrániť svojich používateľov a zabezpečiť integritu vašich webových aplikácií v dnešnom čoraz komplexnejšom digitálnom svete.