# Unsanitized argument command injection

Attacker string reaching a shell, argv, URI handler, or OS-open call without quoting or allowlisting

_Area: Memory corruption and native code. Seen in 10 disclosed reports; 4 confirmed bounties, median $6,250, range $1,000-$8,000; latest 2026-09-15. Updated 2026-10-23._

## How it works
An attacker-controlled value is placed into a command string, process command line, URI-handler dispatch, or OS-open call without quoting or validation. A second interpreter downstream — a shell, a shell-like tokenizer, an OS URI handler, a target program's argument parser, or a terminal line editor — re-reads metacharacters, spaces, quotes, control bytes, or scheme prefixes as syntax instead of data. The broken assumption is that the value is inert text. Shapes seen: true shell-metacharacter injection where the value is interpolated into a string a shell later parses [E8](https://bugbountylibrary.com/r/blog%3Aportswigger-net-research-drag-and-pwnd-leverage-ascii-characters-to-exploit-vs-code.md); argument/URI/open injection where the value becomes extra argv entries or a dispatched URI/file even with no shell involved [E1](https://bugbountylibrary.com/r/blog%3Asecret-club-2021-04-20-source-engine-rce-invite-html.md)[E2](https://bugbountylibrary.com/r/blog%3Apositive-security-blog-ms-officecmd-rce.md)[E3](https://bugbountylibrary.com/r/blog%3Ajfrog-com-blog-parallels-desktop-turns-appliance-install-into-root-shell.md)[E5](https://bugbountylibrary.com/r/h1%3A1720043.md)[E6](https://bugbountylibrary.com/r/h1%3A784714.md)[E7](https://bugbountylibrary.com/r/blog%3Agithub-com-metnew-telegram-links-nsworkspace-open.md); and format-string injection where the value is read as a format template [E4](https://bugbountylibrary.com/r/h1%3A127212.md).

## Where it shows up
- `system()`/`sprintf` sites formatting input as `%s` instead of a typed value [E4](https://bugbountylibrary.com/r/h1%3A127212.md)
- Privileged helpers building a command string with quotes then re-tokenized by a shell-like splitter (Qt splitCommand) [E3](https://bugbountylibrary.com/r/blog%3Ajfrog-com-blog-parallels-desktop-turns-appliance-install-into-root-shell.md)
- URI handlers forwarding a JSON field into a child process command line [E2](https://bugbountylibrary.com/r/blog%3Apositive-security-blog-ms-officecmd-rce.md)
- User strings appended to a game/app command line, reaching console commands [E1](https://bugbountylibrary.com/r/blog%3Asecret-club-2021-04-20-source-engine-rce-invite-html.md)
- Deeplinks resolving to local paths passed to an OS open/execute call [E5](https://bugbountylibrary.com/r/h1%3A1720043.md)
- Bare binary names in `exec.Command`/`os.system` resolved via attacker-influenced PATH [E6](https://bugbountylibrary.com/r/h1%3A784714.md)
- Link previews passing arbitrary schemes (file://, ssh://) to an OS open handler [E7](https://bugbountylibrary.com/r/blog%3Agithub-com-metnew-telegram-links-nsworkspace-open.md)
- Raw bytes (SOH/ETX/CR) in args or filenames reaching a PTY/readline [E8](https://bugbountylibrary.com/r/blog%3Aportswigger-net-research-drag-and-pwnd-leverage-ascii-characters-to-exploit-vs-code.md)

## How to review
Trace every attacker-reachable input to the sink and confirm the invariant per shape: (a) shell sinks — value passed as a discrete argument via list-form exec (e.g. `exec.Command("tar", "-xf", path)`), never interpolated into a shell string; (b) argv sinks — value cannot introduce new arguments (no quote/space breakout); (c) URI/open sinks — scheme and target allowlisted, and open does not execute; (d) tokenizer sinks — no string is built then re-split; (e) format sinks — value always passed as `%s` data, never as the template [E4](https://bugbountylibrary.com/r/h1%3A127212.md); (f) PTY sinks — control bytes stripped before reaching the line editor [E8](https://bugbountylibrary.com/r/blog%3Aportswigger-net-research-drag-and-pwnd-leverage-ascii-characters-to-exploit-vs-code.md); (g) exec sinks — absolute binary paths, not PATH-resolved names [E6](https://bugbountylibrary.com/r/h1%3A784714.md). For patches, check every path to the sink, not just the field touched.

## Variants seen
- Console-command injection via appended connect string, delivery vector for a later memory bug [E1](https://bugbountylibrary.com/r/blog%3Asecret-club-2021-04-20-source-engine-rce-invite-html.md)
- URI scheme handler passing unsanitized URI to OS shell [E2](https://bugbountylibrary.com/r/blog%3Apositive-security-blog-ms-officecmd-rce.md)
- Argument injection via quote/space breakout in URI handler [E2](https://bugbountylibrary.com/r/blog%3Apositive-security-blog-ms-officecmd-rce.md)
- Quote breakout through a shell-like tokenizer, no shell [E3](https://bugbountylibrary.com/r/blog%3Ajfrog-com-blog-parallels-desktop-turns-appliance-install-into-root-shell.md)
- Deeplink path to OS open/execute [E5](https://bugbountylibrary.com/r/h1%3A1720043.md)
- PATH hijack via bare binary name [E6](https://bugbountylibrary.com/r/h1%3A784714.md)
- Arbitrary scheme to OS open handler [E7](https://bugbountylibrary.com/r/blog%3Agithub-com-metnew-telegram-links-nsworkspace-open.md)
- Format-string via error string passed as template [E4](https://bugbountylibrary.com/r/h1%3A127212.md)
- Control-character injection into PTY/readline [E8](https://bugbountylibrary.com/r/blog%3Aportswigger-net-research-drag-and-pwnd-leverage-ascii-characters-to-exploit-vs-code.md)

## Why fixes fail
E2 notes a runtime fix (Electron argument drop) that exempts short schemes, leaving a gap. E3 shows a privileged helper trusting peer credentials without an identity check, so the injection path stayed reachable.

## Impact and severity
Reached root RCE via a privileged helper [E3](https://bugbountylibrary.com/r/blog%3Ajfrog-com-blog-parallels-desktop-turns-appliance-install-into-root-shell.md), drive-by RCE via a link [E2](https://bugbountylibrary.com/r/blog%3Apositive-security-blog-ms-officecmd-rce.md), client RCE [E1](https://bugbountylibrary.com/r/blog%3Asecret-club-2021-04-20-source-engine-rce-invite-html.md)[E5](https://bugbountylibrary.com/r/h1%3A1720043.md), local privilege escalation [E6](https://bugbountylibrary.com/r/h1%3A784714.md), and code execution via format string [E4](https://bugbountylibrary.com/r/h1%3A127212.md). Severity is high because the sink often runs privileged and needs no auth; pre-auth and local-privilege paths made it worse [E3](https://bugbountylibrary.com/r/blog%3Ajfrog-com-blog-parallels-desktop-turns-appliance-install-into-root-shell.md).

## Evidence
- E1: https://bugbountylibrary.com/r/blog%3Asecret-club-2021-04-20-source-engine-rce-invite-html.md
- E2: https://bugbountylibrary.com/r/blog%3Apositive-security-blog-ms-officecmd-rce.md
- E3: https://bugbountylibrary.com/r/blog%3Ajfrog-com-blog-parallels-desktop-turns-appliance-install-into-root-shell.md
- E4: https://bugbountylibrary.com/r/h1%3A127212.md
- E5: https://bugbountylibrary.com/r/h1%3A1720043.md
- E6: https://bugbountylibrary.com/r/h1%3A784714.md
- E7: https://bugbountylibrary.com/r/blog%3Agithub-com-metnew-telegram-links-nsworkspace-open.md
- E8: https://bugbountylibrary.com/r/blog%3Aportswigger-net-research-drag-and-pwnd-leverage-ascii-characters-to-exploit-vs-code.md
