Torna al blog
Implementazione20 agosto 202610 min di letturaAggiornato 30 agosto 2026

Content Security Policy per chatbot su siti web: sbloccare in sicurezza widget, API, immagini e streaming

Una CSP efficace per chatbot su siti web consente solo gli script, le connessioni API, gli stream e le immagini realmente necessari - senza wildcard superflue.

Una qualificata tecnica del suono e dell'illuminazione controlla un modulo di connessione protetto per un widget chatbot su un palco all'aperto estivo.

Un chatbot per siti web raramente si compone di un solo file JavaScript all'interno del browser. Un loader apre il widget, un'API riceve i messaggi, le risposte arrivano tramite streaming e le immagini del profilo o i contenuti multimediali potrebbero risiedere su un altro dominio. Una Content Security Policy (CSP) rende visibili questi percorsi e li limita: il browser carica o si connette solo a ciò che il sito web autorizza esplicitamente.

Si tratta di un secondo livello di protezione fondamentale contro gli attacchi Cross-Site Scripting e l'inclusione di contenuti terzi non previsti. Tuttavia, una CSP non risolve i problemi di un'API non sicura, un'autenticazione mancante, una validazione dell'input carente o le minacce di Prompt Injection. Riduce semplicemente le possibilità di esecuzione di codice malevolo e limita il raggio d'azione di un errore. È quindi fondamentale definire una policy il più circoscritta possibile e già testata, anziché ricorrere a un lungo elenco di domini autorizzati in blocco.

Perché i widget dei chatbot richiedono regole CSP specifiche

In una classica pagina di contenuti statici, le risorse provenienti dall'origine del sito sono spesso sufficienti. Un chatbot, al contrario, continua a comunicare anche dopo il caricamento iniziale. La direttiva connect-src controlla, tra le altre cose, fetch(), XMLHttpRequest, EventSource, WebSocket e sendBeacon(). È proprio qui che transitano i messaggi, le risposte in streaming, gli eventi di feedback e l'eventuale telemetria. Se l'origine corretta non viene specificata, il widget apparirà sullo schermo ma non sarà in grado di rispondere.

Gli altri componenti rientrano in direttive dedicate. script-src determina l'esecuzione del loader del widget, img-src gestisce gli avatar e le immagini delle risposte, style-src controlla i fogli di stile e font-src i font esterni. Un widget basato su iframe necessita inoltre di frame-src. La direttiva default-src funge da ripiego per molti tipi di risorse non espressamente indicati, ma non sostituisce un'inventariazione consapevole.

Il lavoro preparatorio più importante non si svolge quindi in un generatore di CSP, bensì nel browser: aprite una pagina rappresentativa, avviate una conversazione, lasciate che venga inviata una risposta lunga in streaming, consultate le fonti, inviate un feedback e testate sia i casi di errore sia quelli di handoff all'operatore. Nel pannello Rete degli strumenti per sviluppatori potrete identificare le origini effettivamente interpellate. Documentate per ciascun host lo scopo, il tipo di risorsa e la persona responsabile.

Autorizzare distintamente i quattro percorsi dati principali

1. Script del widget e inizializzazione

Ottenete il loader preferibilmente da un indirizzo stabile e con versione definita. Un'autorizzazione generica come script-src https: risulterebbe troppo ampia, poiché consentirebbe l'esecuzione di script da qualsiasi dominio HTTPS. Autorizzate invece l'origine esatta della CDN o distribuite direttamente il loader dal vostro server. Se l'integrazione richiede codice inline, utilizzate un nonce generato ex novo per ciascuna risposta HTTP o un hash idoneo. L'uso di 'unsafe-inline' non dovrebbe diventare una soluzione permanente.

Un nonce va applicato esclusivamente agli script generati dal template lato server. Un middleware che aggiunga ciechamente lo stesso nonce a ogni tag script presente finirebbe per dare fiducia anche a tag iniettati da terzi. Per uno script esterno statico e con versione specifica, la Subresource Integrity può offrire un'ulteriore garanzia; tuttavia, in caso di file soggetti a modifiche frequenti, l'hash deve essere aggiornato tempestivamente.

2. API, Server-Sent Events e WebSocket

Le normali richieste POST e le risposte in streaming tramite fetch() richiedono l'inserimento dell'origine HTTPS dell'API nella direttiva connect-src. Anche i Server-Sent Events gestiti tramite EventSource rientrano in questo ambito. Nel caso di un WebSocket, è necessario specificare esplicitamente l'origine wss:// corrispondente. MDN evidenzia che la direttiva 'self' non include automaticamente gli schemi WebSocket in tutti i browser. Non esiste una direttiva specifica denominata stream-src.

CSP e CORS rispondono a esigenze distinte. La CSP stabilisce verso quali destinazioni la pagina può effettuare connessioni; CORS determina lato server quali origini sono autorizzate a leggere la risposta all'interno del browser. Pertanto, un'autorizzazione in CSP non risolve né un errore CORS né un token di accesso scaduto. Un proxy same-origin può semplificare la policy, ma deve continuare a gestire in modo corretto autenticazione, rate limit, timeout e propagazione degli errori.

3. Immagini, avatar e contenuti multimediali generati

Autorizzate in img-src unicamente la propria origine e l'origine dei contenuti multimediali effettivamente utilizzata. L'uso di data: è necessario soltanto se il widget impiega piccole immagini incorporate; blob: serve solo se il browser genera direttamente le immagini come URL blob. Ogni fonte aggiuntiva amplia la superficie di attacco. Se un'immagine viene prima scaricata tramite fetch() e poi convertita in un URL blob, potrebbero essere interessate sia la direttiva connect-src sia img-src.

Non limitatevi a testare l'avatar predefinito. Verificate le anteprime delle immagini, gli screenshot delle fonti, gli allegati, la modalità scura e la visualizzazione degli errori per i media non disponibili. I parametri URL possono veicolare informazioni riservate all'interno dei report CSP; gli endpoint di reportistica dovrebbero pertanto elaborare le segnalazioni applicando il principio della minimizzazione dei dati ed evitarne la conservazione illimitata.

4. iframe, stili, font e worker opzionali

Un widget integrato direttamente nel DOM di norma non richiede un frame esterno. In questo caso è possibile mantenere frame-src 'none'. Se invece la chat viene eseguita all'interno di un iframe, autorizzate esclusivamente la sua origine esatta. Da non confondere con questa è la direttiva frame-ancestors: quest'ultima stabilisce, sulla risorsa erogata, quali pagine sono autorizzate a incorporarla. Il fornitore del widget deve pertanto impostarla correttamente sulla risposta del proprio iframe.

Il medesimo principio si applica a stili e font. Autorizzate host specifici ed evitate 'unsafe-inline', nella misura in cui l'integrazione lo consenta. L'inclusione di worker o funzionalità audio deve avvenire solo se il prodotto li utilizza realmente. Un'autorizzazione preventiva di blob:, di interi domini wildcard o di fonti multimediali generiche complica le successive attività di audit.

Un esempio pratico di CSP per un widget chatbot

I domini indicati di seguito sono espressamente domini di esempio riservati. Sostituiteli con le origini emersa dalla vostra analisi di rete. L'esempio presuppone l'uso di un loader esterno, un'API HTTPS, un WebSocket separato per lo streaming e un host multimediale dedicato, senza ricorrere a wildcard generiche:

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} rappresenta un valore crittograficamente solido, generato ex novo per ciascuna risposta, che deve risultare identico sia nell'intestazione sia negli elementi script o style autorizzati. Se il widget utilizza un iframe, sostituite frame-src 'none' con l'origine esatta del widget. Se impiega esclusivamente lo streaming HTTPS tramite fetch() o EventSource, l'origine WebSocket può essere omessa. Rimuovete qualsiasi fonte che non risulti strettamente necessaria dopo un test funzionale completo.

La policy rappresenta un punto di partenza operativo, non un modello universale. Una CSP rigorosa e moderna può controllare gli script in modo ancora più stringente tramite nonce o hash e l'uso di 'strict-dynamic'. La fattibilità di questo approccio senza problemi di compatibilità dipende da come il loader genera gli script successivi. Chiarite questo flusso con il fornitore e verificate il comportamento nei diversi browser, con le impostazioni del banner di consenso e nelle varie modalità di deployment.

Dalla modalità Report-Only all'applicazione effettiva della policy

Non attivate una nuova policy in produzione senza averla prima verificata. Il meccanismo W3C Content-Security-Policy-Report-Only segnala le violazioni senza bloccare il caricamento delle risorse. Ciò consente di individuare host di immagini dimenticati, un'origine di streaming differente o codice inline non previsto prima che gli utenti ne risentano. OWASP raccomanda l'intestazione HTTP come canale di erogazione preferenziale, poiché, a differenza del tag meta, supporta l'insieme completo delle funzionalità.

  1. Creare l'inventario: testate l'avvio del widget, il primo messaggio, le risposte lunghe in streaming, le fonti, le immagini, i feedback, l'handoff e i cambi di consenso su diverse tipologie di pagine.
  2. Implementare Report-Only: iniziate applicando la policy restrittiva pianificata e raccogliete le violazioni riscontrate in un arco temporale definito. Filtrate le interferenze dovute a estensioni del browser o ad altri segnali non riproducibili.
  3. Giustificare ogni host: ampliate la policy solo se una specifica funzionalità del prodotto richiede effettivamente l'origine segnalata. Evitate di aggiungere wildcard per rispondere a singole segnalazioni isolated.
  4. Eseguire test automatizzati: integrate test end-to-end che inviino un messaggio, attendano lo streaming completo e carichino un'immagine. Contestualmente, monitorate la console del browser per rilevare eventuali violazioni della CSP.
  5. Applicare la policy e monitorare: attivate l'header Content-Security-Policy, mantenendo parallelamente sotto controllo una versione Report-Only ancora più restrittiva per confrontare i tassi di errore.

Un rollout graduale si adatta perfettamente a un chatbot in Shadow Mode. Per le metriche specifiche relative allo streaming, si rimanda all'articolo sui budget di latenza e timeout. Le violazioni della CSP dovrebbero essere considerate un segnale a sé stante: un timeout e una connessione bloccata richiedono infatti analisi delle cause differenti.

Errori di configurazione frequenti

  • Elenchi di origini troppo ampi: l'uso di *, https: o di estesi domini con wildcard rende la policy comoda da gestire, ma debole e difficile da verificare.
  • Test limitati all'avvio visibile: il widget si apre correttamente, ma lo streaming, i feedback, le immagini o l'handoff falliscono nelle fasi successive.
  • Adozione permanente di 'unsafe-inline': una misura temporanea per la compatibilità non viene successivamente sostituita da nonce, hash o codice esterno.
  • Confusione tra CSP e controllo degli accessi: la policy non sostituisce i permessi lato server, la verifica delle sessioni o la protezione da chiamate improprie agli strumenti.
  • Report contenenti dati eccessivi: URL completi, parametri di query o contesti utente vengono salvati nei sistemi di monitoraggio per periodi inutilmente lunghi.
  • Disallineamento tra staging e produzione: la presenza di host differenti per CDN, API o WebSocket diventa visibile solo dopo il go-live.

Anche una direttiva script-src restrittiva non rende automaticamente sicuro un terzo autorizzato: il suo codice JavaScript verrà eseguito con tutti i permessi concessi dalla pagina. Valutate pertanto i cambi di fornitore, i nuovi sottodomini e gli aggiornamenti del loader al pari di qualsiasi altra dipendenza critica per la sicurezza. L'articolo sulla protezione dalla Prompt Injection integra questo perimetro di sicurezza del browser con regole dedicate a RAG, strumenti e dati.

Checklist prima del go-live

  • Tutte le origini necessarie sono state documentate a partire da sessioni di navigazione reali e giustificate dal punto di vista funzionale?
  • La direttiva script-src autorizza solo il loader e script controllati, senza ricorrere a 'unsafe-inline' generici?
  • La direttiva connect-src include le origini HTTPS, EventSource e, se necessario, WSS esatte?
  • Le origini per immagini, stili, font, frame e worker sono distinte e definite nel modo più restrittivo possibile?
  • I nonce vengono generati ex novo per ogni risposta e applicati solo ad elementi affidabili?
  • Sono stati testati i cambi di consenso, i flussi di streaming lunghi, le immagini, la gestione degli errori, l'handoff sia su desktop sia su dispositivi mobili?
  • La policy è stata prima monitorata in modalità Report-Only e poi applicata tramite header?
  • I report CSP vengono elaborati senza includere dati personali o parametri URL riservati non necessari?
  • È previsto un test di regressione automatizzato a seguito di aggiornamenti del widget o dell'infrastruttura?

Conclusione

Una CSP ben strutturata per i chatbot su siti web non è un insieme di eccezioni, ma una vera e propria mappa tecnica dei percorsi consentiti all'interno del browser. Distinguendo le risorse per loader, API, streaming, immagini e iframe, autorizzando origini puntuali e introducendo la policy prima in modalità Report-Only, il widget rimarrà perfettamente funzionale, riducendo al contempo in modo significativo lo spazio di manovra per script e connessioni non autorizzati.

Fonti

Trasforma le visite al sito in conversazioni migliori

Lancia un chatbot AI utile fin dal primo giorno

Addestra ChatReact con il tuo sito, i documenti e i fatti approvati in modo che i visitatori ottengano risposte più rapide e il tuo team riceva meno richieste ripetitive.

Articoli correlati

Continua la lettura