FlawOpen

flawopen.com/Teardowns/cve-2026-87913-aws-security-agent-mcp-s3-bucket-ownership

● CVE-2026-87913 · CVSS 5.1 · Moyenne
Recherche · FlawOpen

CVE-2026-87913 : fuite S3 du MCP AWS

Un bucket prévisible pouvait recevoir des archives privées dans un autre compte. Passez en 0.2.0 et vérifiez le propriétaire.[1], [2], [4]

💡 Explication en Langage Simple (ELI5)

Imaginez un coursier qui vérifie qu’un bâtiment existe à une adresse, mais pas qui en est propriétaire. Quelqu’un d’autre peut réserver l’adresse en premier et recevoir le colis. S3 doit confirmer le propriétaire attendu lors du contrôle et de l’envoi.[2], [1]

Concepts Clés et Termes

Serveur MCP
Service local proposant des outils à un assistant IA ; ils utilisent les droits du processus serveur.[3]
Bucket S3
Conteneur Amazon S3 à nom global ; le nom ne révèle pas le compte AWS propriétaire.[2], [3]
ExpectedBucketOwner
Paramètre S3 exigeant la confirmation de l’identifiant du compte propriétaire attendu avant l’opération.[2], [8], [9]
CWE-283 et CWE-341
Faiblesses MITRE de propriété non vérifiée et de valeurs prévisibles ; l’avis attribue les deux au défaut.[8], [9]

Correspondances de référentiels

Analyse de Cause Racine

Le serveur MCP AWS Security Agent déduit le nom du bucket d’entrée d’analyse de l’identifiant du compte AWS client et de la région : security-agent-scans-<account-id>-<region>. AWS et le mainteneur indiquent que la version vulnérable vérifiait l’existence du bucket, pas son appartenance au client. Les noms S3 sont globaux et les identifiants de compte publics. Un tiers ayant enregistré le nom prévisible en premier pouvait recevoir l’archive privée envoyée par le serveur ; elle peut contenir du code, des identifiants et l’état d’infrastructure. C’est un défaut de propriété de ressource cloud et de nom prévisible, pas une injection de prompt dans le modèle IA. Les versions 0.1.0 à 0.1.5 sont touchées ; la 0.2.0 ajoute ExpectedBucketOwner aux opérations S3 et échoue si le propriétaire diffère. La mise à niveau ne libère pas un nom déjà enregistré : vérifiez le propriétaire réel et ne relancez pas les analyses si le bucket appartient à un tiers.

Le nom du bucket ne prouve pas sa propriété

LimiteCondition documentéeAction de l’opérateur
Versions concernéesawslabs.security-agent-mcp-server 0.1.0 à 0.1.5 sont concernées ; la version 0.2.0 ajoute la vérification du propriétaire.Passez à la version 0.2.0 ou ultérieure et vérifiez la version du paquet en cours d’exécution.
Nom de bucket prévisibleLe nom du bucket d’analyse est dérivé de l’identifiant du compte et de la région ; un autre compte AWS peut le réserver.Considérez un nom correspondant comme une adresse, pas comme une preuve de propriété.
Téléversement inter-comptesLe serveur vulnérable pouvait accepter le bucket par son nom sans vérifier son propriétaire, puis y téléverser une archive d’analyse privée.Vérifiez que le bucket appartient au compte attendu avant toute analyse ou tout téléversement.
Frontière de propriété corrigéeExpectedBucketOwner demande à S3 de comparer le propriétaire lors de la vérification et du téléversement.Mettez à niveau, vérifiez le propriétaire réel et arrêtez les analyses si le nom appartient à un tiers ; la mise à niveau ne transfère pas le bucket.

Déroulement de l'Attaque Étape par Étape

Étape 1

La demande de scan reçoit le code

Un client IA demande l’analyse ; le serveur archive l’espace de travail avec son identité AWS.[3], [2]

Étape 2

La destination est prévisible

Le nom vient de l’identifiant du compte et de la région ; ces identifiants sont publics et les noms S3 globaux.[1], [2]

Étape 3

Le contrôle ne vérifie que l’existence

Le serveur acceptait un bucket par son nom sans confirmer qu’il appartenait au client.[2], [1]

Étape 4

L’archive peut atteindre un autre compte

Si un tiers avait enregistré le nom, il pouvait recevoir l’archive privée susceptible de contenir des données sensibles.[2], [1]

Code Source : Vulnérable vs Sécurisé

Le code est schématique, pas une copie littérale. L’existence ne suffit pas : S3 doit comparer le compte propriétaire attendu lors du contrôle et de l’écriture. Obtenez ce compte depuis l’identité AWS authentifiée et interrompez l’opération en cas d’écart. Après mise à niveau, vérifiez séparément le propriétaire, car elle ne transfère ni ne libère un nom déjà enregistré. AWS documente ExpectedBucketOwner pour HeadBucket et PutObject : en cas de différence, la requête échoue avec un 403. Utilisez ce contrôle en échec fermé, mais examinez les erreurs d’accès refusé par une voie autorisée de vérification de propriété avant de conclure que le bucket appartient à un tiers.[2], [8], [9]

Extrait source: Exemple AWS SDK dérivé de l’avis ; il ne s’agit pas d’un diff littéral du code source.

IMPLÉMENTATION VULNÉRABLE
# Forme vulnérable simplifiée : le nom est vérifié, mais pas son propriétaire.
s3.head_bucket(Bucket=bucket_name)
s3.put_object(
    Bucket=bucket_name,
    Key=object_key,
    Body=archive_bytes,
)
PATCH SÉCURISÉ ET ROBUSTE
# Associez chaque opération au compte censé posséder le 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,
)

Liste de Contrôle de Sécurité pour l'Ingénierie

Sources