Você confiou no workspace, não nos servidores
Em 26 de junho de 2026, a Wiz divulgou a CVE-2026-12957: o `.amazonq/mcp.json` de um repositório clonado fazia o Amazon Q iniciar automaticamente servidores MCP que herdavam todo o ambiente do desenvolvedor — chaves AWS, tokens de CLI de nuvem, segredos de API e sockets do agente SSH —, sem nenhuma etapa de consentimento separada para os próprios servidores. Um único clique em 'confiar neste workspace' substituía a criação de processos em segundo plano que carregavam sua sessão de nuvem ativa. A Amazon corrigiu isso no Language Servers 1.69.0. Eis por que a correção fecha um produto, mas não a classe, e o que muda quando o agente que abre o repositório vive em uma VM Bromure por perfil, atrás de um broker de credenciais, de uma proteção de leitura/escrita e de um rastreamento em nível de hipervisor.
Ontem a Wiz divulgou a CVE-2026-12957. Um repositório que você clona pode
trazer um arquivo chamado .amazonq/mcp.json, e no momento em que você abre a
pasta no Amazon Q e clica em Confiar neste workspace, esse arquivo
inicia servidores em segundo plano sem um segundo aviso. Eles sobem
herdando suas chaves AWS, seus tokens de CLI de nuvem, seus segredos de API
e o socket do seu agente SSH. Um clique de confiança alcançou tudo o que seu
shell consegue alcançar e entregou isso a um código que o repositório escolheu.
Um desenvolvedor que clona um repositório para experimentar um módulo de
infraestrutura não pensa nisso como conceder acesso a coisa alguma. Clonar é inerte:
escreve arquivos no disco e nada é executado. A decisão de julgamento vem um
passo depois, quando você abre a pasta no seu editor e o assistente
pergunta se deve confiar nela. Esse aviso se parece com aquele familiar “você
confia nos autores dos arquivos desta pasta” que toda IDE exibe,
e você clica em sim do mesmo jeito que já fez mil vezes, porque a
alternativa é um assistente que não consegue ler seu código. Esse sim em particular
fez mais do que deixar o assistente ler. No Amazon Q, antes da correção,
ele também iniciava quaisquer servidores que o repositório tivesse escrito em
.amazonq/mcp.json, e esses servidores subiam dentro do seu shell com
sua sessão de nuvem ativa já em seu ambiente.
Escrevemos sobre o mesmo formato no início deste mês, quando o worm Miasma plantou configuração de projeto em 73 dos próprios repositórios da Microsoft e a carga disparou ao abrir a pasta. Aquela história era sobre uma fonte confiável sendo a superfície de ataque. Esta é mais restrita e mais desconfortável: nenhum worm, nenhum mantenedor comprometido, nada para apontar o dedo a não ser o assistente. O bug estava em como o Amazon Q lia um arquivo comum de configuração de projeto e decidia, no seu único clique de confiança, criar processos de longa duração que carregavam a coisa mais sensível no seu laptop.
O que a CVE-2026-12957 de fato fez.
Em 26 de junho de 2026, a Wiz Research divulgou a CVE-2026-12957, uma falha de alta gravidade (CVSS 8.5) nos Language Servers for AWS, o motor que alimenta o Amazon Q Developer no VS Code, JetBrains, Eclipse e Visual Studio. A Wiz reportou à Amazon em 20 de abril, a Amazon lançou uma correção em 12 de maio, e os detalhes vieram a público em 26 de junho. Não há sinal de que tenha sido explorada em campo. A mecânica, reduzida ao essencial:
- O Amazon Q lê
.amazonq/mcp.jsonde um workspace que você abre: um arquivo com escopo de projeto que declara servidores Model Context Protocol para o assistente usar. - Ao abrir a pasta, o Q iniciava os servidores MCP que o arquivo declarava sem uma etapa de consentimento separada para os próprios servidores. Um repositório que você clonou podia, portanto, colocar uma definição de servidor na frente do assistente e fazê-la executar.
- Os processos criados herdavam todo o ambiente do desenvolvedor, nas palavras da Wiz, “chaves AWS, tokens de CLI de nuvem, segredos de API e sockets do agente SSH”. Um servidor MCP é apenas um comando que o Q inicia, e esse comando subia com tudo o que o seu próprio shell teria.
- Uma definição de servidor pode apontar para qualquer comando, então o arquivo equivale a execução de código arbitrário ao abrir a pasta: ele roda como você, com suas credenciais de nuvem já carregadas, no momento em que você confia no workspace.
A divulgação carrega uma divergência real sobre consentimento, e é o ponto central deste post. A posição da Amazon: “o usuário precisa confiar no workspace quando solicitado.” Há uma barreira, e você clica para atravessá-la. A constatação da Wiz: antes da correção não havia etapa de consentimento separada para os próprios servidores MCP. Ambas se sustentam, e a falha vive na lacuna entre elas. Uma decisão de confiança grosseira e familiar, o mesmo sim/não que você dá a uma pasta para que o editor possa indexá-la, autorizava uma concessão muito maior: criar servidores em segundo plano que carregavam sua sessão ativa. Você respondeu a uma pergunta sobre ler arquivos. O Amazon Q gastou o clique em rodar servidores como você.
A Amazon corrigiu isso no Language Servers 1.69.0 (clientes: VS Code 2.20+, JetBrains 4.3+, Eclipse 2.7.4+, Visual Studio 1.94.0.0+), adicionando o consentimento por servidor que faltava, e corrigiu um desvio de verificação de symlink irmão, CVE-2026-12958. Atualize o Amazon Q. Depois olhe além do patch para a parte que ele deixa de pé: abrir um repositório podia colocar sua sessão de nuvem ativa dentro de um processo que o repositório escolheu.
O mesmo repositório, aberto dentro do Bromure Agentic Coding.
O Bromure Agentic Coding roda seu agente de codificação,
Amazon Q incluído, dentro de uma VM Linux por perfil: seu próprio kernel,
seu próprio sistema de arquivos, sua própria pilha de rede, no framework de
Virtualização da Apple. Um perfil é um escopo coerente de trabalho: este cliente, este
serviço, este módulo open-source que você clonou para avaliar. Você clona
o repositório dentro desse perfil e o abre ali. O comportamento vulnerável
se reproduz exatamente como a Wiz descreveu: você clica em Confiar neste
workspace, o Q lê .amazonq/mcp.json, e inicia os servidores que o
arquivo declara. A criação dispara, e o código escolhido pelo repositório
roda.
Ele roda no convidado. O servidor MCP sobe dentro da VM e
herda o ambiente da VM, e o ambiente da VM não contém
sua sessão de nuvem. O Bromure entrega o convidado com stubs: valores
falsos que parecem reais para aws, gcloud, az, kubectl, git e
qualquer outra coisa que leia um cabeçalho Authorization ou um
AWS_ACCESS_KEY_ID. Um proxy no seu Mac fica na frente de cada
conexão que sai do sandbox, reconhece o stub e o troca pelo
segredo real no fio à medida que a requisição sai;
o sandbox que segurou a
chave percorre o mecanismo.
A chave AWS real, o token de CLI de nuvem real, o segredo de API real nunca
tocam um arquivo, uma variável de ambiente ou uma página de memória que a VM consiga
ler.
Então percorra a herança da CVE através desse limite. O servidor
criado lê $AWS_ACCESS_KEY_ID e encontra um stub. Ele lê ~/.aws
e encontra um perfil stub. Ele lê o ambiente em busca dos tokens de nuvem
e dos segredos de API e encontra placeholders. O servidor roda até o
fim como foi escrito, herdando uma caixa que nunca esteve segurando suas
chaves. O que fez da CVE-2026-12957 um bug de roubo de credenciais é a herança
de ambiente na criação, e o Bromure não a quebra. Ele
deixa o ambiente herdado sem valor.
“Confiar neste workspace” era a pergunta errada.
Esta CVE vale mais do que uma nota de patch por causa da lacuna de consentimento, e a lacuna é um problema de granularidade. O aviso de confiança fazia uma pergunta ampla, você confia nesta pasta, e um único sim tinha de cobrir tanto a coisa inofensiva que você quis dizer (deixar o assistente ler meu código) quanto a coisa perigosa que você não sabia estar anexada (iniciar servidores em segundo plano com minha sessão de nuvem). Você não consegue responder bem a isso. Ninguém consegue, porque a pergunta funde duas concessões que nada têm a ver uma com a outra e mostra a você apenas a inocente.
O Bromure não pede que você seja melhor nesse julgamento. Ele tira o julgamento do caminho. O clique de confiança dentro de um perfil ainda deixa o assistente fazer seu trabalho, e ainda assim ele não consegue iniciar um processo segurando sua sessão de nuvem real, porque essa sessão não está na VM para herdar. Ela vive no host, atrás do broker, alcançável apenas como uma requisição com stub que o proxy preenche no fio e registra. A metade perigosa da concessão se foi. Você não a reteve; não havia nada ali para conceder, porque o limite fica abaixo do agente, onde o aviso de confiança não pode movê-lo.
A outra metade perigosa é um servidor criado que vira destrutivo
em vez de só bisbilhoteiro, e ele encontra as Proteções. O Bromure lê a
operação, não apenas a conexão: um aws s3 ls é uma leitura, um
aws s3 rm é uma escrita; um git fetch é uma leitura, um git push é uma
escrita. Configure a credencial de nuvem de um perfil para perguntar na escrita, e o
momento em que o código tenta uma chamada que altera estado, como um DELETE, um
Terminate* ou um force-push, o Bromure a interrompe no fio e
exibe um aviso no seu Mac nomeando o verbo, o alvo e o
perfil. Leituras nunca interrompem você. A mutação é o que pausa, do
mesmo jeito que “o agente apagou o banco de dados de produção” deixa de ser um
post-mortem e vira uma
caixa de diálogo que você recusa.
O que o rastreamento mostra.
Toda equipe faz a mesma pergunta na manhã seguinte a algo como isso acontecer: eu abri aquele repositório, e o que ele rodou? Em um laptop comum a resposta honesta é um dar de ombros. O servidor MCP que o Q criou era um processo filho na sua sessão, e o que quer que ele tenha lido e para onde quer que tenha ligado, fez isso como você, sem nenhum registro que o separe do seu próprio trabalho.
Dentro do Bromure o agente fica em uma VM e cada byte de saída passa pelo proxy do host, então a criação e suas chamadas permanecem visíveis mesmo quando o agente não consegue vê-las. O host registra o servidor MCP subindo, os comandos que ele rodou, as credenciais que ele pediu ao broker para preencher e cada conexão que ele tentou, no mesmo rastreamento de sessão que todo o resto que o agente fez, escrito abaixo do agente, onde o código criado não consegue alcançar para editá-lo. “O servidor deste repositório tocou minha conta” deixa de ser um palpite que você reconstrói a partir do CloudTrail semanas depois e vira uma linha que você lê: o broker entregou um stub, a requisição tinha um nome, o alvo foi registrado. Para uma empresa essa é a diferença entre corrigimos o Amazon Q e podemos mostrar o que cada repositório que nossos desenvolvedores abriram fez, e a postura de auditoria é aquela à qual nosso trabalho corporativo sempre retorna.
Onde isto não te salva.
Um socket de ssh-agent encaminhado é utilizável enquanto está encaminhado.
O Bromure mantém suas chaves privadas SSH no Keychain do macOS e nunca
as copia para a VM. Mas se um perfil tem o socket do ssh-agent
encaminhado para dentro (do jeito que o OpenSSH pretende), um servidor criado pode
pedir ao agente que assine com essas chaves enquanto o socket está ativo.
O arquivo da chave nunca sai do host; a capacidade de assinatura de fato
chega ao convidado. Encaminhe o socket apenas para perfis que precisam
dele, e dê a ele o mesmo escopo que o broker dá a uma credencial.
Uma escrita que você aprova é uma escrita que acontece.
A proteção de leitura/escrita pega a chamada destrutiva que o agente
não te contou. Ela não lê sua mente sobre intenção. Se
você está derrubando um stack de propósito e aprova o
aviso, o Bromure encaminha o Terminate. O aviso te dá uma
olhada no verbo e no alvo; você ainda tem de lê-lo.
O perfil é de longa duração, então a persistência persiste.
Um perfil Bromure não é um disco descartável. Um servidor criado que se escreve em um caminho de inicialização dentro do perfil pode acordar na próxima sessão naquele perfil. Aquilo a que ele acorda é um convidado sem chaves do host e um broker que fala apenas tokens de curta duração, avisados e com escopo: presença em uma caixa que não tem nada dentro, mas presença mesmo assim.
Corrigido não é o mesmo que resolvido.
A Amazon adicionou consentimento por servidor no 1.69.0, e você deve atualizar. Mas o próximo assistente que ler configuração de projeto ao abrir a pasta tomará a mesma classe de decisão, e o aviso que ele exibir vai parecer igualmente rotineiro. Isolamento é a parte que não depende de um fornecedor específico acertar uma caixa de diálogo de consentimento específica.
O próximo workspace já está clonado em algum lugar.
A lição do escopo da Red Hat foi que o publicador não é uma defesa. A lição dos repositórios da Microsoft foi que o repositório também não é, e que abrir uma pasta é o suficiente para rodar código. O Amazon Q adiciona a próxima linha: o aviso de confiança também não é uma defesa. A pergunta que ele te faz, você confia nesta pasta, não é a pergunta cuja resposta importa, que é esta pasta deveria poder criar servidores carregando minha sessão de nuvem. A segunda nunca te foi mostrada, e você não conseguiria tê-la respondido bem se tivesse sido.
Você não conserta isso lendo o aviso com mais cuidado, porque o
aviso era o aviso errado. Você conserta arranjando as coisas de modo que
“qual workspace é este” deixe de ser a pergunta da qual suas chaves de nuvem dependem;
por que um agente de codificação não é um
sandbox é a versão mais longa
desse argumento. O Bromure Agentic
Coding é a configuração em que o agente abre o
repositório dentro de uma VM por perfil, as credenciais reais ficam no host
atrás de um broker, cada escrita que o agente faz precisa passar por um aviso, e
cada servidor que ele cria é escrito em um rastreamento que ele não consegue editar. O pior
que um mcp.json envenenado pode fazer é herdar uma caixa que nunca esteve segurando
suas chaves. É gratuito, open-source e lançado hoje.