Zpět na blog
Implementace20. srpna 20268 min čteníAktualizováno 30. srpna 2026

Content Security Policy pro webové chatboty: Bezpečné povolené widgetů, API, obrázků a streamování

Prakticky použitelná CSP pro webové chatboty povoluje pouze skutečně potřebné skripty, API připojení, streamy a obrázky – bez zbytečných zástupných znaků (wildcards).

Dospělá technička akcí kontroluje na letním venkovním pódiu zabezpečený připojovací modul pro widget chatbota.

Webový chatbot se v prohlížeči málokdy skládá pouze z jediného JavaScriptového souboru. Loader otevře widget, API přijímá zprávy, odpovědi se vrací jako stream a profilové obrázky nebo média mohou ležet na další doméně. Content Security Policy (CSP) tyto cesty zviditelňuje a omezuje: prohlížeč načte nebo připojí pouze to, co webová stránka výslovně povoluje.

Jedná se o důležitou druhou ochrannou vrstvu proti Cross-Site Scripting (XSS) a neočekávanému obsahu třetích stran. CSP však neopravuje ani nezabezpečené API, ani chybějící autentizaci, nedostatečnou validaci vstupů nebo Prompt Injection. Redukuje možnosti vloženého kódu a omezuje rádius chyby. Klíčová je proto co nejmenší, otestovaná politika namísto dlouhého seznamu plošně schválených domén.

Proč widgety chatbotů potřebují zvláštní pravidla CSP

Při klasické obsahové stránce často stačí zdroje z vlastního původu (origin). Chatbot naopak po načtení pokračuje v komunikaci. Directiva connect-src řídí mimo jiné fetch(), XMLHttpRequest, EventSource, WebSocket a sendBeacon(). Přesně tudy proudí zprávy, streamované odpovědi, události zpětné vazby a případně telemetrie. Chybí-li správný původ, widget se sice zobrazí, ale nedokáže odpovídat.

Ostatní součásti spadají pod vlastní direktivy. script-src rozhoduje o loaderu widgetu, img-src o avatarech a obrázcích v odpovědích, style-src o stylech a font-src o externích písmech. Widget založený na iframe potřebuje navíc frame-src. Directiva default-src slouží jako záložní řešení pro mnoho výslovně neuvedených typů zdrojů, ale nenahrazuje vědomou inventuru.

Nejdůležitější příprava se proto neodehrává v generátoru CSP, ale v prohlížeči: Otevřete reprezentativní stránku, zahajte konverzaci, nechte vygenerovat dlouhou streamovanou odpověď, otevřete zdroje, odešlete zpětnou vazbu a otestujte chybové stavy i předání na operátora (handoff). V panelu Síť (Network) uvidíte skutečně oslovené originy. Ke každému hostiteli zdokumentujte účel, typ zdroje a odpovědnou osobu.

Oddělené povolení čtyř relevantních datových cest

1. Skript widgetu a inicializace

Získejte loader pokud možno ze stabilní, verzované adresy. Povolení jako script-src https: by bylo příliš široké, protože by povolovalo skripty z jakékoli HTTPS domény. Namísto toho povolte přesný CDN origin nebo dodávejte loader sami. Pokud integrace vyžaduje inline kód, použijte nonce vygenerovaný nově pro každou HTTP odpověď nebo odpovídající hash. 'unsafe-inline' by se neměl stát rychlým trvalým řešením.

Nonce patří pouze ke skriptům, které generuje sama serverová šablona. Middleware, který slepě přidá stejný nonce ke každé existující značce script, by dal důvěru i vloženým značkám. Pro statický, verzovaný skript třetí strany může dodatečně pomoci Subresource Integrity; u často se měnících souborů však musí být hash kontrolovaně aktualizován.

2. API, Server-Sent Events a WebSocket

Běžné požadavky POST a odpověď streamovaná přes fetch() vyžadují HTTPS API origin v connect-src. Server-Sent Events přes EventSource tam spadají rovněž. Pro WebSocket zadejte výslovně konkrétní origin wss://. Dokumentace MDN upozorňuje, že 'self' nezahrnuje schémata WebSocket ve všech prohlížečích automaticky. Vlastní direktiva s názvem stream-src neexistuje.

CSP a CORS řeší odlišné úkoly. CSP určuje, kam se stránka vůbec smí připojit; CORS určuje na straně serveru, které originy mohou číst odpověď v prohlížeči. Povolení v CSP tedy neřeší chybu CORS ani vypršený přístupový token. Proxy se stejným originem (Same-Origin-Proxy) může politiku zjednodušit, musí však stále správně zpracovávat autentizaci, limity požadavků (rate limits), časové limity a předávání chyb.

3. Obrázky, avatary a vygenerovaná média

V img-src povolte pouze vlastní origin a skutečně používaný média origin. data: je nutné pouze v případě, že widget používá malé vložené obrázky; blob: pouze v případě, že prohlížeč skutečně vytváří obrázky jako URL objektu blob. Každý další zdroj zvětšuje plochu pro útok. Pokud se obrázek nejprve načte pomocí fetch() a poté převede na Blob URL, mohou být ovlivněny jak connect-src, tak img-src.

Testujte nejen standardního avatara. Zkontrolujte náhledové obrázky, snímky obrazovky zdrojů, přílohy souborů, tmavý režim (Dark Mode) a zobrazení chyb u nedostupných médií. Parametry v URL mohou přenášet důvěrné informace do hlásících protokolů CSP; koncovým bodům pro reporting by proto měly být zprávy předávány s ohledem na datovou úspornost a neměly by se uchovávat na dobu neurčitou.

4. iframe, styly, fonty a volitelné worker skripty

Widget vložený přímo do DOM většinou nepotřebuje cizí rámec. V takovém případě může zůstat frame-src 'none'. Pokud však chat běží v iframe, povolte výhradně jeho přesný origin. Od toho je třeba odlišovat frame-ancestors: Tato direktiva určuje u dodávaného zdroje, které stránky jej mohou vkládat. Poskytovatel widgetu ji proto musí na své odpovědi iframe správně nastavit.

Při stylech a fontech platí stejný princip. Povolte konkrétní hostitele a vyhněte se 'unsafe-inline', pokud to integrace umožňuje. Worker nebo zvukové funkce se přidávají pouze tehdy, pokud je produkt skutečně používá. Preventivní povolení blob:, celých wildcard domén nebo libovolných zdrojů médií komplikuje pozdější audity.

Realistický příklad CSP pro widget chatbota

Následující domény jsou záměrně vyhrazené ukázkové domény. Nahraďte je originy z vlastní síťové analýzy. Příklad předpokládá externí loader, HTTPS API, oddělený WebSocket pro streamování a hostitele médií. Nepoužívá žádné plošné zástupné znaky (wildcards):

Content-Security-Policy:
  default-src 'self';
  script-src 'self' https://cdn.chat.example 'nonce-{RANDOM}';
  connect-src 'self' https://api.chat.example wss://stream.chat.example;
  img-src 'self' data: https://media.chat.example;
  style-src 'self' 'nonce-{RANDOM}';
  font-src 'self';
  frame-src 'none';
  worker-src 'self';
  object-src 'none';
  base-uri 'self';
  frame-ancestors 'self';
  form-action 'self';
  upgrade-insecure-requests;

{RANDOM} představuje silnou hodnotu, vygenerovanou nově pro každou odpověď, která je identická v hlavičce i u povolených prvků script nebo style. Pokud váš widget používá iframe, nahraďte frame-src 'none' přesným originem widgetu. Pokud používá výhradně HTTPS streamování přes fetch() nebo EventSource, origin pro WebSocket odpadá. Odstraňte každý zdroj, který není po úplném testu funkčnosti potřeba.

Politika je praktickým výchozím bodem, nikoli univerzální šablonou. Moderní přísná CSP může skripty ještě silněji řídit pomocí hodnot nonce nebo hashů a 'strict-dynamic'. Zda je to možné bez problémů s kompatibilitou, závisí na tom, jak loader vytváří další skripty. Vyjasněte si tento postup s poskytovatelem a otestujte prohlížeče, režim souhlasu (consent mode) a varianty nasazení.

Od režimu Report-Only k vynucené politice

Nenasazujte novou politiku do ostrého provozu bez prověření. Mechanismus W3C Content-Security-Policy-Report-Only hlásí porušení bez blokování zdrojů. Zjistíte tak zapomenuté hostitele obrázků, odlišný origin streamování nebo inline kód dříve, než to ovlivní uživatele. OWASP doporučuje jako preferovaný způsob doručení HTTP hlavičku; na rozdíl od prvku meta podporuje také plný rozsah funkcí.

  1. Vytvořte inventář: Otestujte spuštění widgetu, první zprávu, dlouhou streamovanou odpověď, zdroje, obrázky, zpětnou vazbu, předání na operátora a změnu souhlasu na několika typech stránek.
  2. Nasaďte Report-Only: Začněte s plánovanou úzkou politikou a sbírejte porušení po omezenou dobu. Odfiltrujte rozšíření prohlížeče a další nereprodukovatelné rušivé signály.
  3. Zdůvodněte každého hostitele: Rozšiřujte politiku pouze tehdy, pokud konkrétní funkce produktu origin vyžaduje. Vyhněte se zástupným znakům (wildcards) jako reakci na jednotlivá hlášení.
  4. Automatizovaně testujte: Doplňte end-to-end testy, které odešlou zprávu, počkají na streamování a načtou obrázek. Současně kontrolujte konzoli prohlížeče na porušení CSP.
  5. Vynuťte a sledujte: Aktivujte hlavičku Content-Security-Policy, souběžně sledujte ještě přísnější variantu v režimu Report-Only a porovnávejte chybovost.
  6. Wal.

Fázované nasazení se dobře hodí k chatbotu v Shadow Mode. Pro metriky specifické pro streamování vám pomůže článek o rozpočtech latence a timeoutech. Porušení CSP by se při tom měla považovat za samostatný signál: Vypršení časového limitu (timeout) a zablokované připojení vyžadují odlišnou analýzu příčin.

Typické chybné konfigurace

  • Příliš široké seznamy zdrojů: *, https: nebo velké wildcard domény dělají politiku pohodlnou, ale slabou a těžko prověřitelnou.
  • Testuje se pouze viditelný start: Widget se otevře, ale streamování, zpětná vazba, obrázky nebo handoff selžou až později.
  • 'unsafe-inline' zůstává trvale: Krátkodobá pomůcka pro kompatibilitu není nahrazena pomocí nonce, hashů ani externího kódu.
  • CSP se plete s řízením přístupu: Politika nenahrazuje oprávnění na stronie serveru, kontrolu relace ani ochranu před zneužitím volání nástrojů.
  • Zprávy obsahují příliš mnoho dat: Úplné URL adresy, parametry dotazu nebo uživatelský kontext končí zbytečně dlouho v monitoringu.
  • Staging a produkce se rozcházejí: Různí hostitelé CDN, API nebo WebSocket se zviditelní až po spuštění ostrého provozu.

Ani úzký script-src nedělá z povoleného dodavatele třetí strany automaticky bezpečný prvek: Jeho JavaScript běží s možnostmi, které mu vaše stránka dává. Prověřujte proto změny dodavatele, nové subdomény a aktualizace loaderu jako jiné závislosti s dopadem na bezpečnost. Článek o ochraně před Prompt Injection doplňuje tuto hranici prohlížeče o pravidla pro RAG, nástroje a data.

Kontrolní seznam před spuštěním (Go-live)

  • Jsou všechny potřebné originy zdokumentované z reálných relací prohlížeče a věcně zdůvodněné?
  • Povoluje script-src pouze loader a kontrolované skripty bez plošného 'unsafe-inline'?
  • Obsahuje connect-src přesné HTTPS, EventSource a případně WSS originy?
  • Jsou zdroje obrázků, stylů, fontů, rámců a workerů oddělené a definované co nejúžeji?
  • Generují se hodnoty nonce nově pro každou odpověď a nastavují se pouze na důvěryhodné prvky?
  • Byla otestována změna souhlasu, dlouhé streamy, obrázky, chyby, handoff i desktopová a mobilní zařízení?
  • Byla politika nejprve sledována v režimu Report-Only a poté vynucena jako hlavička?
  • Zpracovávají se zprávy CSP bez zbytečných osobních nebo důvěrných dat v URL?
  • Existuje po aktualizaci widgetu nebo infrastruktury automatizovaný regresní test?

Závěr

Dobrá CSP pro webové chatboty není sbírkou výjimek, ale technickou mapou povolených cest v prohlížeči. Oddělte loader, API, streamování, obrázky a zdroje iframe, povolte přesné originy a zaveďte politiku nejprve v režimu Report-Only. Widget tak zůstane funkční, zatímco neočekávané skripty a připojení získají výrazně méně prostoru.

Zdroje

Přeměňte návštěvy webu na lepší konverzace

Spusťte AI chatbota, který je užitečný od prvního dne

Naučte ChatReact z vašich stránek, dokumentů a ověřených faktů, aby návštěvníci dostávali rychlejší odpovědi a váš tým řešil méně opakujících se dotazů.

Související články

Pokračovat ve čtení