# Command injection via option parsing gaps

Allowlisted binaries or validators that miss exec-style flags, spaces, or =/# in option names

_Area: Web injection and code execution. Seen in 3 disclosed reports; latest 2026-10-08. Updated 2026-10-24._

## How it works
A command is built by concatenating user input into an argument list or config line. The defense assumes that blocking shell metacharacters (or checking the first token against an allowlist) makes the input safe. That assumption breaks in two ways: the input can still contain spaces, so it becomes extra arguments to the same binary; or the allowlisted binary itself has flags that execute programs or write files. The validator checks the wrong property — character set of the input, not the meaning of the resulting argument vector.

## Where it shows up
- Input concatenated into a shell string where only metacharacters are escaped but whitespace is not [E1](https://bugbountylibrary.com/r/h1%3A212696.md)
- Allowlists that check only the first token, then pass the rest through [E2](https://bugbountylibrary.com/r/ghsa%3AGHSA-cv3g-hj65-pcfh.md)
- Allowlisted binaries with built-in exec/file actions: `find -exec/-execdir/-delete/-ok`, `tar --to-command`, `awk system()`, `git -c core.pager`, `xargs`, `sed e` [E2](https://bugbountylibrary.com/r/ghsa%3AGHSA-cv3g-hj65-pcfh.md)
- Validators gated on a label/context parameter, leaving sibling labels covered only by a weak regex [E3](https://bugbountylibrary.com/r/ghsa%3AGHSA-jm78-9fvv-mhgr.md)
- Config writers that emit option names verbatim into a line where `=`, `#`, `;`, brackets or whitespace change parsing [E3](https://bugbountylibrary.com/r/ghsa%3AGHSA-jm78-9fvv-mhgr.md)

## How to review
Trace every user-controlled value to the exact sink (argv element, config line, shell string). The invariant: after construction, the user value must occupy exactly one argument or one config field, and no allowlisted binary may be invoked with a flag that executes or writes. Check that escaping covers whitespace and quoting, not just metacharacters [E1](https://bugbountylibrary.com/r/h1%3A212696.md); that allowlists are per-binary and reject exec-style flags [E2](https://bugbountylibrary.com/r/ghsa%3AGHSA-cv3g-hj65-pcfh.md); and that every label reaching a sink gets the same strict validation, not just the one the fix targeted [E3](https://bugbountylibrary.com/r/ghsa%3AGHSA-jm78-9fvv-mhgr.md).

## Variants seen
- Space-only gap in an otherwise escaped shell command, injecting flags into an image tool [E1](https://bugbountylibrary.com/r/h1%3A212696.md)
- Allowlisted binary with its own execution actions bypassing metacharacter blocks [E2](https://bugbountylibrary.com/r/ghsa%3AGHSA-cv3g-hj65-pcfh.md)
- Option-name injection via `=`/`#`/whitespace forging dangerous git config keys [E3](https://bugbountylibrary.com/r/ghsa%3AGHSA-jm78-9fvv-mhgr.md)

## Why fixes fail
E2 shows chained fixes that blocked metacharacters but left the allowlisted binary's exec flags open. E3 shows a fix that hardened section names but left option names on a weak CR/LF/NUL check — the same sink reached through a sibling label.

## Impact and severity
All three reach remote code execution [E1](https://bugbountylibrary.com/r/h1%3A212696.md)[E2](https://bugbountylibrary.com/r/ghsa%3AGHSA-cv3g-hj65-pcfh.md)[E3](https://bugbountylibrary.com/r/ghsa%3AGHSA-jm78-9fvv-mhgr.md). Severity is high because the bypass needs no shell metacharacters, so standard filters give false confidence; worse when the sink runs with service privileges or the tool is an agent sandbox.

## Evidence
- E1: https://bugbountylibrary.com/r/h1%3A212696.md
- E2: https://bugbountylibrary.com/r/ghsa%3AGHSA-cv3g-hj65-pcfh.md
- E3: https://bugbountylibrary.com/r/ghsa%3AGHSA-jm78-9fvv-mhgr.md
