flawopen.com/Teardowns/cve-2026-87913-aws-security-agent-mcp-s3-bucket-ownership
CVE-2026-87913: Vazamento S3 no MCP da AWS
Um bucket previsível podia receber arquivos de análise privada em outra conta. Atualize para 0.2.0 e confirme o proprietário.[1], [2], [4]
Imagine um entregador que confere se existe um prédio no endereço, mas não quem é o dono. Outra pessoa pode registrar o endereço primeiro e receber o pacote. O S3 deve confirmar o proprietário esperado na verificação e no envio.[2], [1]
Conceitos Centrais e Termos
Servidor MCP- Serviço local que oferece ferramentas a um assistente de IA; elas usam as permissões do processo servidor.[3]
Bucket S3- Contêiner Amazon S3 com nome global; o nome não revela qual conta AWS é proprietária.[2], [3]
Mapeamentos de frameworks
- Referência CWE para a fraqueza descrita neste guia: CWE-283 CWE-341
- OWASP GenAI 2025 — LLM06:2025 Agência excessiva
Análise de Causa Raiz
O servidor MCP do AWS Security Agent deriva o nome do bucket de entrada da análise do ID da conta AWS do cliente e da região: security-agent-scans-<account-id>-<region>. AWS e o mantenedor dizem que a versão vulnerável verificava se o bucket existia, mas não se pertencia ao cliente. Nomes S3 são globais e IDs de conta são públicos. Um terceiro que registrasse primeiro o nome previsível poderia receber o arquivo privado enviado pelo servidor; ele pode conter código, credenciais e estado de infraestrutura. É uma falha de propriedade de recurso na nuvem e nome previsível, não prompt injection no modelo de IA. As versões afetadas são 0.1.0 a 0.1.5; a 0.2.0 acrescenta ExpectedBucketOwner às operações S3 e falha se o proprietário for outro. A atualização não libera um nome já registrado: confirme o proprietário real e não retome análises se o bucket pertencer a terceiros.
Nome do bucket não comprova sua propriedade
| Limite | Condição documentada | Ação do operador |
|---|---|---|
| Versões afetadas | awslabs.security-agent-mcp-server 0.1.0 a 0.1.5 são afetadas; a 0.2.0 adiciona a verificação de propriedade. | Atualize para 0.2.0 ou posterior e confirme a versão do pacote em execução. |
| Nome previsível do bucket | O nome do bucket de varredura deriva do ID da conta e da região; outra conta AWS pode registrá-lo. | Trate o nome correspondente como endereço, não como prova de propriedade. |
| Upload entre contas | O servidor vulnerável podia aceitar o bucket pelo nome sem verificar o proprietário e então enviar um arquivo privado da varredura. | Confirme que o bucket pertence à conta esperada antes de iniciar a varredura ou o upload. |
| Limite de propriedade corrigido | ExpectedBucketOwner faz o S3 comparar o proprietário tanto na verificação quanto no upload. | Atualize, confirme o proprietário real e interrompa as varreduras se o nome pertencer a terceiros; a atualização não transfere o bucket. |
Fluxo de Ataque Passo a Paso
Código-Fonte: Vulnerável vs. Seguro
O exemplo é esquemático, não uma cópia literal. Existência não basta: o S3 deve comparar a conta proprietária esperada tanto na verificação quanto na gravação. Obtenha essa conta da identidade AWS autenticada e interrompa a operação em caso de divergência. Após atualizar, verifique separadamente o proprietário do bucket, pois a atualização não transfere nem libera um nome já registrado. A AWS documenta ExpectedBucketOwner em HeadBucket e PutObject: uma divergência faz a requisição falhar com 403. Use isso como proteção fail-closed, mas investigue erros de acesso negado por um caminho autorizado de verificação de propriedade antes de concluir que o bucket pertence a terceiros.[2], [8], [9]
Trecho de origem: Exemplo AWS SDK derivado do aviso; não é um diff literal do código-fonte.
# Forma vulnerável simplificada: o nome é verificado, mas não o proprietário.
s3.head_bucket(Bucket=bucket_name)
s3.put_object(
Bucket=bucket_name,
Key=object_key,
Body=archive_bytes,
)
# Vincule cada operação à conta que deve ser proprietária do bucket.
expected_owner = sts.get_caller_identity()["Account"]
s3.head_bucket(
Bucket=bucket_name,
ExpectedBucketOwner=expected_owner,
)
s3.put_object(
Bucket=bucket_name,
Key=object_key,
Body=archive_bytes,
ExpectedBucketOwner=expected_owner,
)
Lista de Verificação de Segurança para Engenharia
- ✓Atualize para 0.2.0 ou posterior e confirme a versão em execução, incluindo plugins, imagens de CI e forks.[2], [4]
- ✓Antes de analisar, confirme que o bucket derivado pertence à conta AWS esperada; encontrar o nome não prova propriedade.[1], [2]
- ✓Passe o ID esperado em
ExpectedBucketOwnerem toda operação S3 com o bucket, inclusive no upload.[8], [9] - ✓Falhe de forma segura diante de divergência. Se o nome pertencer a terceiros, pare as análises e contate a AWS.[1]
- ✓Quando aplicável, crie o bucket na conta do cliente antes do primeiro uso; aplique privilégio mínimo e criptografia.[3], [1]
- ✓Revise análises feitas nas versões afetadas e troque credenciais se arquivos expostos puderem conter segredos.[2], [1]
Fontes
- AWS Security Bulletin 2026-105-AWS — CVE-2026-87913
- Maintainer GHSA-3jxw-vj8m-8x77
- AWS Security Agent IDE integration and scan bucket workflow
- awslabs.security-agent-mcp-server 0.2.0 release
- NVD — CVE-2026-87913
- MITRE CWE-283 — Unverified Ownership
- MITRE CWE-341 — Predictable from Observable State
- Boto3 HeadBucket — ExpectedBucketOwner
- Boto3 PutObject — ExpectedBucketOwner
- Falha relacionada no mesmo pacote (CVE separado): injeção de argumentos Git no AWS MCP, CVE-2026-97662