Skip to content

fix(typespec-vscode): prevent shell injection in tsp compile task - #11275

Merged
timotheeguerin merged 2 commits into
release/july-2026from
fix/vscode-task-shell-injection
Jul 16, 2026
Merged

fix(typespec-vscode): prevent shell injection in tsp compile task#11275
timotheeguerin merged 2 commits into
release/july-2026from
fix/vscode-task-shell-injection

Conversation

@timotheeguerin

Copy link
Copy Markdown
Member

Summary

Fixes a shell command injection vulnerability in the TypeSpec VS Code task provider.

Data flow (source → sink)

  • extension.ts registers createTaskProvider() on activation (default-on).
  • task-provider.tsvscode.workspace.findFiles('**/main.tsp', ...) collects workspace paths, including attacker-controllable directory names; task.definition.path/args also come from user-authored tasks.json.
  • The resolved path/args were interpolated (wrapped only in double quotes) into a command string and passed to new vscode.ShellExecution(cmd, ...), which executes it via the OS shell → command injection.

Fix

Replace vscode.ShellExecution with vscode.ProcessExecution, passing arguments as an array so no shell is involved and no escaping is required.

  • New src/task-command.ts with pure, testable helpers:
    • splitArgsquote-aware tokenizer (respects single/double quotes) so legitimate tasks.json args with spaces keep working; performs no shell expansion.
    • resolveTaskCommand — builds { command, args[] } as [...cli.args, "compile", absoluteTargetPath, ...splitArgs(args)], resolving ${...} variables per element.
  • createTaskInternal now uses these helpers + vscode.ProcessExecution (both cwd and no-cwd branches).

Logic was extracted into a separate module because the unit-test environment has no real vscode module.

Behavior note

Shell features ($VAR, &&, globbing) in tasks.json args are no longer shell-interpreted — the intended hardening. Quoting to group tokens with spaces still works.

Tests

  • New test/unit/task-command.test.ts (9 tests): empty/--watch args, quoted args with spaces, ${workspaceFolder} resolution, and an injection path ($(rm -rf ~)...) verified to remain a single literal argument.
  • Full unit suite passes (11 tests); Prettier + oxlint clean.

@microsoft-github-policy-service microsoft-github-policy-service Bot added the ide Issues for VS, VSCode, Monaco, etc. label Jul 16, 2026
@github-actions

Copy link
Copy Markdown
Contributor

No changes needing a change description found.

@timotheeguerin
timotheeguerin force-pushed the fix/vscode-task-shell-injection branch from 263b4ba to 1627b7d Compare July 16, 2026 16:56
@timotheeguerin
timotheeguerin changed the base branch from main to release/july-2026 July 16, 2026 16:56
@timotheeguerin
timotheeguerin force-pushed the fix/vscode-task-shell-injection branch from 1627b7d to 8bb7167 Compare July 16, 2026 17:01
@azure-sdk-automation

azure-sdk-automation Bot commented Jul 16, 2026

Copy link
Copy Markdown

You can try these changes here

🛝 Playground 🌐 Website 🛝 VSCode Extension

Use vscode.ProcessExecution with an argument array instead of
vscode.ShellExecution so workspace file paths and task arguments are
never interpreted by the OS shell.
@timotheeguerin
timotheeguerin force-pushed the fix/vscode-task-shell-injection branch from 8bb7167 to 74839fe Compare July 16, 2026 17:03
@timotheeguerin
timotheeguerin marked this pull request as ready for review July 16, 2026 17:12
@timotheeguerin
timotheeguerin enabled auto-merge (squash) July 16, 2026 21:56
@timotheeguerin
timotheeguerin disabled auto-merge July 16, 2026 22:03
@pkg-pr-new

pkg-pr-new Bot commented Jul 16, 2026

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/@typespec/spector@11275

commit: a097b02

@timotheeguerin
timotheeguerin merged commit ae3dd50 into release/july-2026 Jul 16, 2026
18 of 24 checks passed
@timotheeguerin
timotheeguerin deleted the fix/vscode-task-shell-injection branch July 16, 2026 22:07
jorgerangel-msft pushed a commit to jorgerangel-msft/typespec that referenced this pull request Jul 17, 2026
Backmerges `release/july-2026` into `main` to bring hotfix commits back
to the development branch.

## Changes from release/july-2026
- **fix(typespec-vscode):** prevent shell injection in tsp compile task
(microsoft#11275)
- **fix(spector):** prevent unauthenticated remote server stop (microsoft#11274)
- **chore:** version bumps for hotfixes (microsoft#11281)

---------

Co-authored-by: Timothee Guerin <tiguerin@microsoft.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ide Issues for VS, VSCode, Monaco, etc.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants