Content Security Policy pentru chatboturi pe website: Permiterea în siguranță a widget-ului, API-ului, imaginilor și streaming-ului
O politică CSP practică pentru chatboturile pe website permite doar scripturile, conexiunile API, fluxurile de streaming și imaginile absolut necesare - fără wildcard-uri inutile.

Un chatbot pe un site web este rareori alcătuit în browser doar dintr-un singur fișier JavaScript. Un loader deschide widget-ul, un API preia mesajele, răspunsurile vin ca un flux continuu (stream), iar imaginile de profil sau fișierele media pot fi găzduite pe un alt domeniu. O politică Content Security Policy (CSP) face aceste trasee vizibile și le limitează: browserul încarcă sau conectează doar ceea ce site-ul web permite în mod explicit.
Acesta este un al doilea nivel important de protecție împotriva atacurilor de tip Cross-Site Scripting și a conținutului neașteptat de la terți. Cu toate acestea, un CSP nu remediază un API nesecurizat, lipsa autentificării, o validare necorespunzătoare a datelor de intrare sau un atac de tip Prompt Injection. El reduce posibilitățile de executare a codului injectat și limitează raza de acțiune a unei erori. Prin urmare, decisivă este o politică cât mai restrânsă și testată, în locul unei liste lungi de domenii autorizate la modul general.
De ce widget-urile de chatbot au nevoie de reguli CSP speciale
În cazul unei pagini clasice de conținut, resursele provenite din propria origine (same-origin) sunt adesea suficiente. În schimb, un chatbot continuă să comunice după încărcare. Directiva connect-src controlează, printre altele, fetch(), XMLHttpRequest, EventSource, WebSocket și sendBeacon(). Exact aici circulă mesajele, răspunsurile de streaming, evenimentele de feedback și, dacă este cazul, datele de telemetrie. Dacă originea corectă lipsește, widget-ul va fi afișat, dar nu va putea răspunde.
Alte componente intră sub incidența unor directive specifice. script-src decide asupra loader-ului de widget, img-src asupra avatarelor și imaginilor din răspunsuri, style-src asupra foilor de stil (stylesheets) și font-src asupra fonturilor externe. Un widget bazat pe iframe necesită în plus frame-src. Directiva default-src servește ca soluție de rezervă (fallback) pentru multe tipuri de resurse nemenționate explicit, dar nu înlocuiește o inventariere conștientă.
Prin urmare, cel mai important pas pregătitor nu are loc într-un generator CSP, ci în browser: deschideți o pagină reprezentativă, inițiați o conversație, lăsați un răspuns lung să fie transmis prin streaming, deschideți sursele, trimiteți feedback și testați cazurile de eroare sau de transfer către un operator uman (handoff). În panoul de rețea (Network) veți vedea originile apelate efectiv. Documentați pentru fiecare host scopul, tipul de resursă și o persoană responsabilă.
Aprobarea separată a celor patru căi de date relevante
1. Scriptul widget-ului și inițializarea
Obțineți loader-ul, pe cât posibil, de la o adresă stabilă și versionată. O permisiune de tipul script-src https: ar fi prea permisivă, deoarece ar autoriza scripturi de pe orice domeniu HTTPS. În schimb, permiteți originea exactă a CDN-ului sau livrați loader-ul direct de pe serverul propriu. Dacă integrarea necesită cod inline, utilizați un nonce nou generat pentru fiecare răspuns HTTP sau un hash corespunzător. Utilizarea 'unsafe-inline' nu ar trebui să devină o soluție permanentă de avarie.
Un nonce trebuie aplicat doar scripturilor pe care le generează șablonul de pe server. Un middleware care adaugă orbește același nonce fiecărui tag de script existent va acorda încredere și tag-urilor injectate rău intenționat. Pentru un script terț static și versionat, Subresource Integrity poate oferi un ajutor suplimentar; totuși, în cazul fișierelor care se modifică frecvent, hash-ul trebuie actualizat în mod controlat.
2. API, Server-Sent Events și WebSocket
Cerările normale POST și un răspuns transmis prin streaming via fetch() necesită originea API-ului HTTPS în connect-src. EventSource pentru Server-Sent Events se încadrează, de asemenea, aici. Pentru un WebSocket, adăugați în mod explicit originea concretă wss://. MDN atrage atenția că 'self' nu include automat schemele WebSocket în toate browserele. Nu există o directivă separată numită stream-src.
CSP și CORS rezolvă sarcini diferite. CSP stabilește unde anume are voie pagina să se conecteze; CORS stabilește la nivel de server ce origini au voie să citească un răspuns în browser. Prin urmare, o permisiune CSP nu rezolvă nici o eroare CORS și nici un token de acces expirat. Un proxy Same-Origin poate simplifica politica, dar trebuie să gestioneze în continuare corect autentificarea, limitele de rată (rate limits), depășirile de timp (timeouts) și transmiterea erorilor.
3. Imagini, avatare și conținut media generat
Permiteți în img-src doar propria origine și originea fișierelor media utilizate efectiv. Directiva data: este necesară numai dacă widget-ul folosește imagini mici încorporate; blob: este necesar doar dacă browserul generează imagini sub formă de URL-uri Blob. Fiecare sursă suplimentară mărește suprafața de atac. Dacă o imagine este mai întâi încărcată prin fetch() și apoi convertită într-un URL Blob, pot fi afectate atât connect-src, cât și img-src.
Testați nu doar avatarul standard. Verificați imaginile de previzualizare, capturile de ecran ale surselor, atașamentele, modul întunecat (dark mode) și afișarea erorilor pentru fișierele media indisponibile. Parametrii din URL pot purta informații confidențiale în rapoartele CSP; prin urmare, punctele finale de raportare (reporting endpoints) ar trebui să proceseze rapoartele cu economie de date și să nu le stocheze pe termen nelimitat.
4. iframe, stiluri, fonturi și workeri opționali
Un widget integrat direct în DOM nu are nevoie, de regulă, de un frame extern. În acest caz, frame-src 'none' poate fi păstrat. Dacă chatul rulează totuși într-un iframe, permiteți exclusiv originea exactă a acestuia. A nu se confunda cu frame-ancestors: această directivă stabilește pe resursa livrată ce pagini au voie să o încorporeze. Prin urmare, furnizorul de widget trebuie să o configureze corespunzător în răspunsul său iframe.
Același principiu se aplică stilurilor și fonturilor. Permiteți hosturi concrete și evitați 'unsafe-inline', în măsura în care integrarea permite acest lucru. Workerii sau funcțiile audio se adaugă doar dacă produsul le folosește cu adevărat. Permiterea preventivă a blob:, a unor domenii întregi cu wildcard-uri sau a surselor media arbitrare îngreunează auditurile ulterioare.
Un exemplu realist de CSP pentru un widget de chatbot
Următoarele domenii sunt domenii de exemplu rezervate intenționat. Înlocuiți-le cu originile identificate în propria analiză de rețea. Exemplul presupune un loader extern, un API HTTPS, un WebSocket separat pentru streaming și un host media. Nu utilizează wildcard-uri generale:
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} reprezintă o valoare criptografică puternică, generată din nou pentru fiecare răspuns, care este identică în header și în elementele script sau style permise. Dacă widget-ul dvs. utilizează un iframe, înlocuiți frame-src 'none' cu originea exactă a widget-ului. Dacă folosește exclusiv streaming HTTPS prin fetch() sau EventSource, originea WebSocket poate fi eliminată. Ștergeți orice sursă care nu este necesară după un test funcțional complet.
Politica prezentată este un punct de plecare practic, nu un șablon universal. Un CSP strict și modern poate controla scripturile și mai puternic prin nonce-uri sau hash-uri și 'strict-dynamic'. Dacă acest lucru este posibil fără probleme de compatibilitate depinde de modul în care loader-ul generează alte scripturi. Clarificați acest flux cu furnizorul și testați browserele, modul de consimțământ (Consent Mode) și variantele de deployment.
De la modul Report-Only la o politică aplicată strict
Nu activați o politică nouă în mod direct în producție fără a o verifica în prealabil. Mecanismul W3C Content-Security-Policy-Report-Only raportează încălcările fără a bloca resursele. Astfel, puteți identifica hosturile de imagini omise, o origine de streaming diferită sau codul inline înainte ca utilizatorii să fie afectați. OWASP recomandă header-ul HTTP ca cale preferată de livrare; spre deosebire de elementul meta, acesta suportă setul complet de funcționalități.
- Creați un inventar: Testați pornirea widget-ului, primul mesaj, un răspuns lung prin streaming, sursele, imaginile, feedback-ul, transferul la un operator uman și schimbarea consimțământului pe mai multe tipuri de pagini.
- Implementați modul Report-Only: Începeți cu politica restrânsă planificată și colectați încălcările într-o perioadă definită. Filtrați extinderile de browser și alte semnale parazite ne-reproducibile.
- Justificați fiecare host: Extindeți politica doar dacă o funcționalitate concretă a produsului necesită originea respectivă. Evitați utilizarea wildcard-urilor ca reacție la rapoarte izolate.
- Testați automatizat: Adăugați teste End-to-End care trimit un mesaj, așteaptă streaming-ul și încarcă o imagine. Verificați concomitent consola browserului pentru încălcări CSP.
- Aplicați strict și monitorizați: Activați header-ul
Content-Security-Policy, mențineți în paralel o variantă Report-Only și mai strictă și comparați ratele de eroare.
O lansare treptată se potrivește foarte bine cu un chatbot în Shadow Mode. Pentru metrici specifice streaming-ului, vă recomandăm articolul despre bugetele de latență și time-out-uri. Încălcările CSP ar trebui tratate ca un semnal separat: un time-out și o conexiune blocată necesită analize diferite ale cauzelor.
Greșeli tipice de configurare
- Liste de surse prea largi:
*,https:sau domenii mari de tip wildcard fac politica facilă, dar slabă și greu de auditat. - Se testează doar pornirea vizibilă: Widget-ul se deschide, dar streaming-ul, feedback-ul, imaginile sau transferul eșuează ulterior.
'unsafe-inline'rămâne permanent: O soluție temporară de compatibilitate nu este înlocuită de nonce-uri, hash-uri sau cod extern.- CSP este confundat cu controlul accesului: Politica nu înlocuiește drepturile de acces de pe server, verificarea sesiunilor sau protecția împotriva apelurilor abuzive de unelte.
- Rapoartele conțin prea multe date: URL-uri complete, parametri de interogare (query parameters) sau contextul utilizatorului ajung inutil în sistemele de monitorizare.
- Mediul de Staging și Producția diferă: Hosturi diferite de CDN, API sau WebSocket devin vizibile abia după lansarea oficială.
Nici măcar o directivă script-src restrânsă nu face un terț autorizat în mod automat sigur: codul său JavaScript rulează cu toate permisiunile pe care i le oferă pagina dvs. Prin urmare, verificați schimbarea furnizorilor, subdomeniile noi și actualizările de loader la fel ca pe orice altă dependență critică pentru securitate. Articolul despre protecția împotriva Prompt Injection completează această barieră din browser cu reguli pentru RAG, unelte și date.
Lista de verificare înainte de lansare
- Sunt toate originile necesare documentate și justificate tehnic pe baza unor sesiuni reale de browser?
- Permite
script-srcdoar loader-ul și scripturile controlate, fără'unsafe-inline'generalizat? - Conține
connect-srcoriginile exacte HTTPS, EventSource și, dacă este cazul, WSS? - Sunt sursele pentru imagini, stiluri, fonturi, frame-uri și workeri separate și definite cât mai restrâns posibil?
- Sunt nonce-urile generate din nou pentru fiecare răspuns și aplicate doar elementelor de încredere?
- Au fost testate schimbările de consimțământ, fluxurile lungi de streaming, imaginile, erorile, transferul la operator, precum și dispozitivele desktop și mobile?
- A fost politica monitorizată mai întâi în modul Report-Only și aplicată ulterior ca header obligatoriu?
- Sunt rapoartele CSP procesate fără date cu caracter personal sau URL-uri confidențiale inutile?
- Există un test de regresie automatizat după actualizările widget-ului sau ale infrastructurii?
Concluzie
Un CSP bun pentru chatboturile de pe site-uri web nu este o colecție de excepții, ci o hartă tehnică a traseelor permise în browser. Separați resursele de loader, API, streaming, imagini și iframe, permiteți origini exacte și introduceți politica mai întâi în modul Report-Only. În acest fel, widget-ul rămâne complet funcțional, în timp ce scripturile și conexiunile neașteptate primesc un spațiu de manevră mult mai redus.
Surse
Transformați vizitele pe site în conversații mai bune
Lansați un chatbot AI util din prima zi
Antrenați ChatReact cu site-ul dvs., documente și fapte aprobate, astfel încât vizitatorii să obțină răspunsuri mai rapide, iar echipa dvs. să primească mai puține solicitări repetitive.
Articole conexe
Continuă lectura
Cum să adăugați un chatbot AI pe un site fără a afecta UX-ul sau SEO-ul
Un plan de implementare pentru adăugarea unui chatbot pe site-ul dumneavoastră, menținând în același timp parcursul utilizatorului, viteza paginii și structura conținutului în stare bună.

Optimizarea timpului de răspuns al unui chatbot AI: buget de latență, streaming și timeout-uri
Răspunsurile rapide ale unui chatbot se construiesc pe parcursul întregului lanț tehnic. Aflați cum să planificați bugetele de latență, streaming-ul, timeout-urile, reîncercările și fallback-urile sigure.

Testarea unui chatbot IA în Shadow Mode: Trecerea sigură de la prototip la lansarea pe site
Utilizând Shadow Mode, porți clare de calitate și o lansare treptată, echipele de dezvoltare web testează chatbot-urile IA în siguranță înainte de lansarea în producție.