Na navigaci | Klávesové zkratky

Jak správně nastavit CSP a script-src

Content Security Policy (CSP) je dodatečný bezpečnostní prvek, který prohlížeči říká, jaké další zdroje může stránka načítat a jak může být zobrazena. Chrání tak před vkládáním škodlivého kódu a útokům jako je XSS. Odesílá se v podobě hlavičky sestavené z řady direktiv. Jeho nasazení ale není vůbec triviální.

Obvykle chceme používat JavaScriptové knihovny umístěné na různých místech mimo náš server, například měřící kód Google Analytics, reklamní systémy, captchy atd. A tady bohužel první verze CSP selhává. Vyžaduje přesnou analýzu načítaného obsahu a nastavení správných pravidel. Tedy vytvořit whitelist, výčet všech domén, což není snadné, jelikož některé skripty dynamicky dotahují další skripty z jiných domén, nebo jsou na jiné domény přesměrované atd. A i když si dáte práci a seznam vytvoříte ručně, nikdy nevíte, co se může v budoucnu změnit, takže musíte neustále sledovat, jestli je seznam stále aktuální a opravovat ho. Analýza Google ukázala, že i to pečlivé ladění ve finále vede k tomu, že povolíte tak široký přístup, že celý smysl CSP padá, jen posíláte s každým požadavek mnohem větší hlavičky.

CSP level 2 už k problému přistupuje jinak, pomocí nonce, nicméně teprve třetí verze řešení dotáhla do konce. Bohužel zatím (rok 2019) nemá dostatečnou podporu u prohlížečů.

O tom, jak sestavit direktivy script-src a style-src, aby správně fungovaly i ve starších prohlížečích a přitom s tím bylo co nejméně práce, jsem sepsal podrobný článek v partnerské sekci Nette. V zásadě výsledná podoba může vypadat nějak takto:

script-src 'nonce-XXXXX' 'strict-dynamic' * 'unsafe-inline'
style-src 'nonce-XXXXX' * 'unsafe-inline'

Příklad použití v PHP

Vygenerujeme nonce a odešleme hlavičku:

$nonce = base64_encode(random_bytes(16));

header("Content-Security-Policy: script-src 'nonce-$nonce' 'strict-dynamic' * 'unsafe-inline'");

A vložíme nonce do HTML kódu:

<script nonce="<?=$nonce?>" src="..."></script>

Příklad použití v Nette

Protože Nette má vestavěnou podporu pro CSP a nonce od verze 2.4, stačí v konfiguračním souboru uvést:

http:
	csp:
		script-src: [nonce, strict-dynamic, *, unsafe-inline]
		style-src: [nonce, *, unsafe-inline]

A v šablonách pak používat:

<script n:nonce src="..."></script>
<style n:nonce>...</style>

Monitoring

Než nastavíte nová pravidla pro CSP, vyzkoušejte si je nejprve nanečisto pomocí hlavičky Content-Security-Policy-Report-Only. Ta funguje ve všech prohlížečích podporujících CSP. Při porušení pravidel prohlížeč nezablokuje skript, ale jen pošle notifikaci na URL uvedené v direktivě report-uri. K příjmu notifikací a jejich analýze můžete použít třeba službu Report URI.

http:
	cspReportOnly:
		script-src: [nonce, strict-dynamic, *, unsafe-inline]
		report-uri: https://xxx.report-uri.com/r/d/csp/reportOnly

Můžete zároveň používat obě hlavičky a v Content-Security-Policy mít ověřené a aktivní pravidla a zároveň v Content-Security-Policy-Report-Only si testovat jejich úpravu. Samozřejmě i selhání ostrých pravidlech si můžete nechat monitorovat.


phpFashion © 2004, 2024 David Grudl | o blogu

Ukázky zdrojových kódů smíte používat s uvedením autora a URL tohoto webu bez dalších omezení.