Content Security Policy: klíčová bezpečnostní politika pro moderní webové aplikace

CSP (Content Security Policy): proč je kritická pro moderní weby

Content Security Policy (CSP) je bezpečnostní HTTP politika, která omezuje, odkud a jaký obsah se může na stránce načítat a vykonávat. Jejím hlavním cílem je zmírnit rizika Cross-Site Scriptingu (XSS), injekcí, clickjackingu a zneužití třetích stran. V éře multimodální indexace (AIO/AEO) a přísných požadavků na důvěryhodnost obsahu je CSP klíčová nejen pro bezpečnost, ale i pro stabilitu renderingu, Core Web Vitals a spolehlivou indexaci vyhledávači i LLM systémy.

Jak CSP funguje: princip deklarativní whitelisty

  • Server posílá politiku přes HTTP hlavičku Content-Security-Policy (nebo Content-Security-Policy-Report-Only při testování).
  • Prohlížeč porovnává každý síťový a vykonávací krok s pravidly (direktivami). To, co není povoleno, je zablokováno nebo nahlášeno.
  • CSP je deklarativní a předvídatelná: snižuje plochu útoku bez potřeby měnit sandbox logiku prohlížeče.

Propojení CSP se SEO, AIO a AEO

  • Stabilní renderovací cesta: správně nastavená CSP minimalizuje selhání načítání JS/CSS a layout shifts, čím podporuje LCP/INP/CLS.
  • Důvěryhodnost signálů: blokování neautorizovaných skriptů zabraňuje manipulaci se strukturovanými daty, metadaty a měřeními.
  • Deterministický HTML pro LLM: AI indexace preferuje konzistentní, neinfikovaný DOM; CSP snižuje riziko injektovaných fragmentů, které by mohly mást modely.
  • Kontrola třetích stran: minimalizace „JS bloatu“ a trackingu chrání výkon a reputaci domény, což sekundárně podporuje viditelnost.

Režimy nasazení: Report-Only a Enforce

  • Report-Only: prohlížeč porušení pouze hlásí na endpoint; ideální pro audit a vytváření baseline.
  • Enforce (ostrý režim): prohlížeč porušení blokuje; nasazujte po ověření metrik a logů.

Základní direktivy CSP a jejich význam

  • default-src: výchozí zdroj pro všechny typy, které nemají vlastní direktivu.
  • script-src: zdroje JavaScriptu; podporuje 'nonce-...', 'sha256-...', 'strict-dynamic', 'unsafe-inline' (nedoporučuje se).
  • style-src: zdroje CSS; podobná pravidla jako script-src s vlastními výjimkami (např. 'unsafe-inline' pro inline styly – snažte se vyhnout).
  • img-src: zdroje obrázků (včetně data: a blob:, pokud je to potřeba).
  • font-src: zdroje fontů; omezte na vlastní CDN.
  • connect-src: XHR/fetch/WebSocket/Beacon; klíčová pro analytiku a API volání.
  • frame-src a child-src: povolit vložený obsah (mapy, videa) pouze z důvěryhodných domén.
  • object-src: vždy nastavte na 'none'; NPAPI/Flash jsou minulostí a rizikem.
  • base-uri: zamezí zneužití <base>; nastavte na vlastní doménu nebo 'none'.
  • form-action: definuje, kam mohou formuláře odesílat data.
  • frame-ancestors: kontroluje, kdo může stránku vkládat do <iframe>; alternativa ke X-Frame-Options.
  • upgrade-insecure-requests: automaticky přepisuje HTTP na HTTPS; vhodné při migraci.
  • block-all-mixed-content: blokuje smíšený obsah; chrání před snížením úrovně zabezpečení.
  • report-to a report-uri: definují, kam posílat hlášení porušení.

Nonce, hash a strict-dynamic: moderní techniky pro skripty

  • Nonce: server při renderu vygeneruje kryptograficky bezpečný token a vloží ho do inline skriptů jako nonce="...token...". CSP povolí pouze skripty s tímto nonce.
  • Hash: pro statické inline skripty použijte 'sha256-...' (nebo sha384/sha512) otisk obsahu.
  • strict-dynamic: pokud je přítomný a alespoň jeden nonce nebo hash, prohlížeč důvěřuje dynamicky vloženým skriptům potomků důvěryhodného skriptu bez nutnosti whitelistu domén.

Příklady politik (bez <pre>, jen 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 skriptu: <script nonce="r4nd0m">/* bootstrap */</script>

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

Vliv CSP na výkon a Core Web Vitals

  • Předvídatelný řetězec závislostí: méně neočekávaných skriptů => nižší riziko blokování hlavního vlákna a lepší INP.
  • Méně mixed content: stabilnější načítání zdrojů = méně fallbacků a reflow => lepší LCP/CLS.
  • Kontrolované třetí strany: přísný connect-src a script-src zabraňují „tajnému“ načítání těžkých knihoven.

Kompatibilita a postupná adopce

  • Začněte v Report-Only, sbírejte logy, iterujte whitelisty, až potom přepněte do Enforce.
  • Opatrně s 'unsafe-inline' a 'unsafe-eval'; jedná se o dočasné výpomoci při refaktoringu, nikoli o dlouhodobé řešení.
  • Pokud používáte knihovny vkládající styly/skripty (např. SPA frameworky), preferujte nonce nebo hash strategie.

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

  • Generujte nonce na request a předejte ho do šablon, aby inline bootstrap skript mohl projít.
  • Minimalizujte inline kód; pokud je nutný, používejte 'sha256-...' nebo nonce.
  • Při ostrovní architektuře zkontrolujte, že dynamicky importované bundly respektují script-src (např. načítání z vaší CDN s integritou).

Trusted Types: doplněk k CSP pro eliminaci XSS

Trusted Types (aktivovaný přes CSP direktivu require-trusted-types-for 'script') brání zneužití API, které přijímají HTML/JS řetězce (např. innerHTML). Nutí aplikaci používat bezpečné továrny pro sanitizaci. Pro vysoce bezpečnostní portály jde o výrazné posílení CSP.

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

  • img-src: povolte precizně (např. vlastní CDN a data: pouze pokud potřebujete malé inline obrázky).
  • font-src: typicky vlastní CDN; nezapomeňte na crossorigin hlavičky a cache.
  • media-src: streamy povolujte selektivně; pro externí přehrávače přidejte frame-src s konkrétními doménami.
  • frame-ancestors: zabrání clickjackingu; povolte pouze důvěryhodné partnery (pokud vůbec).

Reportování incidentů a observabilita

  • Konfigurujte report-uri nebo report-to na vlastní endpoint nebo službu pro sběr událostí.
  • Logy párujte s verzemi (release ID) a cestami, abyste rychle identifikovali šablony, které porušení způsobují.
  • Agregujte podle direktivy a zdroje, sledujte trend false positives u Report-Only a postupně upravujte politiku.

Migrace existující aplikace na přísnou CSP

  1. Audit: zapněte Report-Only, sbírejte porušení aspoň několik dní v reálném provozu.
  2. Refaktoring inline: přesuňte inline skripty a styly do souborů nebo zaveďte nonce/hash.
  3. Mapování třetích stran: identifikujte, které domény jsou nezbytné; redukujte a verzujte.
  4. Postupné zpřísňování: nejprve object-src 'none', base-uri 'self', poté script-src a style-src bez 'unsafe-inline'.
  5. Přechod na Enforce: po stabilizaci metrik přepněte a sledujte produkční logy.

Nejčastější chyby (anti-patterns)

  • Ponechání 'unsafe-inline' a 'unsafe-eval' natrvalo „pro pohodlí“.
  • Příliš široké default-src * nebo script-src https: bez dalších omezení.
  • Ignorování frame-ancestors a spoléhání se pouze na X-Frame-Options.
  • Neoprávněné endpointy v connect-src, které tichounce rozbijí analytiku nebo A/B testování.
  • Chybějící logování porušení a nasazení přímo v Enforce bez pilotní fáze.

Šablony politik podle 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á aplikace s nonce a dynamickými importy: 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'

Integrace s dalšími bezpečnostními hlavičkami

  • Referrer-Policy: minimalizuje únik citlivých URL parametrů.
  • Permissions-Policy: omezuje přístup k senzorům a API (kamera, geolokace).
  • Cross-Origin-Opener/Embedder/Resource-Policy: hardening hranic mezi původy.
  • X-Content-Type-Options: nosniff: brání MIME sniffingu.

Procesní doporučení pro týmy (Dev, Sec, SEO)

  • Sdílená matice třetích stran: na jednom místě dokumentujte účel, domény a SLA každého externího skriptu.
  • CI/CD brány: kontrolujte změny politik a velikost JS bundlů, požadujte nonce/hash injekci.
  • Runbook incidentů: co dělat, když CSP náhle blokuje klíčový zdroj (feature flag, rollback, výjimky).
  • SEO/AIO ověření: testujte, zda CSP neblokuje strukturovaná data, kanonické linky nebo kritické CSS/JS pro rendering.

Checklist před ostrým nasazením

  • Existuje Report-Only historie alespoň několik dní?
  • Máte pokryté object-src 'none', base-uri 'self' a frame-ancestors?
  • Jsou inline skripty/styly nahrazeny soubory nebo chráněny nonce/hash?
  • Je seznam třetích stran minimální a zdokumentovaný?
  • Fungují stránky bez chyb v konzoli a bez degradace CWV?
  • Je konfigurace report-to/report-uri aktivní a monitorovaná?

Shrnutí

CSP je efektivní, standardizovaný nástroj na redukci XSS a rizik z externích zdrojů. Správně navržená politika zvyšuje důvěryhodnost a výkon webu, chrání integritu strukturovaných dat a zlepšuje předvídatelnost renderingu – což je klíčové pro SEO, AIO a AEO. Začněte v režimu Report-Only, iterujte, zavádějte nonce/hash a přísně kontrolujte třetí strany. Výsledkem je bezpečnější web, lepší uživatelská zkušenost a stabilnější signály pro vyhledávače i AI systémy.