PowerShell hashtable string value falsely parsed as blocked `init` command · Issue #834 · wonderwhy-er/DesktopCommanderMCP · GitHub
Skip to content

PowerShell hashtable string value falsely parsed as blocked init command #834

Description

@xyyxyyxx

Summary

Desktop Commander 0.2.50 rejects a PowerShell start_process request with Command not allowed (outer error code INVALID_ARGUMENT) before the command runs. The blocked token init originates from a descriptive string value inside a PowerShell hashtable, not from an executable command.

This is related to #731, but distinct from that issue's PowerShell here-string / format case and the proposed here-string fix in #792.

Environment

  • Desktop Commander v0.2.50 (remote start_process)
  • Windows / Windows PowerShell (powershell.exe)
  • Existing blockedCommands contains init; it was not modified.

Privacy-sanitized minimal reproduction

The following snippet is illustrative PowerShell input, not executed during preparation of this issue:

$metadata = [ordered]@{ Stage='preflight'; Operation='Device init then read-only health check' }; $metadata | ConvertTo-Json

With the installed v0.2.50 dist/command-manager.js extraction logic, an in-memory, parser-only reproduction returns:

extractCommands(...) -> ["=", "init", "convertto-json"]
blocked match         -> "init"

The same snippet with the literal Device preparation then read-only health check yields no init match. A genuine executable init remains detectable as init. None of these reproduced strings were executed as shell commands.

Evidence from the actual observed failure

The actual blocked request was a longer, private PowerShell automation command that included an [ordered]@{ ...; Operation='...' } logging field. start_process returned Command not allowed / INVALID_ARGUMENT immediately, before the requested process was started. Read-only inspection of the installed dist/tools/improved-process-tools.js showed it calls commandManager.validateCommand before terminalManager.executeCommand.

A local parser-only analysis of the preserved, private request isolated the same false-positive blocked token init. The complete original request and device/project paths are intentionally not shared.

Suspected parsing mechanism

In the v0.2.50 extractCommands implementation, the semicolon between PowerShell hashtable properties is treated as a command separator. extractBaseCommand then applies /\\w+=\\S+\\s*/g to a segment beginning with Operation='Device init ...', removing Operation='Device and incorrectly treating the next word init as the executable command.

This diagnosis is based on code inspection and in-memory parser replay, not on a patched runtime or a claim that every later permission gate would succeed.

Expected behavior

  • Hashtable property delimiters and literal, non-executed string content must not become shell commands.
  • Actually executable blocked commands (including nested/chained commands) must remain blocked.
  • Command substitutions in expandable PowerShell contexts must still be checked where execution is possible.
  • A parser regression test should demonstrate the false positive above is fixed and real init invocations are still rejected.

Requested resolution

Please provide a shell-aware command parser correction or a formally supported narrowly scoped approval mechanism. We do not request disabling the blocklist or workarounds through alternate execution tools.

Scope: This public report deliberately excludes all private paths, project names, device identities, firmware images, and logs.

Activity

  1. xyyxyyxx commented on Oct 11, 2026

    @xyyxyyxx
    Author

    Follow-up for a supported admission path, without changing the installed safety blocklist or rerouting a rejected command:

    • Rechecked on 2026-10-11: affected Remote Desktop Commander remains v0.2.50; the latest published release is v0.2.52, whose release notes do not identify a fix for this hashtable-literal parsing defect. The current upstream src/command-manager.ts still tokenizes semicolons within PowerShell hashtables as shell command separators.
    • Request a maintainer-confirmed fixed version/commit or a documented narrowly scoped, auditable approval mechanism for one reviewed command. A generic “update to latest” is not sufficient without a regression test.
    • Suggested acceptance tests: (1) the exact sanitized hashtable with Operation='Device init then read-only health check' is treated as literal data; (2) a genuinely executable blocked init is still denied; (3) chained and nested executable blocked commands remain denied; (4) PowerShell expandable $() contexts remain checked; (5) no relaxation of blockedCommands.
    • This differs from here-string PR fix(command-manager): support PowerShell here-strings to prevent false positive command blocking (#731) #792 and should be tested independently. Please advise the official correction/rollout and verification procedure.

    No local parser, safety configuration, runtime or permission bypass has been performed. We will keep the affected command blocked until the official correction is verified.

  2. xyyxyyxx commented on Oct 15, 2026

    @xyyxyyxx
    Author

    2026-10-15 follow-up: requesting maintainer triage and the supported resolution/admission procedure for this existing issue.

    We have preserved a further remote start_process rejection observed on 2026-10-14 (Command not allowed, outer INVALID_ARGUMENT, no PID). The complete rejected request includes a subsequent hardware workflow, not only JSON logging; it has not been resubmitted, rewritten or rerouted.

    Existing parser-only evidence for the preserved request shows a quoted hashtable value such as scope='Device init <=1; read-only diagnostics' being reduced to an executable-looking init token by assignment removal. This is offline reproduction, not an admission-server audit of the actual matched rule. Cached 0.2.50 and 0.2.51 classifier files had identical SHA-256; this does not establish the currently deployed server version. Our isolated proposal remains NOT DEPLOYABLE and has not been installed. No new parser investigation is requested here.

    Could a maintainer provide:

    1. An assigned owner and a fixed upstream version/commit, or an existing officially supported exact-request review mechanism (including where to submit the complete private request securely).
    2. The supported way to bind the deployed remote build and obtain non-executing admission diagnostics for the preserved request: selected shell, matched rule/token/span and parser errors. We will not launch it merely to generate another rejection.
    3. Release acceptance covering literal hashtable strings, genuine/chained/nested blocked invocations, expandable execution contexts, and fail-closed parser errors, with the existing blocklist retained.

    Our application correction is frozen separately. Any later changed application/source/electrical scope will need its own applicable review; it is not a renamed bypass of the original rejection. A successful unrelated command, issue closure, local mock test or generic user authorization will not be treated as admission.

    Private originals and existing reproducer materials are retained locally for a maintainer-designated secure channel. No device identifiers, private paths, credentials, firmware or full hardware launch command are included in this public follow-up.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions