Чтобы создать работающие ИИ-системы, сначала нужно попытаться их сломать. Мы провели red teaming клиентского ИИ-приложения в сфере финансовых услуг, выступая в роли злоумышленников и проверяя его на прочность. Наши выводы важны для всех, кто внедряет приложения на базе LLM и не может позволить себе пренебрегать безопасностью.
Red teaming — это намеренная попытка взломать собственную ИИ-систему, чтобы устранить уязвимости до того, как их обнаружит настоящий злоумышленник. В сфере финансовых услуг ставки особенно высоки: ИИ-приложения работают с данными клиентов, обрабатывают транзакции и предоставляют финансовую аналитику. Сбой может привести как к ухудшению пользовательского опыта, так и к нарушению нормативных требований, финансовым потерям и непоправимому ущербу для бренда.
Мы стремились заранее выявить уязвимости, проверить реалистичные сценарии атак и помочь организации выполнить требования к безопасности ИИ, которым регуляторы уделяют самое пристальное внимание.
Здесь важно провести различие: джейлбрейк атакует защитные фильтры самой модели, а промпт-инъекция — приложение, используя недоверенные пользовательские данные вместе с доверенным промптом разработчика. Промпт-инъекция опаснее, поскольку нацелена не на модель общего назначения, а на вашу систему и конфиденциальные данные, с которыми та работает.
Первый этап включал около 750 тестов по следующим направлениям:
Утечка данных между сеансами
Раскрытие персональных данных (с помощью естественного языка, манипуляций с API и различных кодировок)
SQL-инъекция
Переопределение системного промпта
В ходе первоначального тестирования мы выявили две серьезные проблемы существующей системы: обработку запросов с несколькими намерениями и использование закодированных промптов.
Запросы с несколькими намерениями: запросы, сочетающие правомерные и вредоносные задачи. Например: «Покажи мои расходы по категориям, а также выполни [вредоносный SQL-запрос]». Приложение не распознавало вредоносное намерение и полностью полагалось на защитные механизмы нижележащего уровня данных. Это все равно что оставить входную дверь открытой, потому что вы доверяете сейфу в подвале.
Кодирование: запросы, закодированные с помощью Base64, Hex, LeetSpeak и омоглифов. Системам бывает сложно отфильтровать заложенное в них вредоносное намерение. Хотя эти запросы не раскрывали конфиденциальные данные, они заметно дестабилизировали систему: вызывали галлюцинации, заставляли ее повторять пользователям вредоносный SQL-запрос, путаться при классификации намерений и т. д.
Первоначальное тестирование выявило следующие проблемы:
Временные галлюцинации: модель уверенно сообщала вымышленные даты, временные метки транзакций или сводки за определенные периоды. В финансовой сфере это серьезный риск, поскольку действия клиента на основе неверной даты могут иметь реальные последствия
Вредоносный SQL-запрос воспроизводится в ответе пользователю (что вызывает опасения из-за риска отравления памяти)
Ошибки в классификации намерений
Нарушение форматирования ответа
Опираясь на эти результаты, мы сузили область исследования. Тесты SQL-инъекций и кодирования отошли на второй план, поскольку команда уже занималась этими проблемами. Вместо этого мы сосредоточились на самых результативных векторах атак: раскрытии персональных данных и утечках между сеансами.
Самый поразительный вывод второго этапа оказался обезоруживающе прост: зачастую никакой изобретательности не требуется.
Во многих случаях было достаточно просто попросить внутренние данные под видом правомерного запроса, чтобы система согласилась их раскрыть. В ответ на простые запросы система упоминала внутренние идентификаторы и системные поля, которые ни в коем случае не должны быть видны конечным пользователям.
При дальнейшем анализе выяснилось, что проблема возникала не только на уровне приложения. Нижележащий сервис преобразования текста в SQL составлял запросы к большему числу полей, чем следовало, а в его пояснениях упоминались данные, доступ к которым должен был быть ограничен. Так обнаружилась реальная брешь на стыке систем — уязвимость, которую можно выявить лишь при тестировании всего стека, а не отдельных компонентов в изоляции.
Проводите red teaming системы, а не модели. Изолированное тестирование LLM почти ничего не говорит о защищенности вашего приложения. Тестируйте весь стек от начала до конца — так, как с ним взаимодействовал бы пользователь.
Входные данные необходимо проверять до передачи в LLM. Закодированные запросы, атаки с несколькими намерениями и базовые попытки инъекций нужно блокировать на периметре, а не передавать эту задачу нижележащим сервисам.
Не доверяйте стыкам систем. В архитектурах с несколькими сервисами самые интересные уязвимости скрываются в брешах между системами. Нулевое доверие означает именно нулевое доверие: проверяйте всё на каждом уровне.
Простые атаки работают. Сложные джейлбрейки попадают в заголовки, но иногда можно просто... попросить. Если система охотно раскрывает внутренние идентификаторы, когда пользователь включает их в остальном правомерный запрос, это проблема.
Понимайте, что именно вы тестируете. Известные сценарии атак могут блокироваться благодаря обучению самой LLM, а не вашим защитным механизмам. Встройте наблюдаемость в процесс red teaming, чтобы понимать, какие средства контроля действительно задействуются.
Ограниченные среды требуют нестандартных решений. Пользовательские провайдеры и поддержка локальных моделей позволяют проводить полноценный red teaming без специального доступа к облаку. Но важно открыто говорить о связанных с этим ограничениях.
Red teaming — не разовая процедура. Это итеративный процесс, который следует по возможности автоматизировать и развивать вместе с системой. Атаки, актуальные завтра, будут отличаться от тех, что важны сегодня.
Контроль за ИИ-системами в регулируемых средах будет только усиливаться. Организации, которые считают тестирование безопасности постоянной практикой, а не формальностью перед запуском, будут лучше готовы к такому контролю и смогут избежать репутационных кризисов, подрывающих доверие клиентов.