Главная / Статьи

Как общедоступные файлы llms.txt позволяют исследователям запускать код в крупных компаниях

Исследователи зарегистрировали незабранные имена пакетов, которые официальные файлы llms.txt предписывали ИИ-агентам установить, и код начал выполняться в крупных компаниях в течение нескольких минут. Почему данные сейчас являются кодом.

Издатель: REACTAPP.TOP9 мин чтения2017 слов

Источники: Data Became Code: We Ran Code Inside Fortune 500s Using Files They Published for AI Agents

Когда опубликованный файл превращается в заказ

Команда исследователей в области кибербезопасности сообщила, что на оборудовании одной из компаний из списка Fortune 500 был запущен код, опубликованный ими, причем это произошло примерно через четыре минуты после того, как код стал доступен. Ещё два сигнала поступили в течение часа. По их словам, никто не воспользовался уязвимостью CVE, не занимался фишингом среди сотрудников и не вмешивался в сетевую защиту. Исследователи зафиксировали несколько имен официальных файлов, предоставляемых самими компаниями через протокол HTTPS, которые уже указывали ИИ-агентам на необходимость использования определённого кода.

Эти файлы были общедоступны, а привязанные к ним имена не были заняты другими пользователями. Агенты выполнили ровно то, для чего были созданы. Та же команда также утверждает, что в процессе массового сканирования этих файлов они наткнулись на уже действующую атаку: файл с инструкциями от поставщика, направлявший агентов на подтверждённый вредоносный код. Этот случай рассматривается ниже.

Сначала — контекст.

Почему llms.txt важен здесь

На протяжении большей части истории Интернета страница на сайте была просто страницей. Её мог читать пользователь, её мог индексировать спам-сканер, но никто не рассматривал её как команду. Сейчас ситуация изменилась.

Компании теперь размещают в корне своих сайтов рядом с robots.txt новый тип файла — llms.txt, а иногда и более длинный файл llms-full.txt. Это не карта сайта и не юридическое уведомление. Это своего рода отобранный набор указаний для ИИ-агентов, определяющих, что читать, какие API использовать, какие пакеты устанавливать и каким доменам доверять. Крупные лаборатории, занимающиеся разработкой больших моделей, публикуют собственные такие файлы, а инструмент Lighthouse от Google в Chrome DevTools теперь включает проверку под названием «агентское просмотрение», побуждающую сайты их предоставлять. Количество таких файлов постоянно растёт.

Команда решила выяснить, насколько широко распространился этот слой инструкций. По их подсчётам, на 6 214 доменов, принадлежащих примерно 15 000 зарегистрированным компаниям, было найдено 8 565 файлов llms.txt. Среди тех, кто публиковал эти файлы, были крупные предприятия, технологические гиганты, компании из сферы финтеха и поставщики военного оборудования.

Типичный файл направляет агента на документацию, чарт изменений и форум сообщества, а затем — на команду установки, похожую на pip install для SDK компании. Этот файл выглядит полезным и официальным, к тому же он поступает с собственного домена компании по протоколу HTTPS. Агент для программирования на ИИ, запрошенный к интеграции с этим продуктом, прочитает эту команду и выполнит её.

Следующий вопрос был почти до смешного прост: кто на самом деле владеет этим именем пакета в PyPI? В каждом случае ответом было «никто». Это имя находилось в официальном файле первой стороны, а пакет, на который оно указывало, так и не был зарегистрирован. Принцип «кто первый, тот и получает».

Исследователи проверили ещё несколько файлов, затем сотни, а потом почти все из них, и везде увидели одно и то же. Инструкции по установке содержали имена пакетов и доменов, которые никто не зарегистрировал. По их словам, они не были «потенциально уязвимы», а просто доступны. Это также не является тайпспквотингом. Имена в файлах написаны правильно, поэтому нет опечаток, которые можно было бы обнаружить, ведь регистрация так и не происходила.

Как код оказался выполняющимся в крупных компаниях

Команда выбрала небольшой набор имен пакетов, присутствовавших в файлах llms.txt известных компаний, и зарегистрировала их в PyPI и npm. Каждый пакет содержал простой механизм отслеживания, минимальный сигнал, сообщающий о том, что произошла установка на инфраструктуру, находящуюся под контролем исследователей. После этого они стали ждать.

Первый сигнал обратной связи поступил менее чем через четыре минуты. А именно, где-то в компании стоимостью несколько сотен миллиардов долларов ИИ-агент прочитал файл llms.txt на сайте компании, нашел строку pip install и выполнил её. Пакет действительно поступил с PyPI, как указано в файле, хотя это был пакет исследователей. Второй сигнал от компании из списка Fortune 500 пришёл в течение часа, а затем последовало ещё несколько десятков сигналов от стартапов и крупных предприятий; у некоторых из них команды по безопасности были крупнее всей профессиональной сети исследователей.

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

Как агенты сами находят эти файлы

Затем в эксперименте исследовались минимальные требования к подсказкам. Исследователи протестировали пять различных конфигураций на двух агентных CLI, передав каждому по одной и той же фразе 100 раз, не включая в неё ничего, кроме имени поставщика. В этой фразе агенту предлагалось использовать все документы данного поставщика для создания и запуска проекта на Node.js с его SDK.

Вот и весь запрос. В нем не было ни URL, ни ссылки на документацию, ни упоминания llms.txt. Не было ни внедрения запроса, ни злоумышленника в процессе, ни социальной инженерии. Агент самостоятельно нашел канал инструкций, поскольку его создавали именно для поиска официальной документации поставщика. Команда подсчитала, сколько из 100 запусков для каждой конфигурации обращалось к llms.txt, увидела команду и установила пакет, который никто не регистрировал.

Пакеты были спроектированы как неактивные, служа лишь сигнальными элементами. Всё, что происходило до этого момента, было контролируемыми исследованиями. То, что произошло дальше, — это отдельный инцидент, обнаруженный во время анализа корпуса данных.

Случай, уже существующий в реальности

Одно открытие заставило команду замереть, потому что это уже происходило на самом деле.

Clerk — поставщик решений для аутентификации, чьи SDK используются во многих продакшн-приложениях на Next.js; он публикует документацию, написанную для ИИ-агентов. Агент, следуя этим указаниям, находит руководство Clerk llms.txt с решением проблемы защиты от аутентификации, в котором приводится следующая команда:

npx clerk-next-fix-auth-protection

Агент читает этот текст и выполняет его, что вполне ожидаемо для инструкций непосредственно от поставщика.

Проблема не в неправильно написанном имени пакета. Сам команда clerk-next-fix-auth-protection представляет собой бинарный файл, входящий в пакет Clerk с ограниченным доступом @clerk/eslint-plugin. В документации рекомендуется сначала установить пакет с ограниченным доступом, а затем вызвать эту команду. Однако если команда выполняется до установки пакета локально, npx ищет её имя в общедоступном реестре npm, где Clerk никогда не публиковал её как отдельный пакет.

Его зарегистрировал кто-то другой. По описанию исследователей в пакете нет функционального кода, но при установке он активирует хуки, которые при каждой установке отправляют имя пользователя установщика, имя компьютера, рабочую директорию и временную метку на внешний сервер. Он классифицируется как MAL-2026-11069 по стандарту CWE-506 «Встроенный вредоносный код» и был замечен инструментами Google OSV.dev и Amazon Inspector. Документация, открытый интерфейс и автоматическая экспекуляция будут одинаковыми независимо от того, захватывает ли пэйлоад имя пользователя или устанавливает полноценный бэкдор. Механизм распространения — это уязвимость, а пэйлоад является лишь вариантом её реализации.

Информация о проблеме была передана команде по безопасности Clerk, которая быстро отреагировала и устранила её. В отчёте подчёркивается, что это не критика в адрес Clerk. Пакет зарегистрировала третья сторона, воспользовавшись путаницей с именем npx, и Clerk не имела над этим контроля. Команда представляет это как подтверждённый пример реальной проблемы структуры, существующей у любого поставщика, публикующего документацию, читаемую агентами.

Почему существующие механизмы контроля могут её не заметить

Все сигналы, на которых основывается система безопасности, здесь указывают в неверном направлении. Агент, обнаруживающий файл llms.txt, видит файл, предоставляемый по HTTPS с официального домена в стандартном формате, предназначенном для использования ИИ, опубликованный компанией или её доверенным партнёром. У агента почти нет причин сомневаться в этом, поскольку сам файл является источником авторитетных данных по своей сути.

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

Доверие также является транзитивным. Файл llms.txt не обязательно должен находиться на сайте целевой компании. Агенты берут необходимую информацию из надежных третьих сторон, таких как документация партнера, руководство SDK поставщика или страница настройки проекта сообщества. Если агент доверяет этой третьей стороне, а файл этой стороны указывает на пакет, за которым никто не претендует, цепочка доверия функционирует аналогичным образом.

Детекция конечных точек тоже не сработала. Для инструмента EDR или прокси это выглядит как работа разработчика с законным менеджером пакетов: команда pip install в адрес pypi.org, домена, который разрешен каждым корпоративным прокси, при этом родительским процессом выступает агент для программирования, намеренно развернутый компанией. Аномалий и оповещений нет. Проблема находится на более раннем этапе, в промежутке между получением инструкции и её выполнением, и конечная точка не может её обнаружить, поскольку ей так и не был задан правильный вопрос.

Данные превращаются в код

На протяжении десятилетий контент потребляли люди. Теперь искусственные интеллектуальные агенты часто первыми его читают, интерпретируют и принимают по нему действия. В этом и заключается категориальная ошибка, в которую вместе впало всё сообщество: граница между данными и кодом исчезла. Всё, что находится на вашем веб-сайте, больше не является просто контентом — это операционный ввод, фактически код, выполняющийся в чужой среде с теми привилегиями, которыми обладает агент.

Это опровергает старое предположение. Раньше страницы и документы по определению считались малорисковыми, поскольку их никто не рассматривал как исполняемые файлы, поэтому никто не выделял средств на обеспечение их целостности. Когда данные становятся кодом, целостность данных становится частью бюджета на безопасность.

Больше, чем один файл

llms.txt — это не вся поверхность атаки. Это первая трещина, указывающая на то, что основа изменилась. Каждая поверхность, к которой подключен агент, превращается в место, куда могут поступать инструкции, и ни одно из этих мест не было разработано с учетом проверок целостности.

Подумайте о том, что на самом деле получает агент: официальные репозитории GitHub, документация, сообщества и форумы, ваши заявки и электронная почта. В течение двадцати лет это был контент, написанный для людей, и никто не внедрял механизмы контроля целостности, потому что контент не мог ничего сделать. Такой мир исчез. Весь объем данных, к которым подключены агенты, тихо превратился в поверхность для выполнения действий.

Настоящей проблемой является не один файл и не один реестр. Сама природа данных изменилась, а индустрия безопасности все еще пытается поспеть за этими изменениями.

Цифры, стоящие за исследованием

  • Размер корпуса: 8,565 файлов llms.txt с 6,214 доменов, взятых из списка примерно 15,000 компаний.
  • Более 237 незабранных элементов, представляющих собой инструкции по установке или настройке: названия пакетов, домены и поддомены. Исследователи утверждают, что все они могли быть забраны, причем большинство — бесплатно.
  • Было затронуто шесть экосистем: PyPI, npm, RubyGems, NuGet, crates.io и Packagist. Что касается доменов, то это просроченные имена .dev и .io, а также заброшенные поддомены на платформах Render, Vercel, Fly и Netlify, все из которых доступны для захвата.

Что могут извлечь защитники

Исследователи описывают llms.txt как лишь первый элемент, который они изучили, и ожидают обнаружения дополнительных способов нарушения безопасности. Из их отчета следуют некоторые практические выводы:

  • Проведите аудит файлов, предназначенных для ваших агентов. Каждое имя пакета, домен и поддомен, упомянутые в них, должны быть зарегистрированы, находиться в вашем владении и находиться под контролем.
  • Запускайте команды из документации, используя полное имя пакета. Простое имя бинарного файла может быть разрешено в отношении публичного реестра, если локальная установка еще не производилась.
  • Рассматривайте документацию от сторонних разработчиков, которую используют ваши агенты, как часть цепочки поставок, поскольку доверие передается через нее.
  • Помните, что стандартные инструменты для работы с конечными точками воспринимают обычную установку пакета и не будут ее фиксировать, поэтому меры контроля должны применяться на более ранних этапах — при формировании команд и при поиске в реестре.

Согласно заявлению о раскрытии информации, в ходе эксперимента ущерб не был причинен. Никакая информация не сохранялась, данные не извлекались; результаты исследования добросовестно сообщаются затронутым организациям, а названия компаний скрываются до завершения устранения проблемы.

Связанная литература

  • Практические заметки: разработчики TypeScript неправильно используют Zod. Это не просто... — Подробное руководство по «Практическим заметкам: разработчики TypeScript неправильно используют Zod. Это не просто...»: контракты, проверки и готовые блоки кода для команд, применяющих эту парадигму.