Claude Code — ИИ-ассистент для программирования от Anthropic — сохраняет команды, которые разработчик одобрил кнопкой «Yes, and don't ask again», в файл проекта .claude/settings.local.json. Если в команде был пароль или токен, он попадает туда же — открытым текстом. Компания Apiiro, занимающаяся безопасностью ПО, нашла на публичном GitHub 1 122 копии этого файла, где лежит хотя бы один секрет. Проверять, работают ли эти ключи, исследователи не стали, но одна компания, которую они уведомили, подтвердила: её ключ был действующим.
Как секрет попадает в файл проекта
По умолчанию Claude Code спрашивает разрешение перед запуском большинства shell-команд. Выбор «Yes, and don't ask again» записывает правило в .claude/settings.local.json внутри проекта, и дальше подходящие команды выполняются без вопросов. Правило покрывает только то, что предлагалось в запросе: иногда это шаблон вроде npm test *, иногда одна точная команда. Во втором случае любой пароль или токен, набранный в ней, сохраняется дословно.
В публичных файлах исследователи находили сохранённые команды вместе с секретами и воспроизвели поведение на последних моделях — Opus 5.5 и Fable 5.1.
Claude Code пытается не пускать файл в git: при первой записи в репозитории он добавляет его в глобальные исключения git пользователя, и git на этой машине игнорирует файл во всех репозиториях. Но защита живёт в настройках одного пользователя на одном компьютере и ничего не делает для файла, который уже попал в коммит. В .gitignore самого проекта Claude Code файл не добавляет, так что защита не переезжает вместе с проектом. В 539 из 1 105 отслеженных репозиториев файл менял коммит, где Claude указан соавтором, — исследователи считают, что ассистент нередко коммитит файл сам.
Что именно нашла Apiiro
Поиск по публичному GitHub дал 104 185 копий файла в 103 617 репозиториях. Примерно 1,1% из них — 1 122 копии — содержат хотя бы один секрет, всего 1 379 различных секретов. Значение считалось секретом, если совпадало с известным форматом ключа или если пароль либо токен стоял рядом с адресом публичного сервера; вердикт должен был подтвердить ещё и ИИ-ревьюер.
- 379 паролей от баз данных; больше трети всех секретов открывают доступ к базе напрямую;
- 43 логина SSH к публичным серверам;
- 42 токена для GitHub, GitLab и npm;
- 23 ключа AWS.
Среди владельцев файлов — 63 организации, в основном софтверные компании разного размера. Самые серьёзные случаи: администраторский облачный ключ самого вендора баз данных и пароль владельца базы медицинских записей.
На понедельник каждая копия с секретом всё ещё была в основной ветке своего репозитория, а в половине репозиториев файл лежал там минимум 217 дней. Удаление файла утечку не отменяет: старые версии остаются в истории git и в форках. Ещё 734 секрета в 509 репозиториях есть только в прежних версиях файла — обычно потому, что файл удалили. Форки разнесли его дальше: 211 форков 74 репозиториев несут те же секреты, что и оригиналы.
Секреты нашлись и в 298 из 76 011 копий общего .claude/settings.json — его команды коммитят намеренно, чаще всего внутри allow-правил. С учётом старых версий и сохранённых журналов чатов агента общий итог — 2 539 секретов в 1 994 репозиториях.
Из 16 кодирующих агентов, чью документацию сравнивали исследователи, Claude Code — единственный, про кого подтверждено, что он по умолчанию сохраняет полную одобренную команду в файле проекта.
Что делать разработчику
Apiiro советует такой порядок:
- Ищите
.claude/settings.local.jsonи.claude/settings.jsonпо всей организации на GitHub и проверяйте историю git каждого репозитория — даже там, где файлов уже нет. - Сначала смените все пароли, токены и ключи, которые файлы когда-либо содержали, и только потом чистите.
- Снимите локальный файл с отслеживания:
git rm --cached .claude/settings.local.json, и добавьте его в.gitignoreсамого репозитория. - Откройте файл на своей машине, даже если он никогда не коммитился, и удалите все правила с секретами.
- Не держите секреты в командах — подставляйте переменные из менеджера секретов, например
$DB_URL, тогда в правиле останется имя переменной. - Одобряйте шаблоны вроде
Bash(npm run:*), а не отдельные команды.
Копии, которые не дошли до GitHub, тоже важны: это обычный JSON в папке проекта, и он может уехать внутрь npm-пакета, Docker-образа, zip-архива или синхронизируемой папки. Вредоносное ПО уже искало секреты на машинах разработчиков: в сентябре 2025 года червь Shai-Hulud прогонял по заражённым компьютерам сканер TruffleHog, и тот пометил больше половины файлов как содержащие секреты.
Обычные сканеры секретов такие файлы часто пропускают. Исследователи прогнали gitleaks и TruffleHog по всем копиям без шага верификации: из 1 122 файлов с секретом gitleaks отметил 564, TruffleHog — 643, а 215 не нашёл ни один. Большинство промахов — пароли внутри команд: сканеры ищут известные форматы ключей, а пароль после PGPASSWORD=, sshpass -p или mysql -p выглядит как обычное слово в обычной командной строке.
Что делать безопаснику
- Считайте папки агентов —
.claude/,.cursor/,.gemini/,.specstory/— и файлы памяти агентов хранилищами секретов наравне с.env, и на ноутбуках, и в репозиториях. - Добавьте их в pre-commit и CI-сканирование секретов вместе с историей git и убедитесь, что сканер ловит пароли внутри команд, а не только известные форматы ключей.
- Внесите
.claude/settings.local.jsonв шаблоны.gitignoreорганизации. - В первую очередь проверяйте учётные данные, привязанные к публичному серверу: именно они дают доступ.
О проблеме сообщали и раньше. Баг-репорт от 11 августа 2025 года говорил, что одобренные команды с API-ключами и токенами сохраняются в settings.local.json дословно. Автоматический бот закрыл его как «not planned» 3 января, после 60 дней без активности. На сегодня все четыре связанных отчёта, на которые ссылаются исследователи, закрыты тем же ботом, последний — вчера. Ответа от Anthropic, по их словам, не получил ни один.
Для российских команд, которые используют Claude Code в разработке, практика та же: файл лежит в проекте, а не в защищённом хранилище, и при публикации репозитория уезжает наружу вместе с историей. Если доступ к Claude Code ограничен, это не отменяет проверку уже существующих репозиториев — секреты в них остаются читаемыми. Смежная проблема из того же семейства — побег ИИ-агента Claude Cowork из виртуальной машины: там речь о границах изоляции, здесь — о том, что агент складывает в проект по своей воле.
Частые вопросы
Кого это касается в первую очередь?
Тех, кто одобрял в Claude Code точные команды с паролями или токенами и чей проект попадал в публичный GitHub. Apiiro насчитала 1 122 таких файла в 103 617 репозиториях и 63 организации среди владельцев.
Файл удалён из репозитория — утечка закрыта?
Нет. Старые версии остаются в истории git и в форках; 734 секрета живут только в прежних версиях файла в 509 репозиториях, а 211 форков 74 репозиториев несут те же секреты, что оригиналы. С историей git приходится разбираться и в других случаях — например, когда path traversal в GitLab с CVSS 10 заставляет пересматривать доступ к репозиториям.
С чего начинать — с ротации или с очистки?
С ротации. Исследователи прямо советуют сначала сменить все пароли, токены и ключи, которые файл когда-либо содержал, и лишь потом чистить историю и файлы.
Как перестать коммитить файл?
Снять с отслеживания командой git rm --cached .claude/settings.local.json и добавить путь в .gitignore репозитория. Глобальные исключения git, которые Claude Code прописывает сам, действуют только на одной машине и не спасают уже сделанные коммиты.
Как одобрять команды, чтобы секреты не сохранялись?
Одобрять шаблоны вроде Bash(npm run:*), а не отдельные команды, и подставлять секреты переменными из менеджера секретов — например $DB_URL. Тогда в правиле останется имя переменной, а не значение.
Поймает ли это gitleaks или TruffleHog?
Часто нет. Из 1 122 файлов с секретом gitleaks отметил 564, TruffleHog — 643, а 215 не нашёл ни один: сканеры ищут известные форматы ключей и пропускают пароли после PGPASSWORD=, sshpass -p или mysql -p. Похожая история с инструментами, которые ищут уязвимости по формальным признакам: эксплуатация OpenSSH SSHole началась через несколько часов после раскрытия, и сигнатурные проверки тут запаздывают так же, как проверки форматов ключей.
Какие секреты утекали чаще всего?
Больше трети открывают базу данных напрямую, включая 379 паролей. Дальше идут 43 логина SSH к публичным серверам, 42 токена GitHub, GitLab и npm и 23 ключа AWS.
Это уже исправлено в Claude Code?
В статье нет сведений об исправлении. Известно, что четыре связанных баг-репорта закрыл автоматический бот, последний — 6 ноября, и ответа от Anthropic авторы отчётов не получили.
Достаточно ли проверить только репозитории на GitHub?
Нет. Файл может остаться в npm-пакете, Docker-образе, zip-архиве или синхронизируемой папке, поэтому его стоит проверить и на машинах разработчиков, даже если он никогда не коммитился.
Чем это отличается от утечки .env?
.env обычно попадает в репозиторий по недосмотру, а здесь секрет сохраняет сам инструмент — в правиле разрешения, которое выглядит как обычная настройка проекта. Поэтому такие папки, как .claude/, .cursor/, .gemini/ и .specstory/, безопасники советуют считать хранилищами секретов наравне с .env.
Источник: thehackernews.com