Voltar para todas as publicações
Publicado em · por Renaud Deraison

A chave nunca expirou

A Truffle Security passou quatro anos a extrair chaves AWS do histórico do git, de datasets do Hugging Face, de imagens Docker e de logs de CI. Das que conseguiu reverificar, 88% continuam a autenticar. A chave ativa mediana tem cinco anos, 2.505 utilizadores nunca rodaram a sua, e 929 deles ostentam a política de quarentena que a AWS aplica quando deteta uma chave em público. Ninguém deixou de detetar nada. O Bromure Agentic Coding mantém fora da VM a metade da chave que assina, por isso o que um agente deixa vazar já está morto no dia em que sai.

Encontrar credenciais vazadas é um problema resolvido. A Truffle Security anda nisso há quatro anos e tem 431.875 deteções AWS para mostrar. A metade por resolver é o passo seguinte, aquele em que alguém tem de entrar na consola e apagar a chave. Isso acontece uma vez em cada sete.

A Truffle Security publicou um censo esta semana, e o BleepingComputer pegou nele na quinta-feira. Desde agosto de 2022 a empresa recolhe chaves de acesso AWS nos sítios onde elas aparecem em público: histórico do git, datasets do Hugging Face, imagens Docker, registos de pacotes, logs de CI. Depois verifica se ainda funcionam.

O relatório conta 431.875 deteções AWS verificadas, deduplicadas para 64.024 chaves de acesso únicas distribuídas por 50.654 contas distintas. Dessas, 10.616 pares traziam material suficiente para serem retestados. Oitenta e oito por cento continuam a autenticar. São 9.308 chaves, ativas hoje, que qualquer pessoa poderia ter apanhado numa superfície pública em algum momento dos últimos quatro anos.

A verificação manteve-se estreita, com chamadas de metadados só de leitura: sts:GetCallerIdentity, iam:ListAccessKeys, enumeração de nomes de políticas, uma leitura de orçamento, uma chamada ao Cost Explorer por conta. Não leram dados nenhuns e não alteraram nada, e avisaram 10.260 dos 10.616 proprietários antes de publicar.

Repare agora na idade das chaves.

Cinco anos, e a contar

A chave mediana que ainda funciona tem 1.831 dias. A mais antiga tem 17,4 anos. Apenas 25 chaves do conjunto, nove décimos de um por cento, datam dos últimos trinta dias.

Essa distribuição descreve sedimento, e não um fluxo de acidentes recentes a serem apanhados e limpos. Uma chave vaza e continua vazada, porque uma chave de acesso estática da AWS não tem expiração: não há relógio, não há renovação, não há certificado a caducar ao fim de dezoito meses. Funciona até alguém abrir a consola e apagá-la. A Truffle mediu com que frequência esse alguém aparece. Entre os utilizadores cujas chaves os investigadores conseguiram enumerar, 398 em 2.903 têm uma chave mais recente ao lado da chave vazada, o que dá 13,7%. Os restantes 2.505 nunca a rodaram.

Também não se pode culpar o passo da deteção, porque a Amazon já tinha feito a descoberta. Quando a AWS deteta uma das suas próprias chaves em público, aplica ao utilizador uma política chamada AWSCompromisedKeyQuarantine, restringe o que a chave pode fazer, e envia um e-mail à conta. Ninguém tem de lho pedir. A Truffle encontrou 929 utilizadores IAM, 12% dos 7.590 ativos, a usar essa política neste momento. Cento e doze deles usam a versão original, ou seja, a AWS assinalou-os há pelo menos três anos e eles continuam a responder.

A deteção funcionou, o e-mail saiu, e três anos depois a chave continua boa.

A vida de uma chave AWS vazadaDIA 0a chave chega a umasuperfície pública: commit,camada, log de CI, datasetDETETADAa AWS aplicaAWSCompromisedKeyQuarantinee avisa o dono da contanada a faz expirarsem TTL, sem renovaçãoa não ser que alguém a apagueDIA 1.831idade mediana de uma chaveque ainda autentica hoje17,4 ANOSchave ativa maisantiga do conjuntoAlguém alguma vez emitiu uma chave de substituição?13,7% · 398 contas86,3% · 2.505 contas nunca rodaram, substituíram nem limparam a chave vazada
Uma chave de acesso estática da AWS não tem expiração, por isso um vazamento não tem data de fim. A única coisa que o encerra é uma pessoa apagar a chave, e ao longo de 2.903 utilizadores enumeráveis isso aconteceu 13,7% das vezes, incluindo para os 929 utilizadores que a própria AWS tinha assinalado e posto em quarentena.

A superfície de vazamento mudou-se para onde não há botão de apagar

A maior fonte isolada de todo o censo é o Hugging Face: 8.482 chaves ativas únicas distribuídas por 3.394 datasets, e uma taxa de chaves root de 17,9%, bem acima do resto da população.

A Truffle já tinha medido a outra ponta desse tubo. Em junho a equipa clonou todos os datasets públicos do Hugging Face: 186,9 milhões de ficheiros únicos, 7,6 petabytes, cerca de 815.000 repositórios de datasets. Achataram Parquet, Arrow, JSONL e arquivos em texto analisável e verificaram tudo o que encontraram. O resultado foram 221.303 credenciais ativas e únicas em 6.003 datasets: 11.496 chaves de fornecedores de IA, 8.557 chaves de contas de serviço do Google Cloud em 3.811 projetos, 8.594 acessos de base de dados funcionais, 3.343 chaves AWS que passam uma verificação de identidade STS, 349 tokens de acesso pessoal do GitHub, dos quais 223 podem fazer push de código e 130 reescrever workflows de CI.

Dois dos seus exemplos mostram até onde viaja um único erro. Alguém colou a chave AWS de uma fintech brasileira num chatbot, e ela aparece agora replicada cerca de dezoito vezes em corpora diferentes. Uma chave Infura capturada da mesma maneira acabou em 1.131 datasets e 10.162 localizações de ficheiro distintas. Quarenta e quatro por cento dos segredos ativos únicos que a Truffle encontrou aparecem em mais do que um dataset.

Depois as pessoas treinam modelos com esses datasets. Os dados de treino documentados do StarCoder contêm 25.217 destas chaves; o Swallow, 22.484; o OLMo 3, 21.278. Os grandes modelos proprietários mantêm os seus corpora privados, por isso ninguém de fora sabe.

A Truffle tira a conclusão crua: a rotação continua a ser a única cura, porque ninguém pode voltar atrás e limpar dados de treino. Trate como queimada qualquer chave que alguma vez tenha chegado a um repositório público, a uma página web ou a um chatbot.

Uma credencial, e sem volta atrásuma chave ativacolada num chatbot,ou commitada, ou logadapublicada num dataset6.003 datasets do HuggingFace guardam chaves ativasreplicada44% dos segredos ativosestão em vários corporausada no treinoStarCoder 25.217 chavesSwallow 22.484 chavesOLMo 3 21.278 chavesUma chave Infura, capturada numa única conversa: 1.131 datasets, 10.162 localizações. Apagar o ficheiro original não chega a nenhuma.O único passo que encerra isto é apagar a chave no fornecedor, e esse passo acontece 13,7% das vezes.
Uma credencial que chega a um dataset público não pode ser retirada. A Truffle encontrou 44% dos segredos ativos duplicados entre corpora, uma chave Infura em 1.131 datasets, e dezenas de milhares de chaves funcionais dentro dos dados de treino documentados de modelos abertos. Apagar o ficheiro original não muda nada a jusante.

Todas as fontes dessa lista são coisas que um agente escreve

Repare outra vez onde a Truffle foi às compras: histórico do git, imagens Docker, registos de pacotes, logs de CI, uploads de datasets. Isso são saídas de build, e são os artefactos que um agente de programação produz agora sem supervisão, de madrugada, a um ritmo que equipa nenhuma conseguiria rever.

Um agente que despacha um backlog enquanto dorme escreve commits, reescreve lockfiles, constrói imagens, faz push de branches e enche logs. Cada uma dessas coisas é uma superfície de publicação, e o agente tem o seu ~/.aws/credentials ao alcance esse tempo todo, porque é assim que o SDK foi desenhado para o encontrar.

Os agentes de programação escrevem esses artefactos mais depressa do que qualquer ferramenta anterior, e os 13,7% não se mexeram.

A metade que assina fica no seu Mac

O Bromure Agentic Coding corre o agente numa VM Ubuntu descartável sobre a framework Virtualization da Apple, com um proxy do lado do anfitrião como única saída. A AWS exige um tratamento próprio neste desenho. O SigV4 nunca põe o segredo no fio, já que o SDK o consome em processo para calcular um HMAC, por isso um proxy não tem nada para trocar em trânsito. O Bromure move então a assinatura.

Dentro da VM, o ~/.aws/config indica um ajudante credential_process. Quando o SDK pede credenciais, o ajudante devolve o identificador de chave de acesso verdadeiro emparelhado com um segredo falso de quarenta caracteres, cunhado de novo em cada sessão. O identificador de chave de acesso é um identificador, não um segredo, e é a metade que diz qual o utilizador IAM que está a chamar. A chave de acesso secreta é a metade que assina, e nunca entra sequer no espaço de endereçamento da VM. O Bromure nem exporta AWS_ACCESS_KEY_ID ou AWS_SECRET_ACCESS_KEY para o ambiente do convidado, com o fundamento de que as variáveis de ambiente escapam por /proc, ps -E e histórico da shell. A VM recebe uma string de região e mais nada.

O SDK assina um pedido cuja assinatura não pode estar certa. À saída, o anfitrião retira essa assinatura e recalcula o SigV4 com o material verdadeiro. O aws, o boto3 e o terraform funcionam como sempre. Tudo o que contorne o proxy recebe um InvalidSignatureException da Amazon, que é a falha que se quer.

Agora passe um workspace Bromure pela metodologia da Truffle. A fasquia deles para contar uma chave é um sts:GetCallerIdentity assinado que volta válido. Suponha que uma dependência comprometida colhe o ficheiro de credenciais desse convidado, ou que o agente é convencido a fazer-lhe cat, ou que um build o insere num bundle público. O que sai é um identificador e quarenta caracteres que nunca foram o segredo. Falha no dia em que vaza, por isso nunca se junta à camada de sedimento e não há uma cauda de cinco anos atrás dele.

Isso também elimina o passo de rotação que fica à espera de um humano. O segredo verdadeiro vive num só lugar, no seu Mac, no painel Credenciais do perfil. Mude-o aí e a sessão seguinte pega nele. Ninguém tem de descobrir qual das noventa execuções noturnas escreveu que artefacto.

Agente no portátil~/.aws/credentialsaws_access_key_id = AKIA…aws_secret_access_key = <real>o agente lê-o, o SDK assina com ele, e todosos artefactos que escreve o podem levarum commit, uma camada, um log de CI, um datasetsts:GetCallerIdentity → válidomais cinco anos disso, em medianaAgente num workspace Bromurena VM · ajudante credential_processAccessKeyId = AKIA…SecretAccessKey = <falso, 40 car.>no Mac: o segredo real, nunca na VMo proxy retira a assinatura condenada e volta a assinaro mesmo artefacto, colhidosts:GetCallerIdentity → InvalidSignatureException
Credenciais AWS num workspace Bromure: o identificador de chave de acesso identifica quem chama e chega à VM, a chave de acesso secreta assina e não chega. O convidado assina um pedido condenado a falhar, o anfitrião volta a assiná-lo com o material verdadeiro, e o que quer que seja colhido da VM falha a mesma verificação STS que o censo usou para contar chaves ativas.

Um pedido assinado mais estreito do que a chave que o assina

O outro destaque do censo é o alcance. De 817 chaves ligadas a uma empresa, 768 davam controlo total da conta: 526 chaves root e 242 utilizadores IAM com AdministratorAccess. Cento e trinta dessas chaves root estão em contas de gestão de organização, a conta que governa todas as contas membro da organização. Entre os utilizadores que os investigadores conseguiram enumerar, 976 tinham AdministratorAccess, ou seja, 84%.

São chaves cunhadas por conveniência, há anos, para uma tarefa que precisava de três permissões.

A definição Guardrails do Bromure estreita a credencial no ponto de utilização, para que nunca tenha de se lembrar de a estreitar na origem. É um motor de políticas do lado do anfitrião, dentro do proxy. Para a AWS, lê o nome da ação no cabeçalho X-Amz-Target nos serviços com protocolo JSON, como o DynamoDB e o Lambda, ou no parâmetro Action= nos serviços com protocolo query, como o EC2, o IAM e o SQS, e recorre ao método HTTP no caso do S3. Delete*, Terminate*, Remove*, Purge* e Destroy* são classificados como destrutivos; Get*, List* e Describe* como leituras. Ponha o perfil em Só leitura e uma mutação volta como um 403 seco que o agente lê como uma falha de API vulgar. Ponha-o em Bloquear destrutivos e as criações e atualizações passam, mas as eliminações não.

Quem impõe isto é o seu Mac, não a VM, por isso um agente que foi convencido de alguma coisa não consegue argumentar até passar. A credencial com que o seu anfitrião assina acaba mais estreita do que a própria credencial, o que vale a pena numa população em que 84% dos utilizadores enumeráveis tinham direitos de administrador.

O registo aparece antes da fatura

Mais um número do relatório. Das 2.754 contas cujos orçamentos os investigadores conseguiram ler, 262 têm sequer um alerta de orçamento configurado, ou seja 9,5%, com um limite mediano de oito dólares. Esse mesmo conjunto gastou 420.631 dólares em julho, com cinquenta contas acima de 1.000 dólares e nove acima de 10.000. A maioria desses proprietários vai conhecer o seu intruso numa fatura.

O Bromure escreve o registo enquanto o trabalho decorre. Cada pedido que o anfitrião assina emite uma linha credential.aws_sign na Janela → Linha do tempo de segurança, com o serviço, o método, o host, a região e o identificador de chave de acesso mascarado, ao lado das descargas de pacotes, dos veredictos da firewall e das trocas de credenciais. O Bromure guarda esse registo no Mac, onde nada dentro da VM o pode editar. Para a versão mais severa, AWS → Exigir aprovação para usar transforma cada chamada de assinatura num pedido de consentimento com uma autorização limitada no tempo, de modo que uma tarde de trabalho a sério pergunta uma vez.

O Bromure aplica a mesma ideia um passo antes, quando levanta um perfil pela primeira vez. Passa a configuração de agente que importou por uma etapa de redação: JSON, TOML e YAML estruturados filtrados por nome de chave, correspondendo a token, secret, password, apikey, credential, authorization, private_key e access_key, e texto corrido filtrado por forma do token, correspondendo a AKIA, ASIA, sk-ant-, ghp_, glpat-, AIza e npm_. Sejam quais forem os segredos reais que estejam nos dotfiles do seu Mac, eles não sobem para a VM com o resto da configuração.

O que o censo prova

A Truffle Security conduziu bem isto: chamadas só de leitura, dados nenhuns tocados, 10.260 dos 10.616 proprietários avisados antes da publicação. A AWS sai daqui melhor do que o título sugere, já que a política de quarentena é a Amazon a encontrar as suas próprias chaves vazadas e a avisar o dono sem que ninguém lho peça. Ambas as metades do sistema de deteção fizeram o seu trabalho.

O resultado foi mesmo assim 9.308 chaves ativas com uma idade mediana de cinco anos, e uma taxa de rotação de 13,7%.

O controlo que falha pede a uma pessoa que cumpra uma tarefa chata meses ou anos depois do erro, num sistema que talvez já nem seja dela, por causa de uma chave que não dá sinal nenhum de ser um problema. Controlos com essa forma falham à escala, e já falhavam antes de haver seja o que for a escrever commits de madrugada.

Portanto, deixe de pedir à tarefa chata que carregue o peso todo. Ponha no workspace uma credencial que nunca foi a credencial, e o censo fica sem nada para contar, o corpus sem nada para replicar, e a cauda de cinco anos passa a ser de outra pessoa.


Fontes: Truffle Security, “Leaked Corporate AWS Keys Held Full Admin Rights” (19 de agosto de 2026) · Truffle Security, “Scanning 7.6 Petabytes of HuggingFace Training Data for Secrets” (1 de junho de 2026) · Truffle Security, “Introducing TruffleHog AWS Analyze” (20 de agosto de 2026) · BleepingComputer, “Hundreds of leaked AWS keys give full control over corporate accounts” (21 de agosto de 2026) · Cybernews, “Massive exposure: researchers test leaked AWS keys, 9 out of 10 still authenticate” (21 de agosto de 2026)