CSP a iné zabezpečenie webových stránok pomocou hlavičiek

Content Security Policy (CSP) určite nie je novinkou posledných dní, no dobre vieme ako to je s novými technológiami. Pokiaľ na pár hodín nezasadnete a neskúsite ich niekde pokusne nasadiť, tak sa nič nenaučíte.

Asi pred týždňom som sa dostal skrz tweet k prednáške Michala Špačka o XSS a CSP, ktorú mal na PHPlive. Keďže problematika nevyzerala zložito, povedal som si, že najbližší víkend jej pár hodín venujem, aspoň opäť pichnem trošku do bezpečnosti, nielen programovania.

Podstata CSP a načo je

Content Security Policy má za úlohu zabrániť načítavaniu nežiadúcich zdrojov na vašich stránkach. Či už sa jedná o JavaScript, CSS, fonty alebo obrázky, tak v prípade použitia CSP máte kontrolu nad tým, čo a odkiaľ bude na vašich stránkach načítané. Mohli by sme to nazvať „whitelitstingom“ zdrojov.

Predstavte si, že ste naprogramovali e-shop a nedopatrením sa stalo, že niektorý z používateľských vstupov ostal neošetrený. V popise objednávky sa vyskytne <script src="https://xss.sk/tajny-skript.js"></script>.

Správca systému objednávku kontroluje, a pri jej zobrazení sa načíta skript zo spomínanej adresy. Cross Site Scripting ako vyšitý. Čo ten skript robí, záleží od útočníka. Môže napríklad zobrať celú HTML stránku a poslať ju útočníkovi, aj s údajmi vášho zákazníka – to by bol ten lepší prípad.

Ak by mal váš systém nasadené CSP, tak správcovi informačného systému by sa v jeho prehliadači daný skript nenačítal, a dá sa povedať, že by ste boli ochránení, a to napriek tomu, že váš web je náchylný na XSS.

Ako to funguje

CSP spočíva v pridaní hlavičky do odpovede vášho servera. V tejto hlavičke je zadefinované z akých zdrojov sa môže konkrétny obsah načítavať. Prehliadač tejto hlavičke rozumie, a pokiaľ stránka bude chcieť niečo načítavať z iných ako povolených zdrojov, prehliadač to zablokuje.

Content-Security-Policy &quot;default-src &#39;self&#39;; script-src &#39;self&#39; &#39;unsafe-inline&#39; https://www.google-analytics.com https://use.typekit.net https://speakerdeck.com https://webelementsk.disqus.com; style-src &#39;self&#39; &#39;unsafe-inline&#39; https://use.typekit.net https://a.disquscdn.com; img-src &#39;self&#39; https://www.google-analytics.com https://p.typekit.net https://referrer.disqus.com; font-src &#39;self&#39; data:; frame-src &#39;self&#39; https://disqus.com https://speakerdeck.com https://www.slideshare.net https://www.youtube.com https://docs.google.com; upgrade-insecure-requests; block-all-mixed-content;&quot;

Rozmeníme na drobné:

  • default-src 'self'
  • script-src 'self' 'unsafe-inline' https://www.google-analytics.com https://use.typekit.net https://speakerdeck.com https://webelementsk.disqus.com
  • style-src 'self' 'unsafe-inline' https://use.typekit.net https://a.disquscdn.com
  • img-src 'self' https://www.google-analytics.com https://p.typekit.net https://referrer.disqus.com
  • font-src 'self' data:
  • frame-src 'self' https://disqus.com https://speakerdeck.com https://www.slideshare.net https://www.youtube.com https://docs.google.com
  • upgrade-insecure-requests
  • block-all-mixed-content

Väčšine z vás to už určite dáva zmysel, no predstavím aspoň pár dôležitých direktív.

default-src 'self'

Týmto nastavením získame základ – takpovediac najbezpečnejší. Nastavenie Content-Security-Policy: default-src 'self' totiž povolí načítavanie zdrojov len z našej stránky. A tak je jasné, že nebudú fungovať žiadne fonty z Typekitu, žiadne Google Analytics a podobne. Pretože default-src 'self' prednastaví hodnotu 'self' týmto direktívam: child-src, connect-src, font-src, img-src, media-src, object-src, script-srcstyle-src.

script-src 'self' 'unsafe-inline' https://www.google-analytics.com ...

Povolíme načítavanie skriptov (JavaScriptu) len z našej domény, potom z domény Google Analytics a podobne. Hodnota 'unsafe-inline' povolí aj inline tag <script></script> a vykonávanie kódu v ňom – nie je ale považovaná za bezpečnú, preto vás už svojim názvom upozorňuje, že je „unsafe“.

font-src 'self' data:

Fonty len z našej stránky a takzvanej „data URI“.

upgrade-insecure-requests

Týmto nastavením poviete prehliadaču, nech všetky zdroje načítava cez HTTPS, ak bola stránka načítaná cez HTTPS, napriek tomu, že stránka ich mala uvedené ako HTTP.

block-all-mixed-content

Ak bola stránka načítaná cez HTTPS, všetky zdroje musia ísť cez HTTPS. Tie cez HTTP nebudú načítané.


Existuje veľa ďalších možností ako nastaviť CSP, podporuje množstvo direktív (napr. direktíva form-action nastavuje, na ktoré stránky je možné odosielať formuláre) a nemá zmysel tu prepisovať celú dokumentáciu.

Tip: Ak si nie ste istý nastavením, môžete zatiaľ použiť hlavičku Content-Security-Policy-Report-Only, ktorá bude len sledovať použitie CSP a reportovať na zadefinovanú adresu. To sa vám môže hodiť, ak plánujete nasadiť CSP na veľký portál a nie je úplne triviálne zistiť, z akých zdrojov sa dodatočný obsah načítava.

Ďalšie zabezpečenie

CSP nie je zďaleka jedinou hlavičkou, ktorá pridáva na bezpečnosti.

Hlavička Strict-Transport-Security

Strict-Transport-Security &#39;max-age=31536000; includeSubDomains; preload&#39;

Strict Transport Security poznáme v spojitosti s HTTPS, špeciálne ako HSTS (HTTP Strict Transport Security). Jedná sa o prípad, keď pridaním tejto hlavičky nútime prehliadač, aby komunikoval so serverom výhradne cez zabezpečený TLS kanál.

  • hlavička vyššie hovorí, že chceme komunikovať cez HTTPS
  • na najbližších 365 dní
  • vrátane všetkých subdomén (na to pozor!)
  • a tiež, že plánujeme stránku pridať do tzv. „preload listu“ prehliadačov: hstspreload.appspot.com

Hlavička X-Xss-Protection

X-Xss-Protection &quot;1; mode=block&quot;

Nastavuje, či sa má použiť zabudovaná ochrana prehliadačov proti XSS. Možností nastavenie sú tri:

  • 0 vypnutá
  • 1 zapnutá
  • 1; mode=block zapnutá, avšak ak sa zistí prítomnosť XSS, odpoveď servera bude zablokovaná

Hlavička X-Content-Type-Options

X-Content-Type-Options &quot;nosniff&quot;

Hovorí prehliadačom, aby sa snažili nehádať Content Type, ale aby vždy používali ten, ktorý príde zo servera. Dôležité najmä kvôli sťahovaniu používateľmi nahraných súborov, kedy by mohol používateľ špeciálne pomenovať súbor, a podsunúť tak iný Content Type.

Hlavička X-Frame-Options

X-Frame-Options &quot;SAMEORIGIN&quot;

Špecifikujete, či môže byť vaša stránka načítaná cez iframe respektíve na ktorých stránkach. SAMEORIGIN povolí len vašu stránku, DENY zakáže vkladanie a allow-from: DOMENA povolí len zo zadanej domény. Správnym použitím tejto hlavičky zabránite tomu, aby bola vaša stránka použitá pri Clickjackingu.

Hlavička Public-Key-Pins

Public-Key-Pins &#39;pin-sha256=&quot;4PWfYq8wTEJsU9Yb10ZrJRomnVm1No/dq6PO27L87bA=&quot;; \
pin-sha256=&quot;jydaS2Wttx9uvS+5yH7Lepkw6ptkrNgOUV8yD+1j1KU=&quot;; \
pin-sha256=&quot;3LPZwmxEF/hvc/v8MNQmsSHc5V59/x3O2eNvFp82xa8=&quot;; max-age=2592000&#39;

HTTP Public Key Pinning (HPKP) pridáva ďalšiu úroveň bezpečnosti. A to tým, že hovorí, ktorým certifikátom má váš prehliadač dôverovať. Predvolené chovania prehliadača je, že dôveruje akýmkoľvek certifikátom, ktoré vydala certifikačná autorita, ktorej dôveruje.

Ak niekto certifikačnú autoritu napadne (málo pravdepodobné, no stalo sa), môže v jej mene vydávať certifikáty a prehliadač ich bude automaticky akceptovať. Preto opäť robíme „whitelisting“ (certifikátov) a bránime MITM útoku s použitím certifikátov kompromitovanej certifikačnej autority.

Nastavenie HPKP nie je zložité, no vyžaduje väčšiu mieru pozornosti pri generovaní kľúčov. Tiež treba dbať na bezpečné uchovanie kľúčov na dlhšie obdobie. Ak poviete prehliadaču, že má akceptovať len konkrétne kľúče a vy nie ste schopný (napr. o dva roky) vygenerovať certifikát so správnym kľúčom, nastáva problém.

Tip: Ak si nie ste istý nastavením, môžete zatiaľ použiť hlavičku Public-Key-Pins-Report-Only, ktorá funguje obdobne ako pri CSP – bude len reportovať.

Záver

Nastavením spomínaných 6 hlavičiek sa úroveň bezpečnosti vašej stránky posúva na oveľa lepšiu úroveň, zabránite veľa útokom. To ale neznamená, že sa máte vykašľať na zabezpečenie vašej aplikácie proti XSS a podobne.

Ak ste spravili všetko, ako ste mali, potešením nebude len vyššia bezpečnosť, ale aj pekný report, v ktorom získate skvelé hodnotenie. :)

Užitočné