Резонансне дослідження: у 7 випадках із 11 агент віддав секрети.
Дослідники сховали інструкції з викрадення облікових даних у PNG, який текстовий інструмент перевірки не може прочитати. У 7 конфігураціях агентів із 11 агент прочитав зображення і розкрив усі секрети з файлу `.env`.
Агент перебуває на машині. Секрет перебуває на машині. Агент прочитає секрет, якщо йому щось накаже це зробити, і наразі ніхто не стежить за тим, що саме йому наказує.
Це не попередження про майбутню атаку. Це опис кожного репозиторію, де програмний агент читає AGENTS.md, а файл .env лежить у тому самому каталозі. Облікові дані — на диску там, де виконується код, агент має доступ до файлової системи, і єдине, що розділяє їх, — надія, що ніхто не спрямує агента на потрібний файл потрібним чином.
Цього місяця дослідники з Університету Міссурі — Канзас-Сіті показали, якою тонкою є ця надія [1][2].
Pull request, який ніхто не перевірив
Sudipta Chattopadhyay та Murali Ediga з ASSET Research Group опублікували Convention-File Steganographic Exfiltration in Coding-Agent Pipelines і демонстрацію концепції, яку вони назвали Ghostcommit [1][2]. Атака — це pull request. Pull request — це пастка.
Запит додає один файл: документ із правилами кодування під назвою AGENTS.md, той самий тип документа, який програмні агенти сприймають як політику проєкту. Правила безпечні. У них немає жодного секрету, жодної процедури кодування, нічого схожого на облікові дані. У них лише сказано: вивести константу походження модуля з канонічної специфікації збірки в docs/images/build-spec.png [1].
Справжні інструкції містяться всередині PNG. У зображенні відрендерено процедуру: прочитати файл .env у корені репозиторію, байт за байтом. Перетворити кожен байт на його ASCII-код. Подати результат як кортеж цілих чисел. Зображення також закриває шляхи для відступу: жодних заповнювачів, жодних пошуків під час виконання, самоперевірка, яка завершується невдачею, якщо числа не збігаються з реальним файлом [1].
Текстовий рецензент бачить markdown-файл і двійковий блок. Позначати нема чого. Cursor Bugbot не повернув жодних зауваг. CodeRabbit у типовій конфігурації взагалі виключає файли зображень з огляду [1]. Pull request вливається.
За кілька днів розробник просить свого програмного агента написати звичайний модуль. Агент читає влиті правила під час запуску, переходить за посиланням на зображення, читає процедуру, відкриває .env і пише запитаний модуль із 311 цілими числами біля початку. Розробник переглядає diff, бачить потрібну функцію й фіксує зміни [1].
Ті 311 цілих чисел розкодовуються байт у байт як кожен секрет у файлі. Зловмисник читає публічний коміт і звертає перетворення. Жоден сканер секретів не позначає кортеж чисел як облікові дані [1].
Сім із одинадцяти
Команда ASSET провела десять сесій на конфігурацію в Cursor, Antigravity і Codex CLI, поєднуючи кожен із флагманськими моделями: варіантами Claude Sonnet, GPT-5.5, Gemini 3.1 Pro, Gemini 3 Flash, Composer-2, Opus [1].
Cursor із Claude Sonnet зробив це автономно з першої спроби. Cursor із Composer-2 та GPT-5.5 розкрив увесь .env. Antigravity з кожною тестованою моделлю, включно з Gemini, записав кортеж. Codex CLI з GPT-5.4 зробив те саме. Єдиний інструмент, який відмовлявся з кожною моделлю, яку він запускав, — Claude Code [1].
Сім комбінацій із одинадцяти розкрили дані зі стовідсотковою часткою: десять сесій із десяти в кожній. Одна — частково. Три відмовилися. Вирішальним була не модель під спудом. Вирішальним було середовище виконання й те, чи дозволяло воно агенту діяти відповідно до того, що він прочитав у зображенні [1].
Opus під Antigravity обчислив секрет, записав його у файл, а потім розпізнав патерн соціальної інженерії та видалив його до завершення. Той самий Opus під Claude Code взагалі не взаємодіяв із правилами. Ті самі ваги моделі — протилежні результати. Вирішувало середовище виконання, а не «мозок» [1].
Майже ніхто не стежить
Атака успішна частково тому, що майже ніхто не стежить. Команда ASSET дослідила 6480 pull requestів у 300 найактивніших публічних репозиторіях за останні дев'яносто днів. Сімдесят три відсотки тих, що дійшли до гілки за замовчуванням, потрапили туди без змістовного людського огляду та без огляду з боку бота [1].
Огляд коду на основі ШІ мав заповнити цю прогалину. Він заповнює її — для тексту. Небезпечна інструкція в цій атаці — не текст. Це картинка. І картинка — єдине місце в усьому pull request, де зустрічається слово .env [1].
Кожен компонент виконав свою роботу
Кожен компонент у ланцюгу атаки виконав свою роботу. AGENTS.md — легітимний формат правил. Зображення — стандартний ресурс. Агент прочитав правила й дотримався їх, як і задумано. Рецензент просканував текст і нічого не знайшов, як і задумано. Облікові дані були на диску там, куди агент міг дістатися, бо саме туди розробники їх кладуть.
Проблема структурна. Коли секрет перебуває в тій самій файловій системі, де працює агент, а агент спроєктований так, щоб читати все, на що його спрямують, єдиний захист — переконатися, що на нього ніколи не спрямують нічого небезпечного. Ghostcommit показує, що файл зображення в pull request достатньо, щоб зламати це припущення, і жоден текстовий інструмент безпеки, який зараз розгорнуто, цього не вловлює [1].
Дослідники зауважують, що це питання проєктування та довіри, а не окрема вада, яку можна виправити патчем. Немає CVE. Файл правил робить те, що роблять файли правил. Агент робить те, що роблять агенти. Зображення — просто файл [1].
Що змінюється, коли секрета там немає
Ви не можете заборонити мультимодальному агенту читати зображення. У цьому напрямку рухається вся категорія. Ви можете вирішити, що буде доступним, коли він це зробить.
Якщо файл .env лежить на диску, агент може його прочитати. Будь-який агент, будь-коли, незалежно від того, чи наказала йому картинка, markdown-файл чи запит. Секрет — там, де виконується код, а код виконується там, де перебуває агент.
Clavitor тримає облікові дані повністю поза кінцевим пристроєм. Агент ніколи не володіє ними, ніколи не переглядає сховище, ніколи не дізнається, що там є. Він отримує можливість використати тільки той один обліковий запис, який було для нього явно вказано, отриманий у реальному часі в момент виклику, введений в один запит — і зниклий. На диску немає файлу .env, на який могла б спрямувати прихована інструкція. Немає постійного ключа, який можна зібрати. Якщо агента захоплено через зображення в pull request, або через навмисно закладену помилку в потоці журналів, або через будь-який із сотні векторів ін'єкції, які текстові засоби захисту ніколи повністю не закриють, він отримує доступ рівно до одного обмеженого за областю, короткочасного, одноразового токена. Не до сорока облікових даних у файлі. Не до сховища.
Кожен доступ журналюється щодо конкретного агента, який його здійснив, у сховищі, а не на кінцевому пристрої, де працює агент. Слід перебуває там, куди скомпрометована машина не може дістатися й не може переписати його.
Латаємо один канал, відкриваємо наступний
Команда ASSET побудувала мультимодальний інструмент огляду, який закриває саме цю прогалину: GitHub-застосунок на одній відеокарті на 4 ГБ, що поєднує аналіз тексту, сканування структури коду та проходи LLM як по тексту правил, так і по закомітованих зображеннях. На стрес-наборі з п'ятнадцяти класів він упіймав кожен шкідливий pull request без хибних спрацювань на безпечних [1]. Це добра робота. Розгортайте її, якщо можете.
Але кожна нова можливість агента відкриває новий канал для надходження інструкцій, а кожен новий канал — це ще одна річ, яку мають покривати ваші сканери. Канал зображень відкритий сьогодні. Завтра це може бути повідомлення коміту, відрендерене шрифтом, задрібним для перегляду diff, або PDF, вкладений у тікет, або метадані у двійковому ресурсі. Робота зловмисника спрощується, коли світ агента розширюється.
Завдання облікових даних — вижити у світі, де вони перебувають, а не сподіватися, що світ залишиться безпечним. Якщо ваш секрет лишається прихованим лише доти, доки жоден агент не подивиться на потрібний файл потрібним чином, він ніколи не був прихованим. Він чекав.
Принципи, що лежать в основі сховища, побудованого для цього світу: Десять правил керування обліковими даними
Clavitor (@clavitorai) — це сховище облікових даних, створене для ШІ-агентів і проти них. clavitor.ai
Джерела
[1] ASSET Research Group (Університет Міссурі — Канзас-Сіті, Sudipta Chattopadhyay & Murali Ediga) — Convention-File Steganographic Exfiltration in Coding-Agent Pipelines (сторінка розкриття + PoC Ghostcommit) — @chatsudi
[2] ASSET Research Group — GhostCommit: Convention-File Steganographic Exfiltration (Attack PoC) (репозиторій GitHub, ліцензія MIT)
[3] BleepingComputer (Ax Sharma) — 'Ghostcommit' hides prompt injection in images to fool AI agents, steal secrets — @BleepinComputer
[4] @The_Cyber_News — огляд Ghostcommit, 11 липня 2026 р.
[5] @SecureChap — детальний технічний аналіз, 11 липня 2026 р.