Мы позволили ИИ-агенту выполнять команды 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Спасибо.

Key Takeaway

Обеспечение безопасности агентов, выполняющих команды Bash, требует детерминированных правил эшелонированной обороны и сканирования цепочки поставок контента вместо надежных промптов.

Highlights

  • Агентский CLI-инструмент Wizard от PostHog выполняет настройку проекта за 5-6 минут вместо часа или двух.

  • Еженедельная аудитория инструмента Wizard достигла 8000 разработчиков.

  • Утилита безопасности Warlock использует детерминированный движок шаблонов Yara для обнаружения угроз.

  • Система безопасности разделяет обнаружение и принятие решений, используя LLM исключительно как советника, а не блокиратора.

Timeline

Анатомия и задачи агентского CLI-инструмента

  • Инструмент Wizard автоматически устанавливает SDK, настраивает события и строит панели мониторинга.
  • Архитектура агента включает языковые модели, управляющие промпты, набор инструментов, движок контекста и терминальный интерфейс.

Инструмент Wizard сокращает время настройки PostHog с часа до пяти минут при бесплатном инференсе. Разработчики создали агент, способный работать в цикле терминала как мини-инженер по внедрению. Постепенно инструмент стал стандартным методом установки для тысяч разработчиков.

Эволюция безопасности и аудит уязвимостей

  • Ранние версии безопасности полагались лишь на промпты и жесткий белый список разрешенных команд.
  • Аудит выявил уязвимости, возникающие из-за взаимодействия невинных компонентов системы друг с другом.

Первоначальная защита включала запрет на выполнение произвольных команд Bash и блокировку доступа к файлам окружения .env. Команда безопасности обнаружила, что атаки комбинируются из безобидных элементов, которые по отдельности выглядят безопасными при код-ревью. Особую угрозу представляет отравление контекста и обучающих данных.

Внедрение утилиты Warlock и детерминированный триаж

  • Специальный сканер Warlock использует детерминированный движок Yara для проверки входящего и выходящего контента.
  • LLM применяется как советник для устранения шума и фильтрации ложных срабатываний после срабатывания жестких правил.

Для масштабирования безопасности был создан сканер Warlock, который выдает рекомендации, но не принимает решения за систему. Правила Warlock проверяют входные данные на наличие промпт-инъекций и утечек персональных данных. Итоговая эшелонированная оборона сочетает песочницу, запрет по умолчанию, хранилище секретов и детерминированное применение правил.

Community Posts

No posts yet. Be the first to write about this video!

Write about this video