Sumário executivo
O Silverfort Uma equipe de pesquisa descobriu que a forma como a Anthropic armazena as credenciais da CLI do Claude Code no macOS facilita que qualquer processo executado com as permissões do usuário roube as credenciais da conta Anthropic do usuário e, por extensão, as credenciais de qualquer servidor MCP conectado. Uma única leitura silenciosa retorna todo o pacote de credenciais, que um invasor pode então reproduzir a partir de outra máquina para se passar pelo usuário.
O Keychain do macOS possui um mecanismo de armazenamento seguro adequado que exige que o usuário insira novamente sua senha ou confirmação biométrica antes de liberar um segredo para um processo solicitante. O Claude Desktop utiliza esse mecanismo corretamente. Se outro processo tentar acessar a credencial armazenada, o macOS solicita que o usuário se autentique novamente. O Claude Code CLI não faz isso. Ele é implementado de forma a permitir que qualquer processo em modo de usuário obtenha a credencial sem qualquer solicitação de reautenticação, e abordaremos isso em detalhes neste blog.
Tecnicamente, isso não é uma vulnerabilidade, mas sim uma falha de projeto na implementação, uma fragilidade de segurança: credenciais que deveriam exigir reautenticação não a exigem. A exploração dessa falha não exige técnicas sofisticadas além do básico "executar código como o usuário", um obstáculo muito menor do que a escalada de privilégios. A falha de projeto afeta qualquer usuário de macOS que execute o Claude Code CLI (não usuários da versão Desktop, nem usuários da CLI do Windows/Linux, já que estes dependem de armazenamento baseado em arquivos, onde as heurísticas de antivírus/EDR existentes já deveriam detectar adulterações).
O resultado final: se um código malicioso estiver sendo executado na conta de um usuário, ele pode ler silenciosamente as credenciais do Claude, sem escalonamento de privilégios, sem solicitação de senha, sem alerta e se movimentar lateralmente, acessando os servidores MCP. No macOS, o Keychain é o melhor método em comparação com o armazenamento baseado em arquivos, mas como o Claude Code CLI ignora a etapa de reautenticação, essa vantagem desaparece, e nenhuma heurística antivírus existente monitora isso da mesma forma que as heurísticas de acesso a arquivos existem em outras plataformas. Se um endpoint for comprometido, um invasor obtém acesso à conta Anthropic do usuário e a quaisquer servidores MCP conectados, podendo influenciar tudo o que esses servidores controlam, como o código-fonte da empresa no GitHub, sua base de conhecimento na Atlassian ou outros conectores MCP sensíveis.
Silverfort A Anthropic reportou essa descoberta em 25 de junho, por meio da HackerOne, seguindo suas práticas de divulgação responsável. A Anthropic respondeu prontamente e, após discussão com sua equipe, confirmou que está monitorando o reforço do controle de acesso ao item Keychain como uma melhoria de segurança e considera essa uma "mudança de defesa em profundidade... que vale a pena implementar". A Anthropic não se opôs. Silverfort Publicar a pesquisa.
Orientações para defensores
Até que esse problema seja resolvido, as organizações que executam o Claude Code CLI no macOS devem configurar um alerta sempre que o mesmo token for usado em máquinas diferentes. Além da detecção e resposta tradicionais, as organizações devem considerar uma plataforma de Segurança de Identidade que possa controlar o uso de credenciais estáticas ou temporárias e sinalizar quando o mesmo token for usado em duas máquinas diferentes — um forte indicador de uso de credenciais roubadas. As equipes de segurança devem monitorar acessos anômalos ou inesperados ao Keychain usado pela CLI do Claude Code. Padrões de acesso incomuns a esse repositório de credenciais são um indicador significativo de possível comprometimento e devem ser tratados como um gatilho para investigação.
Contexto
Os agentes de codificação de IA agora possuem credenciais reais. Para realizar seu trabalho, eles fazem login e mantêm um token na máquina, e o CLI do Claude Code Não é exceção. Quando você executa o Claude, ele faz login com um pacote OAuth: um token de acesso de curta duração e um token de atualização de longa duração. O token de atualização é a parte que deve lhe preocupar. Ele pode ser trocado por novos tokens de acesso até que alguém o revogue, portanto, não se trata de uma sessão temporária. É um acesso permanente à conta, armazenado em um laptop.
O local onde o pacote OAuth fica armazenado depende do seu sistema operacional. Em duas das três plataformas (Linux e Windows), ele é um arquivo simples no disco. No macOS, ele fica no Keychain do sistema – uma escolha intuitiva, mas com uma ressalva: por padrão, o item é vinculado ao programa que o criou, e aqui a segurança é uma ferramenta que qualquer processo pode executar. Portanto, o bloqueio existe, mas nunca é ativado, e qualquer processo sob sua conta obtém os tokens sem que o usuário precise inserir sua senha.
Vamos acompanhar a credencial da CLI do Claude Code nas três plataformas, analisar detalhadamente a falha no macOS, abordar um truque de baixo impacto para reutilizar um pacote roubado e terminar com a pergunta que toda empresa fará: a nova versão não seria melhor? Portal de aplicativos Claude Isso torna isso irrelevante? A resposta curta é não.
Segredos em um arquivo soam pior, mas é o único que você pode assistir.
No Linux e no Windows, as credenciais são armazenadas em um arquivo JSON de texto simples, sem o uso do keystore do sistema operacional. Isso pode parecer uma abordagem geralmente mais frágil, mas um arquivo de credenciais no disco é um problema que os profissionais de segurança já sabem como lidar. É um alvo clássico, e ferramentas de endpoint como antivírus e EDR podem monitorar processos que acessam um arquivo cheio de tokens. Há um local conhecido para implementar um controle e algo concreto para gerar alertas. No macOS, essa rede de segurança desaparece, como veremos.
A documentação da CLI do Claude Code indica onde o arquivo está localizado:
No Linux, as credenciais são armazenadas em
~/.claude/.credentials.jsoncom modo de arquivo 0600.”No Windows, as credenciais são armazenadas em
%USERPROFILE%\.claude\.credentials.jsone herdarão os controles de acesso do diretório do seu perfil de usuário, que restringe o arquivo à sua conta de usuário por padrão.”
Uma ressalva: CLAUDE_CONFIG_DIR Este arquivo é movido para outro local, portanto, as regras de detecção que codificam o caminho literal não detectarão essas instalações.
Dentro desse arquivo está tudo o que vale a pena coletar: um token de acesso OAuth (sk-ant-oat…), o token de atualização de longa duração (sk-ant-ort…), um timestamp expiresAt e os escopos do token. O mesmo repositório também armazena quaisquer tokens OAuth do servidor MCP e segredos de plugins que você tenha conectado. O token de atualização é o mais importante, pois uma única leitura dele garante acesso permanente à conta. No Linux e no Windows, aqui estão algumas sugestões sobre o que observar:
- Monitoramento da integridade dos arquivos. Tratar
~/.claude/.credentials.json(EoCLAUDE_CONFIG_DIRvariante) como um objeto sensível. O alerta desejado é uma leitura ou abertura por qualquer processo que não seja o binário claude. No Linux, você pode fazer isso com um comando auditd watch (auditctl -w /home/*/.claude/.credentials.json -p rwa -k claude_creds) ou telemetria aberta eBPF. No Windows, use auditoria de acesso a objetos (ID do evento 4663) com uma SACL ou telemetria de leitura de arquivos EDR. - Desvio de permissões. O arquivo Linux deve permanecer em
0600Se o conteúdo se tornar legível para o grupo ou para todos, isso já é um sinal de alerta por si só. - Assinaturas de conteúdo. Trate os prefixos sk-ant-oat (acesso) e sk-ant-ort (atualização) como indicadores de credenciais para DLP e antivírus. Sinalize-os em arquivos fora do diretório de configuração, em arquivos compactados, na área de transferência e no tráfego de saída. Uma ocorrência do prefixo refresh-token é a mais grave.
- A questão da identidade. O melhor sinal não está no endpoint. Um token que aparece primeiro em um host e depois em outro é um indicador clássico de roubo de identidade. Fique atento à mesma sessão OAuth surgindo em um novo dispositivo, local ou IP logo após uma leitura local. Detectar esse tipo de reutilização entre hosts é a função de uma plataforma de detecção de ameaças à identidade.
Guarde o arquivo complementar, ~/.claude.json, também está no seu radar. Não é o depósito secreto, mas contém a identidade da conta (oauthAccount,userID), que é a outra metade de uma sessão de trabalho. Mais sobre isso na próxima seção.
A fechadura que não tranca: No macOS, o Acesso às Chaves é uma boa ideia, mas precisa ser implementado corretamente.
O macOS quebra esse padrão, com a CLI mantendo suas credenciais no Keychain em vez de em um arquivo. .credentials.json arquivo. A documentação é explícita:
No macOS, as credenciais são armazenadas no Keychain criptografado do macOS.
Esse é o instinto correto. Um armazenamento criptografado e protegido pelo sistema operacional é sempre melhor que um arquivo simples. Mas um item do Keychain é tão seguro quanto a lista de controle de acesso (ACL) associada a ele, e é aí que esse item em particular falha.
Claude Code CLI cria seu item Keychain executando o seguinte comando: /usr/bin/security add-generic-passworde não passa argumentos de controle de acesso: nem -T para confiar em um aplicativo específico, nem -A para permitir qualquer aplicativo. Portanto, o item herda a lista de controle de acesso (ACL) padrão do Keychain. A página de manual security(1) do macOS explica o que esse padrão faz:
Por padrão, o aplicativo que cria um item tem permissão para acessar seus dados sem aviso prévio. Você pode remover esse acesso padrão especificando explicitamente um caminho de aplicativo vazio: -T "".
Nesse caminho de código, o aplicativo que cria o item é /usr/bin/security ele mesmo. Portanto, o leitor confiável registrado no item é /usr/bin/security, sentado no apple-tool: partição que o macOS reserva para as ferramentas assinadas pela própria Apple. Esse padrão é todo o problema. /usr/bin/security é uma ferramenta de linha de comando de uso geral, assinada pela Apple, e qualquer processo em execução na sua conta pode chamá-la sem privilégios especiais. Uma ACL cujo único leitor confiável é o security A ferramenta é satisfeita por qualquer processo que execute o security ferramenta, o que significa todos os processos na máquina. A ACL (Lista de Controle de Acesso) tem como objetivo controlar qual programa pode ler o segredo. Na prática, ela não controla nada, porque qualquer programa pode lê-lo solicitando a um binário padrão que faça a leitura.
O resultado é uma leitura silenciosa de uma única linha:
security find-generic-password -s "Claude Code-credentials" -a "$USER" -w
Sem Touch ID, sem solicitação de login e senha, sem privilégios de administrador. O JSON completo das credenciais é retornado: o token de acesso, o token de atualização de longa duração e quaisquer segredos do MCP ou do plugin que compartilhem o item.

A Anthropic já faz isso corretamente com o Claude Desktop, então por que não com o Claude Code CLI?
A evidência mais clara de que se trata de uma escolha de implementação, e não de uma limitação do macOS, é que a Anthropic já faz isso corretamente no Claude Desktop. O Claude Desktop roda no mesmo sistema operacional, para o mesmo usuário, e protege o mesmo tipo de segredo. Ele faz isso com o safeStorage do Electron, e vale a pena detalhar o design, pois ele não é o mesmo da interface de linha de comando (CLI). safeStorage O Electron mantém uma chave de criptografia no Keychain e armazena os tokens reais como texto cifrado em um arquivo no disco. A documentação do Electron descreve como essa chave é protegida:
“As chaves de criptografia do seu aplicativo são armazenadas no Acesso às Chaves de uma forma que impede que outros aplicativos as carreguem sem a permissão do usuário.”
O item Keychain que contém essa chave lista apenas o aplicativo Claude assinado em sua ACL, e sua partição está vinculada à equipe de desenvolvimento da Anthropic, portanto, uma leitura de segurança de qualquer coisa Caso contrário, será solicitada a senha de login.O texto cifrado no disco é inútil sem a chave, e a chave não é revelada sem essa solicitação.

Os dois designs parecem semelhantes, mas se comportam de maneira muito diferente. A CLI armazena os tokens no Keychain com uma ACL que permite que qualquer processo os leia. O Claude Desktop armazena apenas uma chave no Keychain, vincula essa chave à sua própria assinatura e mantém os tokens criptografados em um arquivo que, por si só, é inútil. Mesmo sistema operacional, mesmo usuário, mesmo tipo de segredo: um pode ser lido silenciosamente por qualquer processo, enquanto o outro requer aprovação do usuário. A diferença reside em como o item do Keychain é criado e o que ele protege.
Causa raiz: A CLI delega a criação de itens para /usr/bin/security Em vez de usar a API nativa do Keychain Services para vincular o item à assinatura de código do próprio binário do Claude, que é o padrão já utilizado no Claude Desktop, a ferramenta de segurança não consegue vincular um item ao programa que o chamou. Somente a API nativa pode fazer isso. Em termos de vulnerabilidades, isso corresponde às vulnerabilidades CWE-732 (atribuição incorreta de permissão para um recurso crítico) e CWE-522 (credenciais insuficientemente protegidas).

Recriando a sessão sem alterar nenhum arquivo de configuração.
Ler o token é apenas metade da personificação. Para agir como a vítima, a CLI do Claude Code também precisa saber quem está logado, informação que normalmente reside no... oauthAccount bloco interno ~/.claude.jsonA jogada óbvia seria roubar esse arquivo também. Existe uma maneira mais limpa que deixa muito menos rastros, e vale a pena explicá-la, porque a explicação óbvia de por que funciona está errada.
A receita, na máquina do atacante:
1. Exporte o token de acesso roubado e execute o claude uma vez:
export ANTHROPIC_API_KEY=<access-token>
claude
2. Saia e então unset ANTHROPIC_API_KEY.
3. Coloque todo o conteúdo roubado no seu próprio chaveiro:
security add-generic-password -U -s "Claude Code-credentials" -a "$USER" -T /usr/bin/security -w 'PASTE_THE_JSON_HERE'
4.Executar claude Novamente. Agora você está logado como vítima.
Eis a parte contraintuitiva. A variável de ambiente não é o que faz o login. Uma variável roubada sk-ant-oat… O valor inserido em ANTHROPIC_API_KEY é enviado como o cabeçalho X-Api-Key, conforme a documentação de precedência de autenticação da CLI do Claude Code. Esse cabeçalho está incorreto, e o tipo de token também está incorreto, pois um token de acesso OAuth não é uma chave de API do Console. Ele não autentica chamadas de modelo.
Então, para que serve a exportação? A ordem das operações é o ponto principal. A primeira execução, com o token de acesso roubado exportado, é a etapa que grava a identidade da conta da vítima em ~/.claude.json, para que o atacante nunca precise copiar esse arquivo. Em seguida, você remove a variável e coloca o pacote completo, incluindo o token de atualização, no Keychain. A documentação descreve unset ANTHROPIC_API_KEY como forma de "recorrer à sua assinatura", e a execução final faz exatamente isso: autentica-se com o pacote Keychain como credencial de assinatura, cujo token de atualização de longa duração continua gerando novos tokens de acesso. Essa credencial é a entrada de menor precedência na lista e também a mais durável.
Por que os defensores deveriam se importar? Porque o objetivo principal desse método é minimizar o impacto. Uma única leitura silenciosa do Keychain substitui a captura de vários arquivos, e menos arquivos copiados na máquina de origem significam menos indicadores para detecção de exfil. No macOS, você nem pode esperar por um evento de arquivo, porque não há arquivo. A leitura ocorre dentro de um processo, então é o processo que você precisa monitorar.
Toda a cadeia, do início ao fim.
Junte as duas metades e o ataque é rápido. Tudo no lado da vítima funciona como um usuário comum, sem avisos ou privilégios; no lado do atacante, é apenas uma repetição.

Aqui está esse mesmo fluxo como prova de conceito, executado de ponta a ponta:
O gateway de aplicativos Claude não resolveria isso?
Resposta curta: não. Implantamos o gateway, apontamos nosso próprio código Claude para ele e executamos exatamente o mesmo roubo. E funcionou.
É importante ser preciso sobre o que é o gateway, pois seu funcionamento é mais restrito do que o nome sugere. Não se trata de uma camada de segurança que envolve sua configuração padrão do Claude. É uma ferramenta de roteamento, uma forma de direcionar o código do Claude para um endpoint de modelo específico que a organização executa ou escolhe, em um local diferente do caminho padrão da Anthropic: on-premise, Microsoft Foundry, Amazon Bedrock, Google Cloud ou um endpoint próprio da Anthropic. Os motivos que observamos foram os já conhecidos: regras de residência de dados e conformidade, um fornecedor de nuvem preferencial ou uma implantação local. Se esse não for o caso da sua organização, o gateway nunca fez parte da sua configuração e o item do Keychain é exposto exatamente como descrito no restante deste artigo.
É justo perguntar o que o gateway oferece, porque não é nada desprezível. Os desenvolvedores fazem login com o SSO corporativo, as sessões duram cerca de uma hora e a revogação passa pelo IdP, então, quando uma organização desabilita um usuário, o acesso dele ao gateway é encerrado dentro da sessão. A chave upstream, a chave da API do Claude ou a credencial na nuvem, permanece fora do laptop. É isso que o anúncio quer dizer com:
“Nenhum segredo de longa duração fica armazenado nas máquinas dos desenvolvedores.”
Vale a pena ler essa linha com atenção, pois ela se refere à chave upstream, não a roubo. O que ainda permanece no Keychain sob o gateway é uma credencial de atualização. Ela pode estar configurada para que apenas o gateway a reconheça, mas essa é a pegadinha: um invasor que a extraia e se conecte ao gateway como o usuário pode continuar criando novas sessões enquanto a conta permanecer ativa. A sessão de uma hora nunca limita o invasor. A única coisa que o impede é a organização perceber e desabilitar o usuário, e nada sobre uma leitura silenciosa do Keychain faz com que isso aconteça. "Sem segredos de longa duração" se transforma silenciosamente em acesso de longa duração para quem lê o item.
Então, configuramos um gateway, conectamos Claude a ele e repetimos o ataque da seção anterior. A leitura do Keychain não mudou. O mesmo script Python de uma linha extraiu as credenciais sem qualquer solicitação e as copiamos para uma segunda máquina.
Desta vez, nem precisamos da configuração inicial extra da seção anterior, nem de um segundo arquivo da vítima. O endereço do gateway já está dentro da credencial que roubamos. O valor armazenado no item "Claude Code-credentials Keychain" contém mais do que apenas os tokens. Ele também registra o gateway ao qual a vítima estava conectada, de modo que uma leitura silenciosa nos fornece tanto as chaves quanto o endereço do gateway que ela acessa.
Isso significa que não há nada extra para extrair do disco da vítima. Criamos a configuração na própria máquina do atacante, em:
/Library/Application Support/ClaudeCode/managed-settings.json
e aponte para o URL do gateway que acabamos de ler da credencial roubada:
{
"forceLoginMethod": "gateway",
"forceLoginGatewayUrl": "https://claude-gateway.internal.example.com"
}
Escrever esse arquivo não é um obstáculo. A própria Anthropic chama as configurações gerenciadas de "um controle do lado do cliente, não uma barreira de segurança", portanto, um invasor pode criar as suas próprias. Em seguida, carregamos a credencial roubada e iniciamos o Claude Code. Não há nenhuma etapa separada para recriar a identidade da vítima. A credencial contém o token, o token autentica o gateway e o gateway executa a sessão como a vítima, com o acesso da vítima.
O gateway apresenta um obstáculo que um atacante puramente remoto não conseguiria superar. O Claude Code não se comunica com um gateway em um endereço público.
“Em /login, o Claude Code exige que o nome do host ou o endereço IP do gateway seja resolvido apenas para endereços privados: RFC 1918, link-local, CGNAT 100.64.0.0/10, IPv6 ULA fc00::/7 ou loopback para desenvolvimento local. Para um gateway hospedado por você, qualquer endereço público será rejeitado.”
Portanto, a credencial roubada só funciona em algum lugar que consiga alcançar o gateway privado. Isso parece uma barreira intransponível até você se lembrar do modelo de ameaça. Já partimos do princípio de que o atacante está executando o programa como o usuário na máquina da vítima, que, para começar, está dentro dessa rede. Acessar um endereço privado a partir daí é a parte fácil. É uma questão de atrito, não de barreira.
Aqui está a avaliação honesta. O gateway vale a pena por outros motivos. Ele impede que a chave upstream fique armazenada no laptop e oferece à organização um mecanismo central de desativação de credenciais (kill switch) por meio do IdP, embora isso só seja útil depois que alguém perceber o roubo. O que ele não faz é corrigir a vulnerabilidade abordada neste post. A credencial ainda fica armazenada no mesmo item do Keychain, esse item continua legível por qualquer processo sem aviso prévio, e uma credencial de atualização roubada continua sendo usada contra o gateway até que a conta seja desativada.
A verificação de rede é um desvio, não uma parada. E para a grande maioria dos usuários, que nunca interagem com o gateway, nada muda aqui.
O que um defensor deve fazer imediatamente?
- macOS: até que a ACL do item esteja vinculada à assinatura Claude, seu ponto de detecção é o processo, não um arquivo. O sinal é uma chamada `/usr/bin/security find-generic-password` cuja string de serviço é `Claude Code-credentials` e que carrega `-w` para imprimir o segredo. Alerte sobre isso por meio de telemetria de execução de processo ou Endpoint Security e use a linhagem de processo para reduzir falsos positivos: leituras legítimas rastreiam até o binário Claude, então priorize essas, enquanto as suspeitas vêm de um comando de shell, um editor ou host de extensão, ou um script de instalação de dependência. Monitore também `add-generic-password` para o mesmo serviço, pois é assim que um pacote roubado é instalado em uma segunda máquina. Trate esses alertas como um controle compensatório.
- Linux e Windows: monitoramento de integridade de arquivos e DLP em .credentials.json, alertas de desvio de permissões e assinaturas de conteúdo nos prefixos sk-ant-oat e sk-ant-ort.
- Em todos os lugares: correlacione leituras do repositório de credenciais com tráfego de saída inesperado e monitore o plano de identidade em busca do mesmo token sendo reutilizado em diferentes hosts. Faça a rotação em caso de suspeita. Uma única leitura entrega um token de atualização de longa duração, portanto, um evento de leitura confiável exige um logout e um novo login, além da rotação da chave do console, e não apenas a limpeza do endpoint.
- A verdadeira solução pertence à Anthropic e apresenta baixo risco: criar o item Keychain da CLI por meio da API nativa, vinculado à assinatura de código do próprio binário do Claude. Esse é o padrão já utilizado no Claude Desktop.
A boa notícia é que a parte mais difícil já está resolvida dentro do próprio código-fonte da Anthropic. A CLI não precisa de um novo modelo de segurança. Ela precisa do que já está em execução no sistema.
Cronograma de divulgação
25 de junho, 3h46 UTC. O pesquisador submete o relatório com os passos para reprodução, o impacto e três capturas de tela.
25 de junho, 4h05 UTC. Apenas 19 minutos depois, a Anthropic encerra o tópico como Informativo, classificando-o como fora do escopo sob a categoria "Armazenamento local de credenciais, configuração e logs do Claude Code" e afirmando que os processos do mesmo usuário são totalmente confiáveis, portanto, as ACLs do Keychain por processo não adicionam nenhuma restrição significativa.
2 de julho, 11h12 UTC. O pesquisador solicita uma reavaliação humana, argumenta que o fechamento foi mapeado para a exclusão errada (trata-se de uma configuração incorreta da ACL do Keychain, não do armazenamento local, e o Desktop faz isso corretamente no mesmo sistema operacional), anexa o vídeo de prova de conceito e notifica a elaboração de um relatório defensivo com uma oferta de coordenação da divulgação.
2 de julho, 11h14 UTC. A Anthropic reconhece o pedido de reavaliação e afirma que fará uma análise interna, confirma que a discussão pública é aceitável, uma vez que o relatório está encerrado, e solicita acesso a uma versão preliminar com antecedência.
22 julho. O pesquisador compartilha a versão final do blog para revisão pré-publicação, conforme solicitado pela Anthropic, e observa que agora inclui uma análise sobre se o gateway de aplicativos Claude mitiga ou não a falha.
24 julho. A Anthropic concluiu sua revisão, não relatou problemas factuais nem correções solicitadas e aprovou a publicação do relatório. Sua classificação permanece inalterada: acrescenta que agora está monitorando o reforço do controle de acesso ao item Keychain como uma melhoria de segurança em profundidade que vale a pena implementar, embora não o considere uma vulnerabilidade em seu modelo de ameaças.

