Мы позволили ИИ-агенту выполнять команды Bash и выжили — Сара Сандерс, PostHog
AAI Engineer
Computing/SoftwareSmall Business/StartupsInternet Technology
Transcript
00:00:00Всем привет, как настроение? Мы на финишной прямой. Меня зовут Сара, я инженер
00:00:23по контексту в PostHog, и мне выпала радость работать над нашим любимым волшебником каждый
00:00:30день. Итак, что же такое волшебник? Волшебник настраивает PostHog за вас. Это агентский CLI-инструмент,
00:00:39который читает вашу кодовую базу, устанавливает правильный SDK для вашего проекта, настраивает
00:00:44ваши события и создает панели мониторинга. Он берет то, на что раньше уходил примерно час
00:00:52или два настройки, и выполняет это примерно за пять-шесть минут, причем инференс бесплатный
00:00:57за наш счет, чтобы вам было приятно начинать работу с PostHog. Звучит довольно круто. Люди
00:01:03просто в восторге. Но несколько месяцев назад мы осмелились помечтать: а что, если это станет рекомендуемым
00:01:10или стандартным способом установки PostHog в ваш проект? И у меня в голове зазвенели тревожные звоночки.
00:01:17Я начала задаваться вопросом, насколько эта штука безопасна, потому что она выглядит подозрительно похоже на вредоносное ПО.
00:01:25И в ходе этих размышлений я многое узнала. Так что сегодня я расскажу об усвоенных уроках,
00:01:31о том, что не давало мне спать по ночам во время создания этой штуки, и о том, что в итоге получилось.
00:01:37Прежде чем погрузиться во всю эту скучную безопасность, из-за которой вам захочется вздремнуть в два часа дня, я хочу показать вам, как волшебник работает на практике.
00:01:49Если вы посмотрите на экран, он работает для вас в цикле. Это абсолютно тот же опыт, который получает любой,
00:01:56кто запускает NPX PostHog Wizard в своем терминале. Как я уже сказала, это агент. Он определяет, какой SDK подходит для вашего проекта. Устанавливает его, настраивает события, строит панели.
00:02:10Мне нравится называть его маленьким мини-инженером по внедрению прямо в вашем терминале. И иногда, когда я показываю это людям, меня спрашивают: почему агент? Почему бы не дать пользователям хороший промпт? Почему бы не дать им навык, который они могли бы вызвать сами?
00:02:23И хотя мы предоставляем такие возможности, ответ прост: этот опыт разработки и возможности волшебника — и есть главная цель. Это весь наш продукт.
00:02:34Потому что мы создаем CLI-инструмент, который может полноценно участвовать в цикле агента, и испытать это впервые — поистине невероятно.
00:02:43Но нельзя выпускать что-то вроде волшебника, не выпуская при этом то, что делает его немного сомнительным.
00:02:50Давайте разберем его. Посмотрим на анатомию волшебника, ведь модели угроз обычно напрямую вытекают из анатомии самого агента.
00:03:01Итак, волшебник устроен примерно так же, как и то, что многие из вас создают, если разрабатывают агентов.
00:03:07У него есть модели, которые мы подобрали для конкретных задач. У него есть промпты, которые направляют его, и набор инструментов, которые мы ему дали для выполнения работы.
00:03:17Но в нем также есть компоненты, уникальные именно для нас. У него есть собственный движок контекста, полностью созданный моей командой с нуля.
00:03:25Именно он позволяет агенту справляться с задачей на отлично и выдавать стабильные результаты при каждом запуске.
00:03:30Мне нравится называть это мозгом волшебника. Иногда мы зовем это «маркдоном в плаще».
00:03:35Но это наш собственный движок контекста. Также у нас есть интерфейс терминала, который мы написали сами на Ink.
00:03:43И теперь появился сканер безопасности под названием «чернокнижник» (warlock) — я создала его, когда начала изучать тему и столкнулась со всеми ужасами выкатывания агента в продакшн.
00:03:55Так что, если взять анатомию любого агента, способного выполнять команды, это фактически то, что я называю «стартовым набором малвари».
00:04:03Потому что это почти в точности то же самое, что вы передали бы вредоносному ПО, если бы были излишне щедры или хаотично злы.
00:04:11К счастью, это худший сценарий или просто кошмарный сон, и это не мое признание в грехах, а предупреждение для всех вас.
00:04:19Потому что если вы хотите выпустить агента с руками — агента, способного выполнять команды — вам нужно убедиться, что вы не создали вот это.
00:04:28Версия 0 волшебника появилась потому, что Джош Снайдер, если вы знаете его из нашей команды роста, наблюдал, как Cursor галлюцинирует при настройке PostHog самыми худшими из возможных способов.
00:04:41И он подумал: а что, если создать агента, который справится с этим лучше?
00:04:46Поэтому моя команда начала дорабатывать эту идею, убедившись, что он справляется гораздо лучше галлюцинирующего Cursor.
00:04:52И мы подумали: а что, если он сможет подключать к PostHog кого угодно?
00:04:58Неважно, какой у них фреймворк или стек, агент автоматически настроит все события без необходимости что-либо трогать руками.
00:05:04И тогда мы осмелились помечтать: а что, если это станет стандартным способом установки PostHog?
00:05:09Мы мечтали о тысячах разработчиков, запускающих его каждую неделю, и вчера мы как раз достигли отметки в 8 000 человек в неделю.
00:05:16Так что наша мечта сбылась.
00:05:18Но тогда, в те дни, когда мы только мечтали, нам пришлось изучить нашу систему безопасности под микроскопом и посмотреть, что происходит.
00:05:26Поэтому я взяла это на себя, села и оценила текущее положение дел.
00:05:31И поначалу — я говорю примерно о периоде от года до девяти месяцев назад — у нас было то, что я называю «слоем ноль», потому что это буквально не является безопасностью.
00:05:41Это просто промпты, которые подсказывают агенту, что делать, и направляют его, а промпты — это не безопасность.
00:05:48Так что это меня беспокоило.
00:05:51Слой первый: это был список разрешенных элементов.
00:05:53И когда я начала разбираться с этим белым списком, мне стало немного спокойнее, потому что он был довольно жестко ограничен.
00:05:59Но у меня все равно оставалось много поводов для беспокойства.
00:06:01И я начала паниковать из-за того самого движка контекста, о котором я вам рассказывала.
00:06:05Мы передаем агенту огромное количество контекста во время выполнения.
00:06:09Поэтому я написала очень кривой регулярный сканер, чтобы отслеживать вещи, похожие на угрозы, на входе и выходе из волшебника.
00:06:20И я признаю, что это было сделано «на коленке».
00:06:23Но я рассказываю вам все это абсолютно откровенно, потому что все мы создаем вещи, которые кажутся крайне экспериментальными, и все мы делаем это очень быстро.
00:06:33И я знаю, что безопасность — это конек далеко не каждого из нас.
00:06:38И некоторым из приходится изучать ее на ходу, как это делала я.
00:06:43Но об этом нужно думать, когда мы создаем продукты подобной архитектуры.
00:06:50Так выглядела наша система безопасности.
00:06:53Но я задалась вопросом: «Мы что, сгорели на работе?»
00:06:56Хорошая новость: всё было не так плохо, как я думала.
00:06:59Потому что тот белый список, о котором я упоминала ранее, был довольно жестко ограничен.
00:07:03Для bash действовал запрет по умолчанию.
00:07:06Он мог устанавливать только доверенные пакеты, проверенные нами.
00:07:09Он умел собирать проект.
00:07:10Он умел проверять типы.
00:07:11Он умел работать как линтер.
00:07:12И практически больше ничего.
00:07:13Он не мог выполнять случайные команды оболочки.
00:07:16И у него не было доступа к переменным окружения.
00:07:20Агент не мог прочитать ваш файл .env, потому что мы полностью заблокировали это, пропуская секреты через хранилище.
00:07:28Так что я с облегчением вздохнула и поняла, что мы находимся в лучшем положении, чем я думала.
00:07:34Но мне хотелось узнать, где кроются бреши, ведь в безопасности всегда есть бреши.
00:07:39Поэтому я поступила так, как следовало бы поступать всем нам.
00:07:41Я обратилась к нашей команде безопасности и сказала: «Эй, не могли бы вы провести аудит этой штуки и найти бреши?»
00:07:48И они кое-что нашли.
00:07:51Они обнаружили уязвимости.
00:07:52И самое интересное заключалось не в самих найденных багах, а в их природе.
00:07:58Почти ни одно из них не выглядело откровенно злонамеренным.
00:08:01Все они представляли собой две совершенно невинные, благие вещи, которые взаимодействовали друг с другом и создавали брешь.
00:08:07Урок, который я усвоила, заключается в том, что атаки компонуются, а код-ревью — нет, поскольку мы, разработчики, изучаем дифы по отдельности.
00:08:20Но злоумышленники смотрят на всю систему целиком и ищут те самые элементы, которые взаимодействуют и открывают дверь.
00:08:25Однако была еще одна вещь, которая не давала мне спать по ночам.
00:08:29Возвращаясь к движку контекста, я поняла, что самой страшной частью созданного нами агента в нашем случае была вовсе не команда.
00:08:37Это были полезные на вид данные, которыми мы питали его мозг.
00:08:43Ой, кажется, я пошла не в ту сторону.
00:08:46Да.
00:08:47Контекстная фабрика.
00:08:48Итак, это наш контекстный движок, он же мозг волшебника.
00:08:51Благодаря ему волшебник вообще хоть что-то знает и почему он так хорошо справляется со своей работой.
00:08:56Он берет данные из нашей документации.
00:08:58В нем есть написанные вручную промпты с подсказками и уроками, которые мы извлекли на этом пути.
00:09:02А также реальные рабочие сквозные примеры приложений, которые помогают агенту сопоставлять паттерны, чтобы он мог наилучшим образом установить PostHog для вас.
00:09:11Он упаковывает все это в пакеты навыков, которые доставляются волшебнику через наш сервер MCP и загружаются прямо в контекст агента во время выполнения.
00:09:22Подумайте об этом на секунду.
00:09:24Это машина, главная задача которой — принимать контент и внедрять его в агента, способного выполнять команды.
00:09:31Теперь, если бы вы были злоумышленником, вы бы могли сказать: «Что, если я просто отравлю контент?»
00:09:36Не кодовую базу пользователя, не самого агента, а именно контент.
00:09:41Допустим, кто-то открывает пул-реквест в одном из наших открытых репозиториев, ведь в PostHog мы строим все открыто,
00:09:48и они внедряют что-то в файл markdown или в кажущийся безобидным комментарий в коде,
00:09:55а у нас работает какой-нибудь проверочный код-ревью на базе LLM, который говорит: «Выглядит нормально» — и пропускает это.
00:10:04Мы могли только что отправить подписанную нами полезную нагрузку для инъекции промпта в агента, который работает на тысячах машин разработчиков в песочнице, но тем не менее.
00:10:14Так что это была за угроза, которая полностью изменила мое представление о безопасности и волшебнике, поскольку опасный ввод для нас действительно мог прийти из нашей собственной цепочки поставок.
00:10:25В итоге я стала сканировать контент с обоих концов этого конвейера.
00:10:30Во-первых, когда навык создается и выпускается, и снова, когда волшебник действительно использует его.
00:10:36Моя методология такова: перехватить у источника, предположить, что источник дал сбой, и перехватить снова в точке использования.
00:10:43Так что теперь я могу представить вам Чернокнижника.
00:10:48Создание Чернокнижника не было обязательным контролем ущерба.
00:10:52Как я уже говорила, у нас была защита в других аспектах.
00:10:55Но я создала Чернокнижника, потому что мне не нравилось говорить людям: «Ну, эта штука типа неплохо защищена».
00:11:01Так не масштабируется.
00:11:02Это не то, что хочется выпускать в продакшн.
00:11:04Это не то, что должны запускать тысячи разработчиков каждый день.
00:11:08Потому что при выходе на такой масштаб у вас гораздо шире поверхность атаки, гораздо больше пользователей, больше контента поступает по мере расширения возможностей волшебника.
00:11:19И, наверное, всё будет хорошо.
00:11:21Просто это перестает быть достаточным.
00:11:23Так что я вытащила тот кривой маленький регулярный сканер, который засунула туда, убрала его из волшебника и сделала отдельную утилиту.
00:11:30Я назвала его Чернокнижником, потому что всё, что связано с волшебниками, нуждается в телохранителе.
00:11:35И он выполняет ровно одну задачу.
00:11:38Вы передаете ему строку.
00:11:40Он возвращает вам список находок.
00:11:42У каждой из этих находок есть категория, степень серьезности и рекомендуемое действие, после чего он останавливается.
00:11:48Я хочу, чтобы вы сосредоточились на слове «рекомендуемое».
00:11:51Потому что Warlock обнаруживает, а не действует.
00:11:54Он подскажет: «Эй, это похоже на утечку данных.
00:11:57Это критично.
00:11:58Я бы заблокировал».
00:11:59Но что именно делать с этой находкой, решать только вам.
00:12:04Потому что обнаружить проблему — это одна задача, а решить, что с ней делать — совсем другая.
00:12:10И единственный способ сохранить ясность — разделять эти две вещи.
00:12:15Поэтому под капотом Warlock вместо моих самодельных регулярных выражений правила работают на Yara — движке шаблонов, который исследователи малвари используют уже лет 15.
00:12:27Он полностью детерминирован.
00:12:28Тот же вход, тот же выход, каждый раз.
00:12:31Он скучный нарочно.
00:12:33А в безопасности скука — это функция.
00:12:39Так что же Warlock реально ловит «в поле» сегодня?
00:12:42Много всего разного, но две вещи — это просто сущая боль для моей души.
00:12:48Первое — это на самом деле не правило как таковое.
00:12:52Warlock зафиксировал поведение субагента, которое обнажило уязвимость на основе того, что эти субагенты делали.
00:13:03Короче говоря, мы запускали агентов для выполнения крупных задач.
00:13:07Они порождали субагентов.
00:13:08И эти субагенты пытались обойти защитные барьеры, внедренные нами в wizard, и пытались выдумать секреты.
00:13:16Они пытались вытащить секреты буквально отовсюду в кодовой базе.
00:13:20И мы это прикрыли.
00:13:21Мы сказали: «Никаких субагентов больше».
00:13:23И благодаря Warlock мы это поймали.
00:13:26Пойму робота по-человечески.
00:13:28У робота была задача, и он пытался оптимизировать и угодить нам.
00:13:32Но так дело не пойдет.
00:13:35Еще один важный для нас в PostHog вопрос — это PII (персональные данные).
00:13:39Агентам искренне плевать на утечку данных, если вы не зададите четких правил.
00:13:46Оставшись без присмотра, они сливают email и телефоны прямо в события, и для агента это выглядит совершенно нормальным делом.
00:13:57И к счастью для промпт-инъекций — постучу по дереву — мы практически никогда не ловили реальных злонамеренных инъекций в бою.
00:14:08Зато мы ловим тонну ложных срабатываний: экраны демо-логина, тексты в примерах приложений, содержимое нашей документации.
00:14:17Это заставило меня переосмыслить создание приложений и написание доков, потому что я не хочу выпускать ничего, похожего на угрозу.
00:14:27Но ложные срабатывания — это, честно говоря, идеальная подводка к самой грязной и интересной части всего этого.
00:14:36И вот над этим мне пришлось поломать голову.
00:14:39Я тут распинался перед всеми про детерминизм, а потом взял и добавил LLM-слой, чтобы сортировать ложные срабатывания и заглушать шум.
00:14:50Я называю это триажем.
00:14:51Создавая этот слой триажа, мне нужно было сделать выбор.
00:14:56Должен ли этот слой быть вышибалой или советником?
00:15:01Проще всего было бы сделать из LLM вышибалу.
00:15:06Показать команду, спросить, атака ли это, заблокировать, разрешить и делать всё, что она скажет.
00:15:13И хотя это соблазнительно из-за простоты, я не могу ставить модель безопасности в зависимость от подброшенной монетки, если у модели неудачный день или что-то произошло, и она ведет себя иначе, чем вчера.
00:15:26Поэтому вместо вышибалы я сделал модель советником.
00:15:32И это четкая грань, которую я нащупал и которую продолжаю исследовать, и которой хочу поделиться с вами.
00:15:38Во-первых, обнаружение и применение правил для нас остаются детерминированными и механическими.
00:15:43Если правило сработало, затвор запирается, сессия завершается, и никакой модели на этом пути нет.
00:15:49Блокировка происходит еще до того, как мы спросим мнение LLM.
00:15:54LLM может высказаться только потом, если мы ничего не заблокировали.
00:15:58Она создана для устранения шума.
00:16:00Она не предназначена для пропуска чего-либо.
00:16:03И если она дает сбой в закрытую — то есть у модели неудачный день — все запуски wizard прерываются, извините, но мы вас просто защищаем.
00:16:14Применение правил — это то, на что ставишь всё, поэтому оно должно быть детерминированным.
00:16:20А рассуждения — это то, что добавляет нюансов, так что это единственное место, куда можно засунуть вероятностный элемент.
00:16:27Так как же нам внедрять реальные правила для агентов?
00:16:34Это анатомия одного из наших правил Warlock, и у каждого правила Warlock есть четыре части.
00:16:41Часть первая — это метаданные.
00:16:43Простое описание на английском, критичность, категория, действие, направление.
00:16:50Часть первая: поступает ли это внутрь агента?
00:16:52Пишет ли это сам агент?
00:16:57Затем у нас есть строки — это конкретные шаблоны, которые вы ищете.
00:17:03А часть третья — условие.
00:17:05Это то, где правило действительно имеет право сработать.
00:17:10Я пройдусь по этому примеру для вас, и мы можем представить, что пишем его в уме.
00:17:15Промпт-инъекция вроде классического «игнорируй все предыдущие инструкции».
00:17:20Вашим первым инстинктом здесь, вероятно, будет заблокировать слово «игнорировать», но агенты целый день читают код,
00:17:27и слово «игнорировать» постоянно встречается в комментариях к коду или примерах.
00:17:31Так что вам не нужно матчить один только глагол.
00:17:33Вы матчите глагол плюс существительное с инструктивным оттенком.
00:17:38В условии вы говорите: срабатывать, если совпал любой из этих шаблонов.
00:17:42А в метаданных вы определяете, критично ли это, какова категория, каково действие,
00:17:50в данном случае «блокировка», и направление — в данном случае входящий в агента поток.
00:17:56Но чтобы писать хорошие правила, снижающие уровень шума, к ним нужно прилагать тесты.
00:18:02То есть вы должны писать тесты, говорящие: вот шаблоны, которые подходят.
00:18:06А вот те, которые не должны.
00:18:08И этот негативный тест — первая линия обороны против ложных срабатываний.
00:18:13Но также вам нужно убедиться, определяя критичность правила,
00:18:19что вы отслеживаете реальное влияние на практике, а не то, как жутко это выглядит.
00:18:24RM-RF — это страшно, но так мы все удаляем node_modules раз по 40 на дню.
00:18:31Вы определяете реальное влияние для того агента, которого строите,
00:18:37потому что инструмент безопасности, который падает каждый раз при попытке очистить папку сборки,
00:18:42— это инструмент, который отключают и который ничего не ловит.
00:18:47И я с гордость заявляю: вот наша текущая позиция по безопасности.
00:18:51Я наконец могу выйти сюда и сказать, что у нас есть настоящая эшелонированная оборона.
00:18:56Все мои выводы объединились в это.
00:19:00Оно по-прежнему многослойно, но каждый слой теперь выполняет ту работу, в которой он хорош.
00:19:04У нас всё еще есть промпты, но мы используем их только для управления.
00:19:07Всё работает в песочнице.
00:19:09У нас запрещено всё по умолчанию.
00:19:11У нас есть хранилище секретов, чтобы они никогда не попадали в модель.
00:19:14У нас есть Warlock для сканирования входящего контента
00:19:17и сканирования вывода, написанного агентом.
00:19:20У нас также есть триаж для снижения шума,
00:19:23и телеметрия, внедренная во весь процесс,
00:19:26чтобы мы видели всё.
00:19:28Ни один из этих слоев не стоит сам по себе.
00:19:31Ни одна штука здесь вас не спасет,
00:19:33но это просто скучные, честные слои,
00:19:36каждый из которых выполняет одну задачу, в которой он хорош.
00:19:40Так что, если вы создаете агента с руками,
00:19:45весь этот доклад можно уложить в три строчки.
00:19:47Первое: если это не применяется детерминистически,
00:19:50это вообще не применяется.
00:19:52Промпты — это не правила безопасности.
00:19:54Не ведите себя так, будто это они.
00:19:57Второе: опасный ввод — это не только то, что печатает ваш пользователь.
00:20:02Это не просто команды, выполнение которых вы разрешаете.
00:20:04Это всё, что поступает в модель,
00:20:06включая контент, который пишете вы сами.
00:20:09Поэтому сканируйте собственную цепочку поставок у источника
00:20:12и тогда, когда агент её вызывает.
00:20:15Третье: атаки комбинируются, а ревью кода — нет.
00:20:18Большинство наших пробелов во время аудита состояли из двух невинных вещей:
00:20:22рукопожатия и открытия двери.
00:20:25Wizard, Warlock и context mill — всё это с открытым исходным кодом,
00:20:29так что найдите меня внизу.
00:20:32Я в выставочном зале на нашем стенде,
00:20:34и я покажу вам всё вокруг, покажу, что мы построили,
00:20:37и я хочу услышать, как вы обеспечиваете безопасность своих агентов.
00:20:41Спасибо.
00:20:59Спасибо.
Community Posts
No posts yet. Be the first to write about this video!
Write about this video