Skip to content

Windows restart script builds ProcessStartInfo.Arguments via string concatenation without quoting embedded double-quotes #83890

Description

@davinci282828

Severity: medium / Confidence: medium / Category: security
Triage: risk
Detected against: openclaw v2026.5.18 (latest stable at time of scan, 2026-05-18)
Tooling: clawpatch 0.3.0 + acpx/claude-sonnet-4-5 via Brad Mills protocol

Evidence

  • src/cli/update-cli/restart-helper.ts:152-175 (Join-OpenClawProcessArguments)
function Join-OpenClawProcessArguments {
  param([string[]]$Arguments)
  ($Arguments | ForEach-Object {
    if ($_ -match "\\s") {
      '"' + $_ + '"'
    } else {
      $_
    }
  }) -join " "
}
  • src/cli/update-cli/restart-helper.ts:176-195 (Invoke-OpenClawSchtasksWithTimeout)
$startInfo.Arguments = Join-OpenClawProcessArguments -Arguments $Arguments

Reasoning

ProcessStartInfo.Arguments accepts a raw Win32 command-line string. Join-OpenClawProcessArguments wraps space-containing tokens in double quotes but does not escape any embedded double-quote characters (") within those tokens. If a future caller passes an argument containing " (e.g. a path with embedded quotes) the generated command line would be malformed or injectable. Currently the task name is guarded by isWindowsTaskNameSafe (which rejects "), but the function is generic and reused for arbitrary schtasks arguments (/Run, /End, /Query), so a future argument added to those call sites could bypass the protection silently. The mitigation gap is that no existing argument source today produces ", giving medium confidence overall.

Reproduction

Pass a task name containing " directly to Invoke-OpenClawSchtasksWithTimeout (bypassing isWindowsTaskNameSafe) to observe argument injection via the raw Arguments string.

Recommendation

Replace ProcessStartInfo.Arguments (raw string) with ProcessStartInfo.ArgumentList (string collection, available since .NET 5 / PowerShell 7) which avoids the quoting problem entirely: foreach ($a in $Arguments) { $startInfo.ArgumentList.Add($a) }. Alternatively, properly escape embedded double-quotes in Join-OpenClawProcessArguments: replace " with \" inside quoted tokens.

Why existing tests miss this

No tests exist for the generated PowerShell script content.

Suggested regression test

Unit test Join-OpenClawProcessArguments with an argument containing an embedded double-quote and assert the output escapes it correctly.

Minimum fix scope

Replace ProcessStartInfo.Arguments with ProcessStartInfo.ArgumentList in Invoke-OpenClawSchtasksWithTimeout, or add double-quote escaping to Join-OpenClawProcessArguments.


Standardized clawpatch finding. Persistent in v2026.5.18 (not resolved by upgrading from v2026.5.12). Finding ID: fnd_sig-feat-cli-command-0e1f16a0ce-_5f78528d40.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Normal backlog priority with limited blast radius.clawsweeper:fix-shape-clearClawSweeper found a clear likely implementation shape for this issue.clawsweeper:needs-live-reproClawSweeper needs live local, crabbox, or manual validation to confirm this issue.clawsweeper:needs-maintainer-reviewClawSweeper marked this issue as needing maintainer review before automation.clawsweeper:needs-security-reviewClawSweeper marked this issue as needing security-sensitive review.clawsweeper:no-new-fix-prClawSweeper does not recommend queueing a new automated fix PR for this issue.impact:securitySecurity boundary, credential, authz, sandbox, or sensitive-data risk.issue-rating: 🐚 platinum hermitGood issue quality with a plausible reproduction path needing some confirmation.

    Type

    No type

    Fields

    Priority

    None yet

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions