openclaw - ✅(Solved) Fix [Bug]: Provider-supplied OAuth URLs inject Windows cmd.exe via openUrl [1 pull requests, 1 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
openclaw/openclaw#64159Fetched 2026-04-11 06:16:11
View on GitHub
Comments
0
Participants
1
Timeline
1
Reactions
0
Author
Participants
Timeline (top)
cross-referenced ×1

Fix Action

Fixed

PR fix notes

PR #64161: fix: Provider-supplied OAuth URLs inject Windows cmd.exe via openUrl

Description (problem / solution / changelog)

Fix Summary

On Windows, a malicious or compromised provider response can turn an OAuth or sign-in URL into arbitrary command execution on the gateway host. openUrl() wraps the raw URL in quotes for cmd /c start but does not escape embedded double quotes, so a provider-supplied payload like https://example.invalid/" & calc & rem " breaks out of the quoted URL and runs attacker-controlled commands as the local OpenClaw user.

Issue Linkage

Fixes #64159

Security Snapshot

  • CVSS v3.1: 8.3 (High)
  • CVSS v4.0: 9.0 (Critical)

Implementation Details

Files Changed

  • src/commands/onboard-helpers.test.ts (+7/-10)
  • src/infra/browser-open.ts (+4/-17)

Technical Analysis

  1. Use a Windows OpenClaw host on release v2026.4.9 and start an interactive provider auth flow that calls openUrl(), such as MiniMax portal OAuth or Ollama Cloud sign-in.
  2. Return a crafted provider URL containing an injected closing quote and command separator, for example https://example.invalid/" & calc & rem ".
  3. MiniMax still reads verification_uri from the provider JSON response and calls await params.openUrl(verificationUrl) at extensions/minimax/oauth.ts:193-205; Ollama still reads signin_url from /api/me and calls await params.openUrl(authResult.signinUrl) at extensions/ollama/src/setup.ts:84-86,366-370.
  4. On Windows, openUrl() still constructs cmd /c start "" "https://example.invalid/" & calc & rem "" and launches it with windowsVerbatimArguments: true, so cmd.exe executes the injected command on the host.

Validation Evidence

  • Command: pnpm test src/commands/onboard-helpers.test.ts
  • Status: passed (with pre-existing baseline failures)

Risk and Compatibility

non-breaking; no known regression impact

AI-Assisted Disclosure

  • AI-assisted: yes
  • Model: opencode/claude-sonnet-4.6

Changed files

  • src/commands/onboard-helpers.test.ts (modified, +7/-10)
  • src/infra/browser-open.ts (modified, +4/-17)

Code Example

if (platform === "win32") {
  return {
    argv: ["cmd", "/c", "start", ""],
    command: "cmd",
    quoteUrl: true,
  };
}

const quoteUrl = resolved.quoteUrl === true;
const command = [...resolved.argv];
if (quoteUrl) {
  if (command.at(-1) === "") {
    command[command.length - 1] = '""';
  }
  command.push(`"${url}"`);
}
await runCommandWithTimeout(command, {
  timeoutMs: 5_000,
  windowsVerbatimArguments: quoteUrl,
});
RAW_BUFFERClick to expand / collapse

Severity Assessment

CVSS Assessment

Metricv3.1v4.0
Score8.3 / 10.09.0 / 10.0
SeverityHighCritical
VectorCVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:C/C:H/I:H/A:HCVSS:4.0/AV:N/AC:H/AT:N/PR:N/UI:P/VC:H/VI:H/VA:H/SC:H/SI:H/SA:H
CalculatorCVSS v3.1 CalculatorCVSS v4.0 Calculator

Threat Model Alignment

Classification: security-specific

This finding crosses the trusted host/config boundary described in openclaw/SECURITY.md and openclaw/docs/gateway/security/index.md: remote provider responses are untrusted external input and should not become host execution on the gateway. In v2026.4.9, MiniMax verification_uri and Ollama signin_url values still flow into the Windows cmd /c start browser launcher without inner-quote escaping. The Out of Scope list excludes prompt-injection-only chains, trusted-operator local features, and hostile multi-tenant assumptions, but none of those exceptions cover a provider-controlled string reaching host command execution.

Impact

On Windows, a malicious or compromised provider response can turn an OAuth or sign-in URL into arbitrary command execution on the gateway host. openUrl() wraps the raw URL in quotes for cmd /c start but does not escape embedded double quotes, so a provider-supplied payload like https://example.invalid/" & calc & rem " breaks out of the quoted URL and runs attacker-controlled commands as the local OpenClaw user.

Affected Component

File: src/infra/browser-open.ts:37-42,89-103

if (platform === "win32") {
  return {
    argv: ["cmd", "/c", "start", ""],
    command: "cmd",
    quoteUrl: true,
  };
}

const quoteUrl = resolved.quoteUrl === true;
const command = [...resolved.argv];
if (quoteUrl) {
  if (command.at(-1) === "") {
    command[command.length - 1] = '""';
  }
  command.push(`"${url}"`);
}
await runCommandWithTimeout(command, {
  timeoutMs: 5_000,
  windowsVerbatimArguments: quoteUrl,
});

Technical Reproduction

  1. Use a Windows OpenClaw host on release v2026.4.9 and start an interactive provider auth flow that calls openUrl(), such as MiniMax portal OAuth or Ollama Cloud sign-in.
  2. Return a crafted provider URL containing an injected closing quote and command separator, for example https://example.invalid/" & calc & rem ".
  3. MiniMax still reads verification_uri from the provider JSON response and calls await params.openUrl(verificationUrl) at extensions/minimax/oauth.ts:193-205; Ollama still reads signin_url from /api/me and calls await params.openUrl(authResult.signinUrl) at extensions/ollama/src/setup.ts:84-86,366-370.
  4. On Windows, openUrl() still constructs cmd /c start "" "https://example.invalid/" & calc & rem "" and launches it with windowsVerbatimArguments: true, so cmd.exe executes the injected command on the host.

Demonstrated Impact

  • src/plugins/provider-auth-choice.ts:111-124 and src/commands/models/auth.ts:293-304 still hand provider auth methods a host-local openUrl(url) callback, so interactive provider auth reaches the platform browser opener.
  • extensions/minimax/oauth.ts:88-98,193-205 still accepts verification_uri from the provider response, checks only presence plus PKCE state, and then forwards the raw string to params.openUrl(verificationUrl).
  • extensions/ollama/src/setup.ts:84-86,366-370 still reads signin_url from /api/me and, in non-remote interactive mode, forwards that raw response field to params.openUrl(authResult.signinUrl).
  • src/process/exec.ts:15-42,103-114 still contains escapeForCmdExe() and the metacharacter rejection regex, but that protection is only applied when OpenClaw decides it is launching a .cmd or .bat target. openUrl() launches cmd directly, so the URL bypasses that escaping path entirely.
  • Prevalence checks show the issue is specific rather than universal: extensions/google/oauth.ts:35-58 opens a locally generated auth URL, and extensions/github-copilot/login.ts:146-149 displays verification_uri to the user instead of passing it into openUrl().
  • Release verification against v2026.4.9 (60db001e96ff96fe8796b3a9ff1b93125cceaa2e) confirms the vulnerable sink and both provider call paths are still present in the shipped tag.

Environment

  • Verified release: v2026.4.9 (60db001e96ff96fe8796b3a9ff1b93125cceaa2e), published 2026-04-09T02:25:28Z.
  • Platform: Windows only (process.platform === "win32"). macOS uses open, and Linux or WSL use xdg-open or wslview instead of cmd.exe.
  • Trigger path: Interactive provider auth flows that open a browser locally.
  • Prerequisites: The operator starts the auth flow, and the provider response can supply a crafted URL string, for example through a hostile or compromised auth endpoint or an attacker-controlled remote Ollama service.

Remediation Advice

Treat provider-returned browser URLs as untrusted input before any Windows launch step. Parse and scheme-validate the URL, reject embedded quotes and cmd.exe metacharacters, and replace the current cmd /c start path with a Windows opener that does not depend on manual shell quoting.

<!-- submission-marker:IN-rvu-windows-oauth-browser-command-injection-2 -->

extent analysis

TL;DR

The most likely fix is to properly escape and validate provider-returned browser URLs before launching them on Windows to prevent command injection.

Guidance

  1. Parse and validate URLs: Before launching a URL on Windows, parse it to ensure it conforms to expected schemes and reject any URLs with embedded quotes or cmd.exe metacharacters.
  2. Replace cmd /c start: Use a Windows opener that does not rely on manual shell quoting, such as using the start command with proper quoting or an alternative method that safely handles URLs without exposing them to shell interpretation.
  3. Apply input sanitization: Ensure that any input from providers (e.g., verification_uri, signin_url) is sanitized and does not contain characters that could be used for command injection.
  4. Test with crafted URLs: Verify the fix by testing with crafted URLs that previously led to command injection, ensuring they are now properly handled and do not execute arbitrary commands.

Example

// Simplified example of sanitizing a URL before launching
function sanitizeUrl(url: string): string {
  // Basic example, actual implementation should be more robust
  return url.replace(/"/g, '').replace(/&/g, '');
}

// Launching the sanitized URL
const sanitizedUrl = sanitizeUrl(url);
// Use a safe method to launch the URL, avoiding cmd.exe injection

Notes

  • The provided example is a simplified illustration and may not cover all edge cases. A more comprehensive solution should include thorough URL parsing and validation.
  • This fix focuses on the Windows platform, as the issue is specific to how cmd /c start handles URLs on this platform.

Recommendation

Apply a workaround by implementing proper URL sanitization and validation before launching URLs on Windows, replacing the vulnerable cmd /c start method with a safer alternative.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING