Content Security Policy

Content Security Policy

CSP (Content Security Policy): prečo je kritická pre moderné weby

Content Security Policy (CSP) je bezpečnostná HTTP politika, ktorá obmedzuje, odkiaľ a aký obsah sa môže na stránke načítavať a vykonávať. Jej hlavným cieľom je zmierniť riziká Cross-Site Scriptingu (XSS), injekcií, clickjackingu a zneužiťelných tretích strán. V ére multimodálnej indexácie (AIO/AEO) a prísnych požiadaviek na dôveryhodnosť obsahu je CSP kľúčová nielen pre bezpečnosť, ale aj pre stabilitu renderingu, Core Web Vitals a spoľahlivú indexáciu vyhľadávačmi aj LLM systémami.

Ako CSP funguje: princíp deklaratívnej whitelisty

  • Server posiela politiku cez HTTP hlavičku Content-Security-Policy (alebo Content-Security-Policy-Report-Only pri testovaní).
  • Prehliadač porovnáva každý sieťový a vykonávací krok s pravidlami (direktívami). To, čo nie je povolené, je zablokované alebo nahlásené.
  • CSP je deklaratívna a predvídateľná: znižuje plochu útoku bez potreby meniť sandbox logiku prehliadača.

Prepojenie CSP so SEO, AIO a AEO

  • Stabilná renderovacia cesta: správne nastavená CSP minimalizuje zlyhané načítania JS/CSS a layout shifts, čím podporuje LCP/INP/CLS.
  • Dôveryhodnosť signálov: blokovanie neautorizovaných skriptov bráni manipulácii so štruktúrovanými dátami, meta údajmi a meraniami.
  • Deterministický HTML pre LLM: AI indexácia preferuje konzistentné, neinfikované DOM; CSP znižuje riziko injektovaných fragmentov, ktoré by mohli miasť modely.
  • Kontrola tretích strán: minimalizácia „JS bloatu“ a trackingu chráni výkon a reputáciu domény, čo sekundárne podporuje viditeľnosť.

Režimy nasadenia: Report-Only a Enforce

  • Report-Only: prehliadač porušenia len hlási na endpoint; ideálne na audit a vytváranie baseline.
  • Enforce (ostrý režim): prehliadač porušenia blokuje; nasadzujte po overení metrik a logov.

Základné direktívy CSP a ich význam

  • default-src: východiskový zdroj pre všetky typy, ktoré nemajú vlastnú direktívu.
  • script-src: zdroje JavaScriptu; podporuje 'nonce-...', 'sha256-...', 'strict-dynamic', 'unsafe-inline' (neodporúča sa).
  • style-src: zdroje CSS; podobné pravidlá ako script-src s vlastnými výnimkami (napr. 'unsafe-inline' pre inline štýly – snažte sa vyhnúť).
  • img-src: zdroje obrázkov (vrátane data: a blob:, ak je to potrebné).
  • font-src: zdroje fontov; obmedzte na vlastnú CDN.
  • connect-src: XHR/fetch/WebSocket/Beacon; kľúčová pre analytiku a API volania.
  • frame-src a child-src: povoliť vložený obsah (mapy, videá) iba z dôveryhodných domén.
  • object-src: vždy nastavte na 'none'; NPAPI/Flash sú minulosťou a rizikom.
  • base-uri: zamedzí zneužitiu <base>; nastaviť na vlastnú doménu alebo 'none'.
  • form-action: definuje, kam môžu formuláre odosielať dáta.
  • frame-ancestors: kontroluje, kto môže stránku vkladať do <iframe>; alternatíva ku X-Frame-Options.
  • upgrade-insecure-requests: automaticky prepisuje HTTP na HTTPS; vhodné pri migrácii.
  • block-all-mixed-content: blokuje zmiešaný obsah; chráni pred znížením úrovne zabezpečenia.
  • report-to a report-uri: definujú, kam posielať hlásenia porušení.

Nonce, hash a strict-dynamic: moderné techniky pre skripty

  • Nonce: server pri renderi vygeneruje kryptograficky bezpečný token a vloží ho do inline skriptov ako nonce="...token...". CSP povolí iba skripty s týmto nonce.
  • Hash: pre statické inline skripty použite 'sha256-...' (alebo sha384/sha512) otlačok obsahu.
  • strict-dynamic: ak je prítomný a aspoň jeden nonce alebo hash, prehliadač dôveruje dynamicky vloženým skriptom potomkami dôveryhodného skriptu bez nutnosti whitelistu domén.

Príklady politík (bez <pre>, len inline)

Základná bezpečná kostra: Content-Security-Policy: default-src 'self'; script-src 'self'; style-src 'self'; img-src 'self' data:; font-src 'self'; object-src 'none'; base-uri 'self'; frame-ancestors 'none'; form-action 'self'; upgrade-insecure-requests; block-all-mixed-content

Nonce + strict-dynamic: Content-Security-Policy: default-src 'self'; script-src 'nonce-r4nd0m' 'strict-dynamic' https:; object-src 'none'; base-uri 'self'; a v HTML skripte: <script nonce="r4nd0m">/* bootstrap */</script>

Report-Only pre audit: Content-Security-Policy-Report-Only: default-src 'self'; script-src 'self'; report-uri https://csp.example.com/report

Vplyv CSP na výkon a Core Web Vitals

  • Predvídateľný reťazec závislostí: menej neočakávaných skriptov => nižšie riziko blokovania hlavného vlákna a lepšia INP.
  • Menej mixed content: stabilnejšie načítanie zdrojov = menej fall-backov a reflow => lepší LCP/CLS.
  • Kontrolované tretie strany: prísny connect-src a script-src bránia „tajnému“ načítaniu ťažkých knižníc.

Kompatibilita a postupná adopcia

  • Začnite v Report-Only, zbierajte logy, iterujte whitelisty, až potom prepnite do Enforce.
  • Opatrne s 'unsafe-inline' a 'unsafe-eval'; ide o dočasné crutches pri refaktoringu, nie dlhodobé riešenie.
  • Ak používate knižnice vkladajúce štýly/skripty (napr. SPA frameworky), preferujte nonce alebo hash stratégie.

CSP a hydratačné frameworky (SSR/SSG)

  • Generujte nonce na request a prepasujte ho do šablón, aby inline bootstrap skript mohol prejsť.
  • Minimalizujte inline kód; ak je nutný, používajte 'sha256-...' alebo nonce.
  • Pri ostrovčekovej architektúre skontrolujte, že dynamicky importované bundly rešpektujú script-src (napr. načítanie z vašej CDN s integritou).

Trusted Types: doplnok k CSP na elimináciu XSS

Trusted Types (aktivovaný cez CSP direktívu require-trusted-types-for 'script') bráni zneužitiu API, ktoré akceptujú HTML/JS reťazce (napr. innerHTML). Núti aplikáciu používať bezpečné továrne na sanitizáciu. Pre vysokobezpečnostné portály ide o výrazné posilnenie CSP.

Politika pre zdroje: obrázky, fonty, média, iframy

  • img-src: povoľte precízne (napr. vlastná CDN a data: iba ak potrebujete drobné inlinované obrázky).
  • font-src: typicky vlastná CDN; nezabudnite na crossorigin hlavičky a cache.
  • media-src: streamy povoľujte selektívne; pre externé prehrávače pridajte frame-src s konkrétnymi doménami.
  • frame-ancestors: zabráni clickjackingu; povoľte iba dôveryhodných partnerov (ak vôbec).

Reportovanie incidentov a observabilita

  • Konfigurujte report-uri alebo report-to na vlastný endpoint alebo službu na zber eventov.
  • Logy párujte s vydaniami (release ID) a cestami, aby ste rýchlo identifikovali šablóny, ktoré porušenia spôsobujú.
  • Agregujte podľa direktívy a zdroja, sledujte trend false positives pri Report-Only a postupne upravujte politiku.

Migrácia existujúcej aplikácie na prísnu CSP

  1. Audit: zapnite Report-Only, zbierajte porušenia aspoň niekoľko dní na reálnej prevádzke.
  2. Refaktoring inline: premiestnite inline skripty a štýly do súborov alebo zaveďte nonce/hash.
  3. Mapovanie tretích strán: identifikujte, ktoré domény sú nevyhnutné; redukujte a verzujte.
  4. Postupné sprísnenie: najskôr object-src 'none', base-uri 'self', potom script-src a style-src bez 'unsafe-inline'.
  5. Prechod na Enforce: po stabilizácii metrik prepnite a sledujte produkčné logy.

Najčastejšie chyby (anti-patterns)

  • Ponechanie 'unsafe-inline' a 'unsafe-eval' natrvalo „pre pohodlie“.
  • Príliš široké default-src * alebo script-src https: bez ďalších obmedzení.
  • Ignorovanie frame-ancestors a spoliehanie sa len na X-Frame-Options.
  • Nepovolené endpointy v connect-src, ktoré ticho rozbijú analytiku alebo A/B testovanie.
  • Chýbajúce logovanie porušení a nasadenie priamo v Enforce bez pilotnej fázy.

Šablóny politík podľa typu webu

Obsahový web / blog: Content-Security-Policy: default-src 'self'; script-src 'self'; style-src 'self'; img-src 'self' data:; font-src 'self'; object-src 'none'; base-uri 'self'; frame-ancestors 'none'; form-action 'self'

E-commerce s vybranými third-party: Content-Security-Policy: default-src 'self'; script-src 'self' https://pay.example.com https://tag.example.com; style-src 'self'; img-src 'self' https://img.cdn.example.com data:; connect-src 'self' https://api.example.com https://analytics.example.com; frame-src https://pay.example.com; object-src 'none'; base-uri 'self'; form-action 'self' https://pay.example.com

Webová aplikácia s nonce a dynamickými importmi: Content-Security-Policy: default-src 'self'; script-src 'nonce-ABCD' 'strict-dynamic' https:; style-src 'self'; img-src 'self' data:; connect-src 'self' https://api.example.com; font-src 'self'; object-src 'none'; base-uri 'self'

Integrácia s ďalšími bezpečnostnými hlavičkami

  • Referrer-Policy: minimalizuje únik citlivých URL parametrov.
  • Permissions-Policy: obmedzuje prístup k senzorom a API (kamera, geolokácia).
  • Cross-Origin-Opener/Embedder/Resource-Policy: hardenovanie hraníc medzi pôvodmi.
  • X-Content-Type-Options: nosniff: bráni MIME sniffingu.

Procesné odporúčania pre tímy (Dev, Sec, SEO)

  • Spoločná matica tretích strán: na jednom mieste dokumentujte účel, domény a SLA každého externého skriptu.
  • CI/CD brány: kontrolujte zmeny politík a veľkosť JS bundlov, vyžadujte nonce/hash injekciu.
  • Runbook incidentov: čo robiť, keď CSP náhle blokuje kľúčový zdroj (feature flag, rollback, výnimky).
  • SEO/AIO overenie: testujte, či CSP neblokuje štruktúrované dáta, kanonické linky alebo kritické CSS/JS pre render.

Checklista pred ostrým nasadením

  • Je k dispozícii Report-Only história aspoň niekoľko dní?
  • Máte pokryté object-src 'none', base-uri 'self' a frame-ancestors?
  • Sú inline skripty/štýly nahradené súbormi alebo chránené nonce/hash?
  • Je zoznam tretích strán minimálny a zdokumentovaný?
  • Fungujú stránky bez chýb v konzole a bez degradácie CWV?
  • Konfigurácia report-to/report-uri je aktívna a monitorovaná?

Zhrnutie

CSP je efektívny, štandardizovaný nástroj na redukciu XSS a rizík z externých zdrojov. Správne navrhnutá politika zvyšuje dôveryhodnosť a výkon webu, chráni integritu štruktúrovaných dát a zlepšuje predvídateľnosť renderingu – čo je kľúčové pre SEO, AIO a AEO. Začnite v režime Report-Only, iterujte, zavádzajte nonce/hash a striktne kontrolujte tretie strany. Výsledkom je bezpečnejší web, lepšia používateľská skúsenosť a stabilnejšie signály pre vyhľadávače aj AI systémy.

Pridaj komentár

Vaša e-mailová adresa nebude zverejnená. Vyžadované polia sú označené *