Skip to content

runtime: harden external process invocation - #93

Merged
Gregory Joseph (gnjoseph) merged 3 commits into
microsoft:feat/spe-mcp-serverfrom
gnjoseph:fix/process-invocation-hardening
Aug 20, 2026
Merged

runtime: harden external process invocation#93
Gregory Joseph (gnjoseph) merged 3 commits into
microsoft:feat/spe-mcp-serverfrom
gnjoseph:fix/process-invocation-hardening

Conversation

@gnjoseph

Copy link
Copy Markdown
Collaborator

Summary

  • centralize external CLI launches behind a shell-free process abstraction
  • validate Azure subscription and resource-group identifiers at tool and helper boundaries
  • preserve Windows CLI shim resolution, timeout, error, and detached-process behavior
  • bump the package to 0.2.0-alpha.2 and add focused process-boundary regression coverage

Validation

  • npm run ci - 893 passed, 7 skipped
  • npm pack --dry-run - @microsoft/spe-mcp@0.2.0-alpha.2
  • deterministic process-invocation eval - 4/4 passed
  • base mock eval - 12/12 passed
  • safety mock eval - 6/6 passed
  • deploy-loop mock verification - passed
  • live deploy-loop once and one-shot - deployment, redirect registration, and teardown succeeded; both still exceed the existing 120-second performance target

Reviewer notes

cross-spawn is promoted from a transitive dependency to a direct dependency so Windows command shims can be resolved without enabling shell parsing. Public fixtures use inert punctuation-only inputs.

grjoseph and others added 3 commits August 20, 2026 13:46
Route all Azure CLI (az), Azure Developer CLI (azd), and local dev-server
child processes through a single shared, shell-free launcher (src/proc-exec.ts)
that resolves platform executable shims (including Windows .cmd/.bat) without
spawning a command interpreter. Arguments are never passed through a shell, so
shell metacharacters in user-influenced values can no longer alter the executed
command line.

Add strict allowlist validation for Azure subscription IDs and resource-group
names, enforced at the tool boundary and re-asserted at the process-invocation
boundary as defense-in-depth. Add focused unit/integration regression tests,
including shell-metacharacter payloads and a valid GUID path. Valid inputs and
existing behavior are unchanged.

Adds cross-spawn (^7.0.6) runtime dependency and @types/cross-spawn dev
dependency; regenerates package-lock.json and THIRD-PARTY-NOTICES; bumps the
package to 0.2.0-alpha.2.

AB#3116729
Copilot-Session-Id: 9b07fed7-d2cf-4209-8682-6c3004401c04
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add durable offline coverage asserting both boundaries of the shell-free process launcher:

1) malformed, externally-influenced CLI identifiers are rejected before any spawn (validator throws/returns an error and the launcher is never invoked); and 2) every legal-but-shell-sensitive argument that reaches az/azd/npm stays a single discrete argv element with shell left falsy.

New src/azure-cli.proc.test.ts exercises the proc-exec seam for listResourceGroups/resourceGroupExists/showSyntexProvider/registerSyntexProvider; proc-exec.test.ts and deploy-azure.test.ts gain punctuation-heavy discrete-argv cases.

AB#3116729

Copilot-Session-Id: 9b07fed7-d2cf-4209-8682-6c3004401c04

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Replace illustrative command-name examples in the process-invocation safety fixtures with inert, punctuation-only tokens. Reject-before-spawn and discrete-argv coverage is preserved: every invalid token still trips the same allowlist branch, and valid legal-but-sensitive values are retained.

AB#3116729
Copilot-Session-Id: 9b07fed7-d2cf-4209-8682-6c3004401c04
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@gnjoseph
Gregory Joseph (gnjoseph) merged commit d637877 into microsoft:feat/spe-mcp-server Aug 20, 2026
5 of 6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant