Обратно в блога
Имплементация20 август 2026 г.9 мин четенеАктуализирано 30 август 2026 г.

Content Security Policy за уебсайт чатботове: Безопасно разрешаване на Widget, API, изображения и Streaming

Практичната CSP за уебсайт чатботове разрешава само наистина необходимите скриптове, API връзки, стриймове и изображения - без излишни заместващи знаци (wildcards).

Възрастна сценична техника на лятна сцена на открито проверява защитен свързващ модул за чатбот уиджет.

Уебсайт чатботът в браузъра рядко се състои само от един JavaScript файл. Зареждащият модул (loader) отваря уиджета, API приема съобщенията, отговорите се връщат като стрийм, а профилните изображения или медиите може да се намират на друг домейн. Content Security Policy (CSP) прави тези пътища видими и ги ограничава: браузърът зарежда или се свързва само с това, което уебсайтът изрично разрешава.

Това е важен втори защитен слой срещу Cross-Site Scripting (XSS) и неочаквано съдържание от трети страни. CSP обаче не коригира нито незащитено API, нито липсваща автентификация, лоша валидация на въведените данни или Prompt Injection. Тя намалява възможностите за инжектиран код и ограничава радиуса на дадена грешка. Ето защо от решаващо значение е възможно най-минималната и тествана политика, вместо дълъг списък с общо разрешени домейни.

Защо уиджетите за чатбот се нуждаят от специални CSP правила

При класическа страница със съдържание често са достатъчни ресурси от собствения произход (origin). За разлика от нея, чатботът продължава да комуникира след зареждането си. connect-src управлява между другото fetch(), XMLHttpRequest, EventSource, WebSocket и sendBeacon(). Точно тук преминават съобщения, стрийминг отговори, събития за обратна връзка и евентуално телеметрия. Ако правилният произход липсва, уиджетът се появява, но не може да отговаря.

Други компоненти попадат под собствени директиви. script-src определя зареждащия модул на уиджета, img-src – аватарите и изображенията в отговорите, style-src – таблиците със стилове (stylesheets), а font-src – външните шрифтове. Уиджет, базиран на iframe, се нуждае допълнително от frame-src. default-src служи за резервен вариант за много изрично непосочени типове ресурси, но не замества съзнателната инвентаризация.

Затова най-важната предварителна работа не се извършва в CSP генератора, а в браузъра: отворете представителна страница, започнете разговор, оставете дълъг отговор да се стриймва, отворете източници, изпратете обратна връзка и тествайте случаи на грешки и прехвърляне към оператор (handoff). В панела Network ще видите действително адресираните Origins. Документирайте за всеки хост целта, типа ресурс и отговорното лице.

Отделно разрешаване на четирите релевантни пътя за данни

1. Скрипт на уиджета и инициализация

Вземайте зареждащия модул по възможност от стабилен, версиониран адрес. Разрешение като script-src https: би било твърде широко, защото така биха били допустими скриптове от всеки HTTPS домейн. Вместо това разрешете точния CDN origin или сами разпространявайте зареждащия модул. Ако интеграцията изисква инлайн код, използвайте nonce, генериран наново за всеки HTTP отговор, или подходящ хеш. 'unsafe-inline' не трябва да се превръща бързо в трайно решение.

Nonce трябва да се добавя само към скриптове, които самият сървърен шаблон генерира. Междинен софтуер (middleware), който сляпо добавя един и същ nonce към всеки съществуващ script таг, би гласувал доверие и на инжектирани тагове. За статичен, версиониран скрипт от трета страна Subresource Integrity може допълнително да помогне; при често променящи се файлове обаче хешът трябва да се актуализира контролирано.

2. API, Server-Sent Events и WebSocket

Обикновените POST заявки и отговор, стриймван през fetch(), се нуждаят от HTTPS API origin в connect-src. Server-Sent Events през EventSource също попадат тук. За WebSocket въведете конкретния wss:// origin изрично. MDN посочва, че 'self' не включва автоматично WebSocket схеми във всички браузъри. Собствена директива на име stream-src не съществува.

CSP и CORS решават различни задачи. CSP определя докъде изобщо страницата има право да се свързва; CORS определя от страна на сървъра кои origins могат да четат отговор в браузъра. Ето защо разрешението в CSP не коригира нито CORS грешка, нито изтекъл токен за достъп. Прокси от същия произход (Same-Origin Proxy) може да опрости политиката, но трябва продължително и правилно да обработва автентификацията, лимитите на заявките (rate limits), просрочванията (timeouts) и предаването на грешки.

3. Изображения, аватари и генерирани медии

Разрешете в img-src само собствения си произход и действително използвания медиен origin. data: е необходимо само ако уиджетът използва малки вградени изображения; blob: – само ако браузърът действително генерира изображения като Blob URL. Всеки допълнителен източник увеличава повърхността за атака. Ако дадено изображение първо се зареди чрез fetch() и след това се преобразува в Blob URL, това може да засегне както connect-src, така и img-src.

Тествайте не само стандартния аватар. Проверете визуализациите за предварителен преглед, екранните снимки на източниците, прикачените файлове, тъмния режим (Dark Mode) и изобразяването на грешки за недостъпни медии. Параметрите в URL могат да носят поверителна информация в CSP докладите; затова крайните точки за докладване (reporting endpoints) трябва да обработват докладите пестеливо спрямо данните и да не ги съхраняват за неограничено време.

4. iframe, стилове, шрифтове и незадължителни Workers

Уиджет, вграден директно в DOM, обикновено не се нуждае от чужд кадър (frame). Тогава frame-src 'none' може да остане. Ако чатът обаче работи в iframe, разрешете единствено неговия точен origin. Различно от това е frame-ancestors: тази директива определя в предоставения ресурс кои страници имат право да го вграждат. Затова доставчикът на уиджета трябва да я зададе съответно в своя iframe отговор.

При стиловете и шрифтовете важи същият принцип. Разрешете конкретни хостове и избягвайте 'unsafe-inline', доколкото интеграцията го позволява. Workers или аудио функции се добавят само ако продуктът наистина ги използва. Превантивното разрешаване на blob:, цели домейни със заместващи знаци или произволни медийни източници затруднява последващите одити.

Реалистичен CSP пример за чатбот уиджет

Следните домейни са съзнателно резервирани примерни домейни. Заменете ги с origins от вашия собствен мрежов анализ. Примерът предполага външен зареждащ модул, HTTPS API, отделен WebSocket за стрийминг и медиен хост. Той не използва общи заместващи знаци (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} представлява силна стойност, генерирана наново за всеки отговор, която е идентична в заглавната част (header) и в разрешените script или style елементи. Ако вашият уиджет използва iframe, заменете frame-src 'none' с точния origin на уиджета. Ако използва изключително HTTPS стрийминг през fetch() или EventSource, WebSocket origin отпада. Премахнете всеки източник, който не е необходим след пълен функционален тест.

Политиката е практична начална точка, а не универсален шаблон. Модерна стриктна CSP може да управлява скриптовете още по-строго чрез nonces или hashes и 'strict-dynamic'. Дали това е възможно без проблеми със съвместимостта, зависи от това как зареждащият модул генерира следващите скриптове. Уточнете този процес с доставчика и тествайте браузъри, режим на съгласие (Consent Mode) и варианти за внедряване (deployment).

От Report-Only към принудителна политика

Не активирайте нова политика директно в работен режим без проверка. Механизмът на W3C Content-Security-Policy-Report-Only съобщава за нарушения, без да блокира ресурси. Така откривате забравени хостове за изображения, различен стрийминг origin или инлайн код, преди потребителите да бъдат засегнати. OWASP препоръчва HTTP header като предпочитан начин за предоставяне; за разлика от мета-елемента, той поддържа и пълния набор от функции.

  1. Създаване на инвентар: Тествайте старта на уиджета, първото съобщение, дългия стрийминг отговор, източниците, изображенията, обратната връзка, прехвърлянето към оператор и промените в съгласието на няколко типа страници.
  2. Внедряване на Report-Only: Започнете с планираната строга политика и събирайте нарушения за ограничен период от време. Филтрирайте разширенията за браузъра и други непроизводими смущаващи сигнали.
  3. Обосноваване на всеки хост: Разширявайте политиката само ако конкретна функция на продукта се нуждае от дадения произход. Избягвайте заместващи знаци (wildcards) като реакция на единични съобщения.
  4. Автоматизирано тестване: Допълнете с End-to-End тестове, които изпращат съобщение, изчакват стрийминг и зареждат изображение. В същото време проверявайте конзолата на браузъра за CSP нарушения.
  5. Принудително прилагане и наблюдение: Активирайте заглавната част Content-Security-Policy, следете паралелно още по-строг вариант в Report-Only и сравнявайте процента на грешките.

Етапното внедряване съответства добре на чатбот в Shadow режим. За специфични измервателни стойности при стрийминг помага статията за бюджети за латентност и просрочвания (timeouts). В този контекст CSP нарушенията трябва да се считат за отделен сигнал: просрочването и блокираната връзка се нуждаят от различен анализ на причините.

Типични грешни конфигурации

  • Твърде широки списъци с източници: *, https: или големи домейни със заместващи знаци правят политиката удобна, но слаба и трудна за проверка.
  • Тестване само на видимия старт: Уиджетът се отваря, но стриймингът, обратната връзка, изображенията или прехвърлянето към оператор се провалят едва по-късно.
  • 'unsafe-inline' остава за постоянно: Краткосрочното помощно средство за съвместимост не се замества с nonces, hashes или външен код.
  • CSP се бърка с контрол на достъпа: Политиката не замества правата от страна на сървъра, проверката на сесията и защитата срещу злоупотреба с извикване на инструменти.
  • Докладите съдържат твърде много данни: Пълни URL адреси, параметри за заявки (query parameters) или потребителски контекст попадат ненужно дълго в мониторинга.
  • Разминаване между Staging и Production: Различни CDN, API или WebSocket хостове стават видими едва след пускането в реална среда (Go-live).

Дори строгият script-src не прави автоматично сигурен разрешения доставчик от трета страна: неговият JavaScript работи с възможностите, които вашата страница му предоставя. Затова проверявайте смяната на доставчик, новите субдомейни и актуализациите на зареждащия модул точно както правите с други критични за сигурността зависимости. Статията за защита от Prompt Injection допълва тази граница в браузъра с правила за RAG, инструменти и данни.

Списък за проверка (Checklist) преди Go-live

  • Документирани и технически обосновани ли са всички необходими origins от реални браузърни сесии?
  • Разрешава ли script-src само зареждащия модул и контролирани скриптове, без общ 'unsafe-inline'?
  • Съдържа ли connect-src точните HTTPS, EventSource и евентуално WSS origins?
  • Определени ли са източниците за изображения, стилове, шрифтове, кадри (frames) и workers отделно и възможно най-строго?
  • Генерират ли се nonces наново за всеки отговор и поставят ли се само на доверени елементи?
  • Тествани ли са промените в съгласието, дългите стриймове, изображенията, грешките, прехвърлянето към оператор, както и десктоп и мобилните устройства?
  • Наблюдавана ли е политиката първоначално в Report-Only и след това наложена ли е като header?
  • Обработват ли се CSP докладите без излишни лични или поверителни URL данни?
  • Има ли автоматизиран регресионен тест след актуализации на уиджета или инфраструктурата?

Заключение

Добрата CSP за уебсайт чатботове не е съвкупност от изключения, а техническа карта на разрешените браузърни пътища. Разделете зареждащия модул, API, стрийминга, изображенията и iframe ресурсите, разрешете точни origins и първоначално въведете политиката в режим Report-Only. Така уиджетът остава функционален, докато неочакваните скриптове и връзки получават значително по-малко поле за изява.

Източници

Превърнете посещенията в сайта в по-добри разговори

Пуснете AI чатбот, който е полезен от първия ден

Обучете ChatReact с вашия сайт, документи и одобрени факти, за да получават посетителите по-бързи отговори, а екипът ви — по-малко повторни запитвания.

Свързани статии

Продължете да четете

Илюстрация към статията Как да добавите AI чатбот към уебсайт без да увреждате UX или SEO
Имплементация7 април 2026 г.10 мин четене

Как да добавите AI чатбот към уебсайт без да увреждате UX или SEO

План за внедряване на чатбот на Вашия уебсайт, запазвайки потребителското пътуване, скоростта на страниците и структурата на съдържанието в добро състояние.

Прочетете статията
Мрежова инженерка проверява трасето за отговор на AI чатбот в оптичен разпределител
Имплементация6 август 2026 г.9 мин четене

Оптимизиране времето за отговор на AI чатбот: Бюджет за латентност, стрийминг и тайм-аути

Бързите отговори на чатбота се зараждат по протежение на цялата техническа верига. Ето как да планирате бюджети за латентност, стрийминг, тайм-аути, повторни опити и сигурни алтернативни сценарии.

Прочетете статията
Отговорник по качеството проверява тестови казуси преди пускането на чатбот в светло лоби на хотел
Имплементация10 август 2026 г.8 мин четене

Тестване на AI чатбот в Shadow Mode: Безопасно от прототип до уебсайт старт

Чрез Shadow Mode, ясни изисквания за качество и поетапен rollout, уеб екипите тестват безопасно AI чатботове преди пускането им в реална среда.

Прочетете статията