Claude Code сохраняет пароли из команд в файл — на GitHub таких 1 122

Ответ «Yes, and don't ask again» записывает команду вместе с паролем в .claude/settings.local.json, а защита от коммита есть только на одной машине.

Обложка: Claude Code сохраняет пароли из команд в файл — на GitHub таких 1 122

Claude Code, консольный кодинг-агент Anthropic, при выборе ответа «Yes, and don't ask again» сохраняет одобренную команду в файл .claude/settings.local.json внутри проекта, и если в ней был пароль или токен, он остаётся там открытым текстом. Исследователи компании Apiiro Шмулик Коэн (Shmulik Cohen) и Матан Гилади (Matan Giladi) 5 ноября 2026 года опубликовали результаты сканирования публичного GitHub: из 104 185 копий этого файла 1 122 содержат хотя бы один секрет.

Проверить себя стоит каждому, кто подтверждает команды Claude Code вручную и подставляет секреты прямо в командную строку: PGPASSWORD=... psql, sshpass -p, curl с заголовком Authorization. Файл задуман как личный, но от коммита его защищает только глобальная настройка git на одной машине, в самом репозитории защиты нет. Исправления в Claude Code на 9 ноября нет, бюллетеня безопасности и номера CVE по этой теме Anthropic не публиковала. Борис Черный (Boris Cherny) из команды Claude Code ответил в обсуждении на Hacker News, что команда ищет способ это предотвратить.

Ключевые выводы
  • Apiiro нашла 104 185 публичных копий .claude/settings.local.json в 103 617 репозиториях GitHub; в 1 122 файлах (1,1%) лежит хотя бы один секрет, всего 1 379 уникальных значений. Данные собраны 1–3 ноября 2026 года.
  • С учётом истории git, общего файла .claude/settings.json и сохранённых в репозиториях переписок с агентами набралось 2 539 секретов в 1 994 репозиториях.
  • Секреты никто не проверял на действительность: Apiiro не использовала ни один ключ. Одна из 63 затронутых организаций подтвердила, что её ключ был рабочим.
  • Сканеры видят не всё: из 1 122 файлов gitleaks пометил 564, TruffleHog 643, а 215 файлов не пометил ни один.
  • Что делать: убрать файл из индекса командой git rm --cached, добавить его в .gitignore репозитория и заменить все секреты, которые когда-либо попадали в одобренные команды.

Как пароль из команды попадает в файл настроек?

Через правило разрешения, которое Claude Code создаёт по вашему ответу. В ручном режиме (Manual) агент спрашивает подтверждение перед shell-командами. По документации о разрешениях, одобрение Bash-команды с «don't ask again» действует постоянно для репозитория и команды: правило записывается в .claude/settings.local.json в корне git-репозитория и применяется во всех будущих сессиях. Одобрение правки файла живёт только до конца сессии и в файл не попадает.

Правило хранит текст команды или её начало. Если Claude собрал команду со строкой подключения из вашего конфига, пароль становится частью правила. Apiiro показывает это на запросе к PostgreSQL: вариант 2 в диалоге предлагает запомнить префикс команды вместе с переменной PGPASSWORD.

Claude Code сохраняет пароли из команд в файл — на GitHub таких 1 122_6
Диалог подтверждения Claude Code с командой psql: пароль вымышленный, хост зарезервированный. Изображение: Apiiro

После такого ответа в файле появляется запись (пример Apiiro, формат правил по документации Claude Code):

			{
  "permissions": {
    "allow": [
      "Bash(PGHOST=orders-db.example.invalid PGPORT=5432 PGUSER=orders_admin PGDATABASE=orders PGSSLMODE=require PGAPPNAME=orders-backfill-2026-11 PGCONNECT_TIMEOUT=15 PGPASSWORD=Fk7pQ2xT9mWv4Lz psql *)"
    ]
  }
}
		

По данным Apiiro, это поведение самого Claude Code и от модели не зависит: его воспроизвели с Opus 5.5 и Fable 5.1. Исследователи сравнили по документации 16 кодинг-агентов и пишут, что только у Claude Code подтверждена запись полной одобренной команды в файл проекта по умолчанию.

Почему файл оказывается в git, если Claude Code его прячет?

Потому что прячет он его только на вашей машине. В документации о настройках сказано: при первой записи файла в git-репозитории, который его ещё не игнорирует, Claude Code добавляет шаблон **/.claude/settings.local.json в глобальный файл исключений git. Это файл из настройки core.excludesFile, а если она не задана, $XDG_CONFIG_HOME/git/ignore или ~/.config/git/ignore. В .gitignore самого репозитория ничего не пишется, поэтому вместе с проектом защита не переезжает.

Apiiro перечисляет случаи, когда глобального исключения недостаточно: новая машина или контейнер, где его нет, скопированная папка проекта, файл, который уже однажды закоммитили. Последний случай описан в документации git: правила игнорирования не действуют на уже отслеживаемые файлы. Документация Claude Code признаёт такой сценарий: отслеживаемый .claude/settings.local.json агент считает «файлом из репозитория» и просит подтвердить доверие к папке. По наблюдению Apiiro, пользователя о самом факте отслеживания не предупреждают, а следующее одобрение дописывается в тот же файл. Как устроены уровни исключений, мы разбирали в гайде по .gitignore.

The part people don't expect: the file is created inside the project, and Claude Code only adds it to your global git ignore, not the repo's .gitignore.
shmulcисследователь Apiiro, автор публикации на Hacker News (перевод: «Чего люди не ожидают: файл создаётся внутри проекта, и Claude Code добавляет его только в ваш глобальный git ignore, в .gitignore репозитория он не попадает»)

Отдельная цифра исследования: в 539 из 1 105 прослеженных репозиториев с секретом файл менял коммит, где Claude указан соавтором. Apiiro делает вывод, что агент часто коммитит файл сам. Это наблюдение о подписи коммита: оно не доказывает, что каждый секрет добавил и отправил в репозиторий именно агент. Участники обсуждения возражали и против заголовка. Пользователь Aurornis заметил, что само нажатие «don't ask again» ничего не публикует: нужно ещё закоммитить локальные настройки и выложить репозиторий.

Сколько секретов нашли и чьи они?

В текущих версиях файла на GitHub нашлось 1 379 уникальных секретов в 1 122 файлах из 104 185. Из них 636 ключей в формате известных провайдеров и 743 пароля или токена, записанных рядом с адресом публичного сервера. Больше трети открывают базу данных напрямую.

Claude Code сохраняет пароли из команд в файл — на GitHub таких 1 122_17
Типы 1 379 уникальных секретов в публичных копиях .claude/settings.local.json; строка «прочие» получена вычитанием названных категорий из общего числа. График: Tproger по данным Apiiro

Остальные цифры исследования:

  • 2 539 уникальных секретов в 1 994 репозиториях, если считать историю файла, общий .claude/settings.json и сохранённые переписки с агентами;
  • 734 секрета в 509 репозиториях остались только в старых версиях файла: чаще всего его удалили, но история git хранит прежнее содержимое;
  • 211 форков 74 репозиториев несут те же секреты, что и оригиналы;
  • на 2 ноября 2026 года каждый файл с секретом лежал в основной ветке; в медианном репозитории он впервые закоммичен за 217 дней до этой даты, в 118 репозиториях больше года назад.

Среди владельцев 63 организации, от студенческих команд до стартапов и ИТ-компаний; большинство файлов принадлежит отдельным разработчикам. Названий Apiiro не раскрывает и приводит обезличенные примеры: облачный API-ключ с правами управления у разработчика СУБД, пароль продакшен-базы Azure Postgres у B2B-стартапа, пароль владельца базы приложения с медицинскими записями. Организациям сообщили 2 и 3 ноября, Anthropic уведомили до публикации.

Секреты в командах нашлись и в других файлах, которые оставляют агенты:

Где ещё нашлись секреты

5 сервисов, 3 столбца
Где ещё нашлись секреты
Тип файлаПровереноС секретом
Общий .claude/settings.json76 011 (все найденные)298 файлов
Переписки с агентами (.specstory, aider, экспорт Cursor)2 523120 файлов в 87 репозиториях
Файлы памяти агентов (MEMORY.md и похожие)1 2009 репозиториев
Заметки о передаче дел и деплое2 09533 файла
Настройки автоодобрения VS Code Copilot1739 репозиториев
Листайте столбцы →Смахните влевоВсе 3 столбца
Apiiro, сбор 1–3 ноября 2026 года

Ограничения названы в самом исследовании. Ни один ключ не использовали, поэтому «секрет» здесь означает значение в формате известного провайдера либо пароль рядом с публичным адресом, без подтверждения, что доступ действует. Кандидатов отбирали правилами, затем 2 774 значения в замаскированном виде оценивала ИИ-модель по письменной рубрике. Приватные репозитории не измерялись. Apiiro продаёт продукты для безопасности приложений, включая поиск секретов, и в теме заинтересована.

Почему сканеры секретов это пропускают?

Потому что пароль внутри команды не похож на ключ. Apiiro прогнала gitleaks и TruffleHog по всем 104 185 файлам, без этапа проверки ключей на действительность.

Сколько из 1 122 файлов с секретами пометили сканеры

3 сервиса, 3 столбца
Сколько из 1 122 файлов с секретами пометили сканеры
СканерФайловДоля
TruffleHog64357,3%
gitleaks56450,3%
Не пометил ни один21519,2%
Листайте столбцы →Смахните влевоВсе 3 столбца
Apiiro; доли рассчитаны Tproger

Оба инструмента ищут форматы ключей: префикс провайдера, длинную случайную строку. Пароль после PGPASSWORD=, sshpass -p, mysql -p или токен в заголовке curl выглядит обычным словом в обычной команде. Вывод для практики: чистый отчёт сканера по каталогу .claude не означает, что секретов там нет.

Что ответила команда Claude Code?

Борис Черный, которого Apiiro называет руководителем Claude Code в Anthropic, 7 ноября пришёл в обсуждение на Hacker News (621 балл и 417 комментариев к 9 ноября).

Historically Claude Code has not done secret scrubbing (there are many good tools for that), but we are looking into what we can do to prevent this.
Борис Черный (Boris Cherny)команда Claude Code, Anthropic (перевод: «Исторически Claude Code не вычищал секреты, для этого есть много хороших инструментов, но мы изучаем, что можем сделать, чтобы это предотвратить»)

Дальше в том же комментарии три тезиса. Первый: файл должен оставаться локальным, Claude Code сам добавляет его в исключения git при создании, поэтому найденные копии, по мнению Черного, были созданы и закоммичены вручную. Второй: правила разрешений он назвал устаревшим подходом и советует автоматический режим, где действия проверяет классификатор; по словам Черного, он включён по умолчанию и доступен на всех тарифах. О переносе этого классификатора на сервер мы писали в сентябре. Третий: включить сканирование секретов на хостинге кода.

Когда читатель заметил, что автоматический режим тоже спрашивает о чувствительных командах и предлагает запомнить ответ, Черный согласился: «Yeah good catch». О планах он сказал так:

There's a few possible approaches: making sure auto mode catches this, building in basic secret scanning, a few other ideas. Going to prototype a few of these to understand the tradeoffs better before we ship something.
Борис Черный (Boris Cherny)команда Claude Code, Anthropic (перевод: «Есть несколько возможных подходов: добиться, чтобы авторежим это ловил, встроить базовое сканирование секретов, ещё пара идей. Сделаем прототипы нескольких вариантов, чтобы лучше понять компромиссы, прежде чем что-то выпускать»)

Сроков он не назвал. Механизм при этом известен давно: issue 5544 с описанием того, как одобренные команды с ключами дословно сохраняются в .claude/settings.local.json, пользователь asherfeldmangit открыл 11 августа 2025 года. 3 января 2026 года его закрыл бот github-actions с пометкой «not planned» после 60 дней без активности. Apiiro ссылается ещё на три обращения (11982, 13106, 91270); по данным GitHub, все они тоже закрыты ботом как неактивные или дубликаты, а ответа Anthropic, как пишут исследователи, не получило ни одно. В феврале 2026 года тот же случай на собственном репозитории описал в блоге ironPeak Нильс Хофманс (Niels Hofmans): закоммиченный файл содержал все одобренные команды с паролями баз и API-ключами.

Как проверить свой репозиторий и что делать с найденным?

Сначала выясните, отслеживается ли файл и был ли он в истории, затем замените секреты и только потом чистите. Команды выполняются в корне репозитория.

			# отслеживает ли git файлы настроек Claude Code
git ls-files .claude/
# попадал ли локальный файл в историю хотя бы раз, во всех ветках
git log --all --oneline -- .claude/settings.local.json
# какое правило игнорирует файл; --no-index нужен, чтобы команда ответила и для отслеживаемого файла
git check-ignore -v --no-index .claude/settings.local.json
# все копии файла на своей машине
find ~ -path '*/.claude/settings.local.json' 2>/dev/null
		

В организации на GitHub оба файла находит поиск по коду: org:ВАША-ОРГАНИЗАЦИЯ path:.claude/settings.local.json и такой же запрос для .claude/settings.json. Откройте каждый файл и прочитайте список allow; в самом Claude Code правила показывает команда /permissions. Сканеры ловят не всё, поэтому добавьте поиск по шаблонам, которые называет исследование:

			grep -nE 'PGPASSWORD=|sshpass -p|mysql .*-p|Bearer |://[^/ ]+:[^@ ]+@' .claude/settings.local.json
# сканеры по истории репозитория, команды из их README
gitleaks git -v
gitleaks dir -v .claude/
trufflehog git file://.
		

Если git check-ignore показывает правило из файла вне репозитория, защита есть только на этой машине. Отслеживаемый файл никакое правило не защищает. Для него Apiiro и документация git дают один рецепт:

			git rm --cached .claude/settings.local.json
echo '.claude/settings.local.json' >> .gitignore
git add .gitignore
git commit -m "Stop tracking Claude Code local settings"
		

Команда убирает файл из индекса и оставляет на диске. Из истории, форков и чужих клонов секрет никуда не девается, поэтому порядок такой:

  1. Отзовите или замените каждый секрет, который когда-либо был в файле. Инструкция GitHub об удалении чувствительных данных называет это первым шагом и отмечает, что его может оказаться достаточно.
  2. Удалите правила с секретами из локального файла, даже если он никогда не коммитился.
  3. Если историю нужно переписать, GitHub предлагает git-filter-repo версии 2.47 или новее. Работают в отдельном свежем клоне, сохранив локальные изменения: git-filter-repo --sensitive-data-removal --invert-paths --path .claude/settings.local.json, затем git push --force --mirror origin. Хеши коммитов изменятся, подписи сломаются; остальные клоны GitHub советует пересоздать либо тщательно очистить, иначе старая история вернётся со следующим push.
  4. Проверьте, включено ли сканирование секретов. По документации GitHub, в публичных репозиториях оно работает автоматически и бесплатно. На других хостингах и в приватных проектах ту же роль выполняют gitleaks и TruffleHog в pre-commit и CI.

Чтобы история не повторилась, Apiiro советует не вписывать секреты в команды: пусть команда ссылается на переменную окружения, тогда в правиле останется $DB_URL вместо пароля. Одобрять лучше шаблоны вроде Bash(npm run:*), чем одиночные команды со строкой подключения. К каталогам .claude/, .cursor/, .gemini/ и .specstory/ исследователи рекомендуют относиться так же, как к .env.

Чего ждать дальше?

Конкретных обещаний пока нет. Черный говорил о прототипах без дат, а в списке изменений версии 2.1.321, последней на 9 ноября, защиты от записи секретов в правила нет. Это вторая за неделю история о данных пользователей Claude Code: 7 ноября мы разбирали, как агент подставлял email аккаунта в User-Agent.

Источники: Apiiro: Coding Agents Copy Your Secrets to a Hidden File. Thousands Are on GitHub, Hacker News: обсуждение исследования и ответы Бориса Черного, Claude Code Docs: Permissions, Claude Code Docs: Settings, Git: документация gitignore, GitHub: issue 5544 в anthropics/claude-code, ironPeak: Leaking secrets from the claud, GitHub Docs: Removing sensitive data from a repository, GitHub Docs: Secret scanning

Изображение на обложке: Tproger по данным Apiiro