Claude Code хранит MCP-токены на Linux в открытом виде

Claude Code 2.1.257 хранит на Linux OAuth-токены удалённых MCP-серверов в обычном JSON-файле. Защищают его только права доступа, хотя документация по MCP называет такое хранение безопасным. Это показал разбор, опубликованный 2 сентября в блоге Secretspec.
Автор подключился к нескольким удалённым MCP-серверам и открыл ~/.claude/.credentials.json. Режим у файла 0600, как и положено. Но на верхнем уровне в нём лежит объект mcpOAuth с токенами доступа. Для примера автор привёл запись для сервера cloudflare-observability, скрыв все значения: в ней есть поля accessToken, clientId, discoveryState, redirectUri, serverName и serverUrl.
Ошибки или регрессии тут нет: поведение совпадает с документацией Anthropic по управлению учётными данными. На macOS используется зашифрованный Keychain, а если он недоступен, Claude Code откатывается на тот же файл. На Linux это ~/.claude/.credentials.json с режимом 0600, на Windows %USERPROFILE%\.claude\.credentials.json, который наследует права профиля пользователя. Основной логин Claude Code устроен так же. Судя по разбору в публичном гисте на GitHub, на Linux, в WSL и в нативной Windows в том же файле лежит объект claudeAiOauth с accessToken, refreshToken и сроком действия. Там же сказано, что на macOS Claude Code сам удаляет этот файл и переносит данные в Keychain.
По словам автора, это «куда более узкое утверждение», чем то, что обычно слышат в словах «хранится безопасно». Режим 0600 закрывает файл от других учётных записей на той же машине. Против кода, запущенного от вашего имени, он бесполезен: такой код читает файл без всяких препятствий. А такой код в экосистеме Claude Code уже появлялся. Например, исследование GitSpawn описывало, как команда из Git-конфига недоверенного репозитория запускается с правами пользователя ещё до запроса разрешения. На Linux от такого кода токены MCP-серверов отделяет всего лишь стандартный бит прав.
Разбор объясняет, почему эту проблему легко пропустить. Запускаешь claude mcp login, подтверждаешь доступ в браузере и возвращаешься к подключённому серверу. Токен никто не создавал вручную, не копировал из панели и не вставлял в конфиг. Но Claude Code всё равно получил учётные данные и должен их где-то хранить, иначе соединение не переживёт перезапуск.
OAuth здесь действительно полезен. Клиент сам находит сервер авторизации, запрашивает конкретные права (scopes), обменивает код авторизации на токен, обновляет токен и умеет отозвать доступ. Документация Anthropic по MCP также позволяет зафиксировать набор прав, которые запрашивает Claude Code. Но хранить токен локально OAuth не помогает: это bearer-токен, которым пользуется любой, кто им завладел. В сравнительной таблице автора и OAuth-токен, и обычный API-токен с ограниченными правами одинаково можно переиспользовать после кражи. OAuth отвечает за то, как клиент получает и продлевает делегированный доступ. Где этот доступ лежит между использованиями - отдельный вопрос.
Авторы разбора, разработчики SecretSpec, предлагают сделать слой хранения заменяемым. OAuth-клиент Claude Code обращается к интерфейсу хранилища учётных данных, тот работает через TypeScript SDK SecretSpec, а SDK уже ходит к провайдеру, которого выбрал пользователь или организация. В SDK встроен резолвер на Rust, поэтому на стороне TypeScript не нужен отдельный код под каждый бэкенд. Claude Code сериализовал бы учётные данные каждого MCP-сервера отдельно и просил SecretSpec загрузить, сохранить или удалить их. В SecretSpec 0.20 есть 33 интеграции: локальные связки ключей, менеджеры паролей, зашифрованные файлы, облачные хранилища секретов. Сейчас SDK даёт только независимый от провайдера резолвер, и узкие операции get/set/delete под Claude Code авторы обещают добавить сами.
Системную связку ключей по умолчанию предлагается включать так: secretspec config global init --provider keyring --profile default. Команда может потребовать OpenBao или облачное хранилище секретов, а машина без графической оболочки может использовать хранилище, зашифрованное через age. Сам OAuth-поток при этом не меняется, меняется только место хранения.
В Codex хранение MCP-токенов уже настраивается. В справочнике по конфигурации описаны бэкенды auto, file и keyring, а строка mcp_oauth_credentials_store = "keyring" переключает его на системную связку ключей. Автор оговаривается, что это не универсальный интерфейс к провайдерам секретов. Но на Linux открытый файл перестаёт быть единственным вариантом.
С открытыми проектами SecretSpec уже действует напрямую: выпустил помощники учётных данных для Git и Docker и предложил Nix общий интерфейс резолвера секретов. С Claude Code так не получится. В публичном репозитории нет основной реализации CLI, а лицензия - «все права защищены». «Мы можем описать проблему и предложить интеграцию с SecretSpec на TypeScript, но изменить хранение OAuth-токенов MCP в Claude Code сегодня может только Anthropic», - пишет автор.
Дальше
Claude Cowork управляет компьютером в фоне
Пока вы заняты другой задачей, Claude в фоне кликает, печатает и открывает приложения прямо на рабочем столе macOS. Бета включается на планах Pro и Max в десктопном приложении, в Claude Cowork и Claude Code.
Читайте также
- Пользователь: Claude Code отправлял его email наружу
- Anthropic открыла песочницу Claude Code под Apache-2.0
- Уязвимости в маркетплейсе плагинов Claude Code
- Уязвимость Agentjacking позволяет взломать Claude Code и Cursor через фальшивые отчеты об ошибках
- Атака Miasma через конфигурации ИИ-ассистентов
- Команда Claude Code определила цикл через условие остановки
Комментарии
Пока никто не написал. Будьте первым.
Присоединяйтесь к разговору
Войдите, чтобы оставить комментарий. Он появится после модерации.

