système : OPÉRATIONNEL
← retour à tous les hacks
INFRASTRUCTURE MEDIUM NEW

Injection SQL en position d'identifiant dans le gateway MCP d'Amazon

Un avis de juillet 2026 corrige une injection SQL authentifiée dans le gateway MCP open source d'Amazon : un nom de table non filtré, en position d'identifiant, permettait de lire les clés d'API stockées des agents.

2026-07-08 // 6 min affects: mcp-gateway-registry, mcp-protocol, ai-agent-infrastructure

De quoi s’agit-il ?

Le 6 juillet 2026, Amazon a publié un avis de sécurité pour mcp-gateway-registry, un gateway et registre open source pour les serveurs Model Context Protocol (MCP). Le projet centralise la découverte, l’authentification et l’autorisation, et sert de proxy aux outils MCP pour les agents IA et les assistants de code — en pratique, un plan de contrôle placé entre les agents et les outils qu’ils appellent. L’avis décrit une injection SQL authentifiée dans le composant de gestion des politiques de rétention du service de métriques. La faille est classée CWE-89, notée CVSS 8.1 (v3.1) / 8.6 (v4.0), toutes deux ÉLEVÉES, et corrigée en version 1.0.13. Il s’agit d’une vulnérabilité divulguée et corrigée ; l’analyse ci-dessous est défensive et ne reproduit aucun exploit fonctionnel.

Comment ça marche

Le code de gestion des politiques de rétention laisse l’appelant préciser à quelle table de métriques une politique s’applique. Cette valeur table_name, fournie par l’appelant, est interpolée dans une requête SQL en position d’identifiant — là où figure un nom de table ou de colonne — sans neutralisation adéquate. Les versions affectées vont de 1.0.3 à 1.0.12.

Le point subtil, c’est pourquoi la parade habituelle ne s’applique pas. Les requêtes paramétrées — le remède standard contre l’injection SQL — ne lient les entrées non fiables qu’en position de valeur :

# Sûr : la valeur est liée, jamais interprétée comme du SQL
cursor.execute("SELECT * FROM metrics WHERE day = %s", (user_day,))

# Dangereux : un identifiant ne peut pas être lié, il est donc concaténé
cursor.execute(f"DELETE FROM {table_name} WHERE ts < now() - interval '30 days'")

La plupart des pilotes de base de données n’offrent aucun paramètre substituable pour un nom de table ou de colonne ; les développeurs recourent donc au formatage de chaîne — et la logique de rétention, qui itère naturellement sur un ensemble de noms de tables, est un endroit classique où ce motif apparaît. Comme le texte injecté est interprété comme partie intégrante de la structure de la requête, et non comme une donnée, un utilisateur distant authentifié peut sortir de l’identifiant prévu et exécuter du SQL arbitraire contre la base de métriques. Selon l’avis, cela inclut la lecture des données stockées — jusqu’au matériel de clés d’API — ainsi que la suppression ou la modification des enregistrements.

Pourquoi c’est important

Une injection SQL dans une application web classique fait fuiter des lignes. La même faille dans un gateway MCP fait fuiter le matériel qui autorise les agents à atteindre les outils en aval. C’est la même leçon que dans toute la vague de failles d’infrastructure IA de 2026, y compris l’injection pré-authentification du proxy LiteLLM : les gateways sont des surfaces de crédentiels de premier rang, car ils agrègent des secrets qui reposaient auparavant derrière des frontières distinctes.

Deux détails élèvent le risque concret. D’abord, « authentifié » est une barrière plus basse dans un écosystème d’agents que dans un contexte humain : un gateway de ce type dessert de nombreuses identités d’agents, comptes de service et jetons, dont n’importe lequel pourrait être l’appelant authentifié. Ensuite, l’injection atteint un magasin qui, selon l’avis lui-même, peut contenir du matériel de clés. Un primitive de lecture à cet endroit peut se propager aux systèmes que ces clés déverrouillent, transformant la faille d’un seul composant en une compromission de plusieurs outils.

Défenses

Le correctif de la 1.0.13 est le bon modèle, et les leçons générales valent pour tout service qui construit du SQL à partir de noms :

  • Mettre les identifiants en liste blanche. Validez table_name contre un ensemble fixe et connu de tables de métriques, et rejetez tout le reste. N’interpolez jamais une entrée d’appelant en position d’identifiant, même après échappement.
  • Ne pas croire que la liaison de paramètres couvre les identifiants. Les substituts protègent les valeurs, pas les noms de table ou de colonne. Si un nom doit être dynamique, passez par une table de correspondance, pas par un formatage de chaîne.
  • Comptes de base de données à moindre privilège. Le service de métriques devrait se connecter avec un rôle qui ne touche que les tables de métriques — pas celles qui contiennent les crédentiels ou la configuration — afin qu’une injection ne puisse pas pivoter vers les secrets.
  • Séparer les secrets de la télémétrie. Ne co-localisez pas le matériel de clés d’API avec les données de métriques, et chiffrez les secrets au repos pour qu’une lecture d’un magasin ne livre pas l’autre.
  • Restreindre et auditer les surfaces d’administration. Protégez la gestion des politiques de rétention par une autorisation forte, et journalisez son usage.
  • Mettre à jour et faire tourner les clés. Passez en 1.0.13 ou ultérieure. Toute instance ayant exécuté une version affectée et joignable par des identités authentifiées non fiables devrait voir ses clés stockées renouvelées et l’intégrité de ses données de métriques vérifiée.

Statut

ÉlémentDétailStatut
RéférenceCVE-2026-14471 (GHSA-79qc-vqfr-xx5q)Public
Versions affectées1.0.3 – 1.0.12Confirmé
Version corrigée1.0.13Disponible
Avis publié6 juil. 2026Public (AWS)
SévéritéCVSS 8.1 v3.1 / 8.6 v4.0, CWE-89ÉLEVÉE
ContournementAucun — mise à jour requise

La leçon est étroite et réutilisable : les requêtes paramétrées sont nécessaires mais pas suffisantes. Partout où une plateforme d’agents laisse un appelant nommer une table, une colonne ou un champ de tri, ce nom exige une liste blanche — car un identifiant ne peut jamais être lié en toute sécurité, seulement validé.

Sources