Переоткрытая старая уязвимость
Суть LLM05 в одной фразе: сгенерированный текст передаётся дальше без проверки, как будто ему можно доверять. Разработчик, который никогда не вставит пользовательский ввод в страницу без экранирования, спокойно рендерит ответ модели как готовый HTML. А ведь путь к этому ответу мог пролегать через чужие документы, страницы и сообщения — все каналы промпт-инъекций заканчиваются именно здесь.
Различие с классикой в источнике недоверия. У пользовательского ввода виновник очевиден — пользователь; у вывода модели виновник размыт: то ли модель ошиблась, то ли её убедили, то ли в обучении лежит закладка. Отсюда и ошибочное ощущение безопасности: «это же наш сервис сгенерировал».
Потребители вывода и их риски
| Куда уходит ответ | Атака | Последствие |
|---|---|---|
| Веб-интерфейс | скрипты и разметка в сгенерированном HTML | кража сессии пользователя |
| Markdown-рендер | ссылки и картинки на ресурсы атакующего | фишинг, утечка токенов через загрузку |
| SQL-запрос, собранный моделью | инъекция в сформированный запрос | доступ к чужим данным |
| Командная строка или код | исполнение вложенных команд | компрометация сервера |
| Почта и рассылки | скрытые получатели, ссылки | эвакуация переписки |
| Файловые операции | перезапись по подсказанному пути | порча и подмена данных |
| Следующий конвейер обработки | команды для следующей системы | цепочка машинных действий |
Заметьте закономерность: чем дальше за пределы человеческого просмотра уходит вывод, тем дороже цена ошибки. Текст на экране человек ещё заметит; команду, ушедшую в планировщик, — уже нет.
Принцип защиты: контекст потребителя решает
Универсального фильтра «безопасного текста» не существует — безопасность определяется тем, где вывод будет исполняться. Экранирование разметки для веба, параметризация для баз, списки разрешённых команд для шелла, валидация схемы для межсистемных обменов. Один и тот же ответ модели требует разной обработки для разных потребителей, и именно потребитель задаёт правила.
Отсюда практические правила:
- вывод рендерится как текст по умолчанию; любое обогащение разметкой — осознанное решение с белым списком тегов и атрибутов;
- ссылки проходят через белый список доменов; автоматические загрузки изображений и ресурсов отключены;
- если модель формирует запросы к данным — только через параметризованные шаблоны, где модель заполняет значения, а не структуру;
- исполнение сгенерированного кода — в изолированной среде без сети и секретов, по кнопке человека для необратимого;
- межмашинные обмены валидируются по схеме: структура обязательна, лишние поля отбрасываются.
Опасная связка с агентными сценариями
Отдельного внимания заслуживают системы, где вывод модели напрямую становится действием: агент решил — агент выполнил. Здесь LLM05 смыкается с избыточными полномочиями, и цена ошибочной генерации мгновенна. Дисциплина та же, но строже: каждое действие описано в узком интерфейсе с валидацией параметров, а не свободной командой; необратимые операции — только через подтверждение; журнал действий ведётся на уровне системы, а не на уровне «что сказала модель».
Программа наведения порядка
Шаг первый — инвентаризация потребителей: куда фактически уходит вывод каждой модели в вашей системе, включая неочевидные пути — логи с форматированием, рассылки, автоматические тикеты. Шаг второй — классификация по типу исполнения: просмотр человеком, рендер, запрос, команда, обмен. Шаг третий — установка барьера по типу из таблицы выше для каждого класса. Шаг четвёртый — тесты: в корпус проверок включаются атаки, где модель просят сгенерировать разметку со скриптом, ссылку на подозрительный домен, команду с дописанным аргументом. Прогон до релиза и после каждого изменения конвейера — как для любого другого барьера.
Типичные заблуждения команды
Опыт внедрения показывает устойчивость трёх мифов. Первый — «модель у нас серьёзная, она не будет генерировать вредоносное»: генеративная природа как раз означает правдоподобное продолжение любого шаблона, включая опасный, особенно после целенаправленной инъекции. Второй — «у нас есть WAF на входе»: барьер на входе не видит то, что рождается внутри системы; вывод — отдельный периметр со своими правилами. Третий — «вывод видит человек, он заметит»: замечает тот, кто ждёт подвоха; оператор в потоке работы читает содержание, а не разметку, и ссылка, неотличимая от привычной, проходит незамеченной. Разбор этих мифов с командой на конкретных примерах — дешевле любого инструмента, потому что исправляет саму точку принятия решений о доверии.
Полезная аналогия для переговоров с руководством: вывод модели — это письмо от неизвестного корреспондента. Его можно читать, но не стоит исполнять без проверки. Ни один разумный процесс не подписывает приказ по тексту из анонимного конверта; тем же правилом стоит защищать и машинные конвейеры.
Минимальный набор для старта
Если бюджет ограничен, закройте три позиции. Первая — экранирование разметки во всех веб-интерфейсах, где отображаются ответы: это часы работы и самый массовый вектор. Вторая — белый список доменов для ссылок из генерируемого контента: снимает фишинг под брендом. Третья — параметризация всех запросов к данным, которые формирует модель: закрывает инъекции в собственную периферию. Остальные барьеры из таблицы добавляются по мере роста конвейера, но эти три устраняют подавляющую часть практических сценариев за минимальные усилия.