FlawOpen

flawopen.com/Teardowns/cve-2026-14540-google-mcp-toolbox-ssrf

● CVE-2026-14540 · CVSS 8.0 · Haute
Recherche · FlawOpen

CVE-2026-14540 : SSRF dans Google MCP Toolbox

CVE-2026-14540 permettait aux requêtes HTTP de MCP Toolbox de suivre des redirections sans vérifier la destination réseau finale. Passez à la version 1.5.0 ou ultérieure.[1], [3]

💡 Explication en Langage Simple (ELI5)

Un service de courrier vérifie la première adresse d’un colis, puis suit toute étiquette de réexpédition sans contrôler la nouvelle destination. Une redirection HTTP joue ce rôle : sans vérifier l’adresse IP finale, une requête destinée à un site ordinaire peut aboutir sur un réseau privé. Le correctif contrôle la destination réelle lors de la connexion et vérifie aussi les destinations de redirection.[2], [4], [7]

Concepts Clés et Termes

Server-side request forgery (SSRF)
Un service est amené à envoyer une requête HTTP vers une destination influencée par l’attaquant. La requête part du serveur et peut donc atteindre des réseaux inaccessibles à son initiateur.[6]
Redirection HTTP
Une réponse peut demander au client HTTP d’envoyer une nouvelle requête vers une autre URL. Vérifier uniquement l’URL initiale ne limite pas la destination de cette requête suivante.[4], [7]
DNS rebinding et TOCTOU
Un nom d’hôte peut être résolu vers une adresse pendant la validation puis vers une autre à l’ouverture du socket. Vérifier l’IP résolue au moment de la connexion ferme cet écart entre contrôle et utilisation.[2], [7]
Generic HTTP source et tool
Composants de MCP Toolbox qui construisent des requêtes HTTP à partir d’endpoints configurés et de paramètres d’outils. L’avis désigne ce chemin comme affecté.[1], [2], [4]
CWE-918
Server-Side Request Forgery (SSRF) : l’application récupère une URL ou destination sans contrôler suffisamment où la requête peut aller.[6]

Correspondances de référentiels

  • Référence CWE pour la faiblesse décrite dans ce guide : CWE-918
  • D3-OTF Filtrage du trafic sortant — La restriction du trafic sortant décrite dans ce guide limite les destinations accessibles au service ou à l’hôte.

Analyse de Cause Racine

Dans les versions affectées, la generic HTTP source créait un Go http.Client avec timeout et transport, sans politique de redirection vérifiant la destination ni restriction d’IP au niveau du socket. Go suivait les redirections par défaut. Comme les outils HTTP configurés peuvent intégrer des paramètres aux requêtes, une valeur manipulée ou une redirection pouvait détourner l’appel de sa destination prévue. Vérifier uniquement l’URL d’origine ne suffit pas : une redirection change la destination et le DNS peut renvoyer une autre IP entre la validation et la connexion. Le correctif upstream ajoute SSRFGuard, refuse les destinations bloquées dans CheckRedirect et vérifie de nouveau l’IP résolue à la couche de connexion. Les adresses privées, loopback, link-local et autres adresses non globales sont bloquées par défaut ; l’autorisation de plages ou de réseaux privés constitue une exception à limiter strictement.[1], [2], [4]

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

Étape 1

Appliquer le test d’accessibilité en trois conditions

Cette chaîne nécessite les trois conditions suivantes : (1) un déploiement concerné, de la version 0.3.0 à 1.4.0, utilise generic HTTP source/tool ; (2) un appelant peut invoquer ce chemin et contrôler l’URL/le chemin ou déclencher une redirection ; et (3) l’hôte Toolbox peut router vers la destination. Si une condition manque, cette chaîne ne peut pas atteindre cette destination par ce chemin. L’authentification et les contrôles d’accès propres à la destination restent applicables.[1]

Étape 2

Un argument d’outil influence une requête sortante

Un outil HTTP configuré combine son endpoint de base avec des valeurs d’entrée. La description du CVE indique que des paramètres de chemin forgés peuvent rediriger la HTTP source vers une autre destination. Un utilisateur ou agent MCP appelle l’outil ; un contenu non fiable n’influence cet appel que si le workflow environnant le permet.[1], [2]

Étape 3

L’URL d’origine ne contraint pas les redirections

Le client affecté n’avait ni hook restrictif CheckRedirect ni validation de l’IP de destination. Une réponse peut indiquer une autre URL ; contrôler uniquement la base ou la première requête ne limite donc pas la suivante.[1], [2]

Étape 4

Le Toolbox effectue la requête depuis son propre réseau

La requête suivante part de l’hôte Toolbox et peut atteindre les destinations autorisées par son réseau. Des services internes ou d’autres endpoints accessibles peuvent alors recevoir des requêtes que l’appelant MCP ne pourrait pas envoyer directement. Le CVE ne prouve pas que chaque déploiement expose des identifiants cloud ou que toute redirection aboutit.[1]

Étape 5

Mettre à niveau et vérifier les limites de sortie

Passez à MCP Toolbox 1.5.0 ou ultérieur. Le correctif valide les IP littérales configurées, contrôle les destinations de redirection et bloque les IP résolues non autorisées à la connexion, y compris contre le DNS rebinding. Gardez allowPrivateNetworks désactivé sauf nécessité ; limitez étroitement les plages autorisées et appliquez une politique de sortie distincte.[2], [3], [4]

Code Source : Vulnérable vs Sécurisé

Cette comparaison ciblée porte sur le chemin upstream du client HTTP, pas sur le remplacement complet du fichier. Le correctif fusionné ajoute SSRFGuard : il vérifie les destinations de redirection et refuse aussi les IP résolues bloquées au moment de la connexion, fermant ainsi la faille DNS rebinding qu’une simple vérification lors de la redirection laisserait ouverte. Le guard bloque par défaut les adresses privées et non globales. allowPrivateNetworks, allowedIpRanges et customBlockedIpRanges sont des contrôles puissants ; une exception d’allowlist doit se limiter à la plage nécessaire. Fichier source : internal/sources/http/http.go.[2]

Extrait source: Extrait du client HTTP et de la politique de redirection

IMPLÉMENTATION VULNÉRABLE
client := http.Client{
	Timeout: duration,
	Transport: tr,
}

// Sans politique CheckRedirect, le client suit les redirections HTTP selon
// la politique par défaut. Le transport ne filtre pas non plus les destinations SSRF.
PATCH SÉCURISÉ ET ROBUSTE
client := &http.Client{
	Timeout: duration,
	Transport: tr,
	CheckRedirect: func(req *http.Request, via []*http.Request) error {
		if len(via) >= 10 {
			return fmt.Errorf("stopped after 10 redirects")
		}
		hostname := req.URL.Hostname()
		if ip := net.ParseIP(hostname); ip != nil {
			if guard.IsIPBlocked(ip) {
				return fmt.Errorf("redirect to blocked IP %s denied", ip)
			}
			return nil
		}
		addrs, err := resolver.LookupHost(req.Context(), hostname)
		if err != nil {
			return fmt.Errorf("failed to resolve redirect host %s: %w", hostname, err)
		}
		for _, addr := range addrs {
			if ip := net.ParseIP(addr); ip != nil && guard.IsIPBlocked(ip) {
				return fmt.Errorf("redirect host %s resolves to blocked IP %s", hostname, addr)
			}
		}
		return nil
	},
}
// Le même SSRFGuard s’applique aussi à l’ouverture du socket,
// afin qu’une réponse DNS ne puisse pas remplacer une adresse autorisée par une adresse bloquée.

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

Sources