Vissza a bloghoz
Megvalósítás2026. augusztus 20.9 perc olvasásFrissítve 2026. augusztus 30.

Content Security Policy weboldal chatbotokhoz: Widget, API, képek és streaming biztonságos engedélyezése

A weboldal chatbotokhoz készült, a gyakorlatban is jól működő CSP csak a valóban szükséges szkripteket, API-kapcsolatokat, streameket és képeket engedélyezi – felesleges dzsóker karakterek (wildcards) nélkül.

Egy felnőtt rendezvénytechnikus egy nyári szabadtéri színpadon ellenőriz egy biztosított csatlakozómodult egy chatbot widgethez.

Egy weboldal chatbot ritkán áll csupán egyetlen JavaScript-fájlból a böngészőben. Egy betöltő (loader) nyitja meg a widgetet, egy API fogadja az üzeneteket, a válaszok streamként érkeznek vissza, a profilképek vagy egyéb médiatartalmak pedig esetleg egy további domainen találhatók. A Content Security Policy (CSP) láthatóvá teszi és korlátozza ezeket az útvonalakat: a böngésző csak azt tölti be vagy ahhoz csatlakozik, amit a weboldal kifejezetten engedélyez.

Ez egy fontos második védelmi vonal a Cross-Site Scripting (XSS) és a váratlan harmadik féltől származó tartalmak ellen. A CSP azonban nem javítja ki sem a nem biztonságos API-t, sem a hiányzó hitelesítést, a hiányos bemenet-ellenőrzést vagy a prompt injection sérülékenységeket. Csökkenti az beékelődött kód lehetőségeit, és korlátozza a hibák hatósugarát. Ezért döntő fontosságú a lehető legkisebb, tesztelt szabályzat (policy) alkalmazása a túl általánosan engedélyezett domainek hosszú listája helyett.

Miért van szükségük a chatbot widgeteknek speciális CSP-szabályokra?

Egy klasszikus tartalmi oldal esetében gyakran elegendőek a saját eredetből (origin) származó erőforrások. Ezzel szemben a chatbot a betöltés után is folytatja a kommunikációt. A connect-src szabályozza többek között a fetch(), XMLHttpRequest, EventSource, WebSocket és sendBeacon() hívásokat. Pontosan itt zajlik az üzenetváltás, a válaszok streamingje, a visszajelzések küldése és adott esetben a telemetria. Ha hiányzik a megfelelő origin, a widget ugyan megjelenik, de nem tud válaszolni.

A többi összetevő külön direktívák alá tartozik. A script-src dönt a widget loaderéről, az img-src az avatárokról és a válaszképekről, a style-src a stíluslapokról, a font-src pedig a külső betűtípusokról. Egy iframe-alapú widgetnek ezenfelül a frame-src direktívára is szüksége van. A default-src tartalékként szolgál a sok kifejezetten nem megnevezett erőforrástípushoz, de nem helyettesíti a tudatos leltározást.

A legfontosabb előkészítő munka ezért nem a CSP-generátorban történik, hanem a böngészőben: nyisson meg egy reprezentatív oldalt, indítson beszélgetést, streameljen egy hosszú választ, nyissa meg a forrásokat, küldjön visszajelzést, és tesztelje a hiba- és átadási (handoff) eseteket. A Hálózat (Network) panelen láthatja a ténylegesen megszólított origineket. Dokumentálja minden host esetében a célt, az erőforrás típusát és a felelős személyt.

A négy releváns adatútvonal külön-külön történő engedélyezése

1. Widget-szkript és inicializálás

A loadert lehetőség szerint stabil, verziózott címről szerezze be. Egy olyan engedélyezés, mint a script-src https: túl tág lenne, mert ezzel bármilyen HTTPS-domainről származó szkript megengedetté válna. Ehelyett engedélyezze a pontos CDN-origint, vagy szolgáltassa ki saját maga a loadert. Ha az integrációnak inline kódra van szüksége, használjon minden HTTP-válasznál újonnan generált nonce-ot vagy egy megfelelő hasht. Az 'unsafe-inline' nem válhat gyors, tartós megoldássá.

Nonce csak olyan szkriptekhez tartozzon, amelyeket a szerveroldali sablon maga hoz létre. Egy olyan middleware, amely vakon minden meglévő script-címkéhez ugyanazt a nonce-ot adja hozzá, a beékelődött címkékben is megbízna. Egy statikus, verziózott külső szkriptnél a Subresource Integrity (SRI) is segíthet; gyakran változó fájloknál azonban a hasht ellenőrzötten frissíteni kell.

2. API, Server-Sent Events és WebSocket

A normál POST-kéréseknek és a fetch() funkción keresztül streamelt válaszoknak szükségük van a HTTPS API originre a connect-src-ben. Az EventSource-on keresztüli Server-Sent Events szintén ide tartozik. WebSocket esetén kifejezetten adja meg a konkrét wss://-origint. Az MDN rámutat arra, hogy a 'self' nem minden böngészőben foglalja magában automatikusan a WebSocket-sémákat. Önálló stream-src nevű direktíva nem létezik.

A CSP és a CORS eltérő feladatokat oldanak meg. A CSP határozza meg, hogy az oldal egyáltalán hová csatlakozhat; a CORS szerveroldalon határozza meg, hogy mely originek olvashatják a választ a böngészőben. Egy CSP-engedélyezés ezért nem javít ki sem egy CORS-hibát, sem egy lejárt hozzáférési tokent. Egy Same-Origin proxy egyszerűsítheti a szabályzatot, de a hitelesítést, a rate limiteket, az időtúllépéseket és a hibák továbbítását továbbra is megfelelően kell kezelnie.

3. Képek, avatárok és generált médiatartalmak

Az img-src-ben csak a saját origint és a ténylegesen használt média-origint engedélyezze. A data: használata csak akkor szükséges, ha a widget kis beágyazott képeket használ; a blob: pedig csak akkor, ha a böngésző a képeket valóban Blob-URL-ként hozza létre. Minden további forrás növeli a támadási felületet. Ha egy képet először a fetch() segítségével töltenek be, majd Blob-URL-lé alakítanak át, mind a connect-src, mind az img-src érintett lehet.

Ne csak az alapértelmezett avatárt tesztelje. Ellenőrizze az előnézeti képeket, a források képernyőfotóit, a fájlmellékleteket, a sötét módot és a nem elérhető médiatartalmak hibamegjelenítését. Az URL-paraméterek bizalmas információkat vihetnek a CSP-jelentésekbe; a jelentési végpontoknak ezért az adatminimalizálás elvét követve kell feldolgozniuk a jelentéseket, és nem szabad korlátlanul megőrizniük azokat.

4. iframe, stílusok, betűtípusok és opcionális workerek

Egy közvetlenül a DOM-ba beágyazott widgetnek általában nincs szüksége idegen frame-re. Ilyenkor a frame-src 'none' maradhat. Ha viszont a chat egy iframe-ben fut, kizárólag annak a pontos originjét engedélyezze. Ettől megkülönböztetendő a frame-ancestors: ez a direktíva a kiszolgált erőforráson határozza meg, hogy mely oldalak ágyazhatják be azt. A widget szolgáltatójának ezért ezt megfelelően be kell állítania az iframe-válaszán.

A stílusok és betűtípusok esetében ugyanez az elv érvényes. Engedélyezzen konkrét hostokat, és kerülje az 'unsafe-inline'-t, amennyire az integráció ezt lehetővé teszi. Workerek vagy funkciók csak akkor adódnak hozzá, ha a termék valóban használja őket. A blob:, az egész dzsóker domainek vagy a tetszőleges médiaforrások elővigyázatosságból történő engedélyezése megnehezíti a későbbi auditokat.

Egy realisztikus CSP-példa chatbot widgethez

A következő domainek szándékosan lefoglalt példadomainek. Cserélje ki őket a saját hálózati elemzéséből származó originekkel. A példa egy külső loadert, egy HTTPS API-t, egy különálló WebSocketet a streaminghez és egy médiahostot feltételez. Nem használ általános dzsóker karaktereket:

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;

A {RANDOM} egy erős, válaszonként újonnan generált értéket jelöl, amely a fejlécben és az engedélyezett script-, illetve style-elemeken azonos. Ha a widgete iframe-et használ, cserélje ki a frame-src 'none' értéket a pontos widget-originre. Ha kizárólag fetch() vagy EventSource segítségével történő HTTPS-streaminget használ, a WebSocket-origin elhagyható. Távolítson el minden olyan forrást, amelyre egy teljes funkcionális teszt után nincs szükség.

A szabályzat egy gyakorlati kiindulópont, nem pedig univerzális sablon. Egy modern, szigorú CSP még erősebben vezérelheti a szkripteket nonce-ok vagy hashtagok és a 'strict-dynamic' segítségével. Hogy ez kompatibilitási problémák nélkül lehetséges-e, attól függ, hogyan hoz létre a loader további szkripteket. Tisztázza ezt a folyamatot a szolgáltatóval, és tesztelje a böngészőket, a hozzájárulási (consent) módot és a telepítési változatokat.

A Report-Only módtól a kikényszerített szabályzatig

Ne élesítsen egy új szabályzatot ellenőrizetlenül. A W3C Content-Security-Policy-Report-Only mechanizmusa jelenti a megsértéseket anélkül, hogy blokkolná az erőforrásokat. Így azelőtt felismerheti az elfelejtett képhostokat, az eltérő streaming-origint vagy az inline kódot, mielőtt az a felhasználókat érintené. Az OWASP a HTTP-fejlécet javasolja preferált kiszolgálási útvonalnak; a meta-elemmel ellentétben ez a teljes funkciókészletet támogatja.

  1. Leltár készítése: Tesztelje a widget indítását, az első üzenetet, a hosszú streaming-választ, a forrásokat, a képeket, a visszajelzést, a handoffot és a hozzájárulás váltását több oldaltípuson.
  2. Report-Only bevezetése: Kezdjen a tervezett szigorú szabályzattal, és gyűjtse a megsértéseket egy korlátozott időszakban. Szűrje ki a böngészőbővítményeket és más nem reprodukálható zavaró jeleket.
  3. Minden host indoklása: Csak akkor bővítse a szabályzatot, ha egy konkrét termékfunkció igényli az origint. Kerülje a dzsóker karakterek használatát egyedi jelentésekre reagálva.
  4. Automatizált tesztelés: Egészítse ki end-to-end tesztekkel, amelyek üzenetet küldenek, megvárják a streaminget és betöltenek egy képet. Ezzel párhuzamosan ellenőrizze a böngészőkonzolt a CSP-sértések szempontjából.
  5. Kikényszerítés és megfigyelés: Aktiválja a Content-Security-Policy fejlécet, tartson szem előtt párhuzamosan egy még szigorúbb Report-Only változatot, és hasonlítsa össze a hibaarányokat.

A szakaszos bevezetés jól illeszkedik egy Shadow Mode-ban működő chatbot szcenárióhoz. A streaming-specifikus mérési értékekhez a latenciakeretekről és időtúllépésekről szóló cikk nyújt segítséget. A CSP-sértéseket külön jelzésként kell kezelni: az időtúllépés és a blokkolt kapcsolat eltérő ok-okozati elemzést igényel.

Jellemző hibás konfigurációk

  • Túl tág forráslisták: A *, https: vagy a nagy dzsóker domainek kényelmessé, de gyengévé és nehezen ellenőrizhetővé teszik a szabályzatot.
  • Csak a látható indítást tesztelik: A widget megnyílik, de a streaming, a visszajelzés, a képek vagy a handoff csak később bukik el.
  • Az 'unsafe-inline' tartósan megmarad: A rövid távú kompatibilitási segédletet nem cserélik ki nonce-okra, hashtagekre vagy külső kódra.
  • A CSP-t összetévesztik a hozzáférés-vezérléssel: A szabályzat nem helyettesíti a szerveroldali jogosultságokat, a munkamenet-ellenőrzést és a visszaélésszerű eszközhívások elleni védelmet.
  • A jelentések túl sok adatot tartalmaznak: A teljes URL-ek, lekérdezési paraméterek vagy felhasználói kontextusok feleslegesen sokáig maradnak a monitorozásban.
  • A Staging és a Production eltér egymástól: A különböző CDN-, API- vagy WebSocket-hostok csak élesítés után válnak láthatóvá.

Még a szigorú script-src sem teszi automatikusan biztonságossá az engedélyezett harmadik féltől származó szolgáltatót: a JavaScriptje azokkal a lehetőségekkel fut, amelyeket az Ön oldala biztosít számára. Ezért a szolgáltatóváltást, az új aldomaineket és a loader-frissítéseket úgy ellenőrizze, mint más biztonsági szempontból releváns függőségeket. A prompt injection elleni védelemről szóló cikk kiegészíti ezt a böngészőhatárt a RAG-ra, az eszközökre és az adatokra vonatkozó szabályokkal.

Ellenőrző lista az élesítés előtt

  • Dokumentálva van és szakmailag indokolt minden szükséges origin a valódi böngészőmunkamenetekből?
  • A script-src csak a loadert és az ellenőrzött szkripteket engedélyezi, általános 'unsafe-inline' nélkül?
  • A connect-src tartalmazza a pontos HTTPS-, EventSource- és adott esetben WSS-origineket?
  • A kép-, stílus-, betűtípus-, frame- és worker-források külön-külön és a lehető legszigorúbban vannak meghatározva?
  • A nonce-ok válaszonként újonnan generálódnak, és csak a megbízható elemekhez kerülnek beállításra?
  • Tesztelték a hozzájárulási váltásokat, a hosszú streameket, a képeket, a hibákat, a handoffot, valamint a meglévő asztali és mobileszközöket?
  • A szabályzatot először Report-Only módban figyelték meg, majd fejléc formájában kikényszerítették?
  • A CSP-jelentések feldolgozása felesleges személyes vagy bizalmas URL-adatok nélkül történik?
  • Van automatizált regressziós teszt a widget- vagy infrastruktúra-frissítések után?

Összegzés

Egy jó CSP a weboldal chatbotokhoz nem kivételek gyűjteménye, hanem az engedélyezett böngészőutak technikai térképe. Válassza külön a loader, az API, a streaming, a képek és az iframe-erőforrásokat, engedélyezzen pontos origineket, és a szabályzatot először Report-Only módban vezesse be. Így a widget működőképes marad, miközben a váratlan szkriptek és kapcsolatok lényegesen kisebb mozgásteret kapnak.

Források

Alakítsa át a weboldallátogatásokat jobb beszélgetésekké

Indítson olyan AI-chatbotot, amely az első naptól hasznos

Oktassa a ChatReactet a weboldalával, dokumentumaival és jóváhagyott tényekkel, hogy a látogatók gyorsabb válaszokat kapjanak, és csökkenjen a csapata ismétlődő kéréseinek száma.

Kapcsolódó cikkek

Olvasson tovább