# Request input reaching subprocess argv

Request fields flowing into subprocess argv, executable choice, or env vars like NODE_OPTIONS

_Area: Web injection and code execution. Seen in 4 disclosed reports; latest 2026-05-19. Updated 2026-11-01._

## How it works
A server takes a request field and uses it, directly or after weak filtering, as a subprocess command, an argument token, or an environment variable. The broken assumption is that a denylist, a falsy auth check, or a substring guard makes the input safe. Each guard is incomplete: it misses a subcommand, a long flag alias, a doubled path separator, or an unset-token branch, so attacker text still lands in argv and the OS executes it.

## Where it shows up
- Config fields passed into `exec`/`spawn` argv, such as `sshArguments` space-split into ssh argv [E2](https://bugbountylibrary.com/r/ghsa%3AGHSA-2q4c-3mrw-63c3.md)
- Per-command denylists gating subprocess execution (docker, npx, node) [E1](https://bugbountylibrary.com/r/ghsa%3AGHSA-m99r-2hxc-cp3q.md)
- Auth guards wrapped in `if (this.accessToken)` where the default is empty string [E3](https://bugbountylibrary.com/r/ghsa%3AGHSA-wvr4-3wq4-gpc5.md)
- Shared authz helpers that authorize all UI endpoints when the authenticator is nil ("no password" mode) [E2](https://bugbountylibrary.com/r/ghsa%3AGHSA-2q4c-3mrw-63c3.md)
- Validation branches using `.includes()` instead of `.startsWith()`, or skipping an enablement check [E4](https://bugbountylibrary.com/r/ghsa%3AGHSA-cvrr-qhgw-2mm6.md)
- Env-var blocklists that omit `NODE_OPTIONS` or similar loader hooks [E4](https://bugbountylibrary.com/r/ghsa%3AGHSA-cvrr-qhgw-2mm6.md)
- Regex path guards like `/^\/[^/]/` that miss `//`-prefixed paths [E1](https://bugbountylibrary.com/r/ghsa%3AGHSA-m99r-2hxc-cp3q.md)

## How to review
Trace every request field to its sink and ask: can this string become an executable, an argv token, or an env var? For each allowed binary, enumerate its full subcommand and flag surface (docker build/pull/push/cp/commit, npx `--yes` as well as `-y`) and confirm the guard covers all of it [E1](https://bugbountylibrary.com/r/ghsa%3AGHSA-m99r-2hxc-cp3q.md). For auth, verify the guard fails closed when the token is unset, not open [E3](https://bugbountylibrary.com/r/ghsa%3AGHSA-wvr4-3wq4-gpc5.md); for shared authz helpers, confirm a nil authenticator denies rather than allows [E2](https://bugbountylibrary.com/r/ghsa%3AGHSA-2q4c-3mrw-63c3.md). For sentinels, require exact prefix matching and that the authorization check still runs on the matched branch [E4](https://bugbountylibrary.com/r/ghsa%3AGHSA-cvrr-qhgw-2mm6.md). The invariant: no request value may reach argv, executable selection, or a security-relevant env var without an allowlist that covers the whole surface.

## How finders spotted it
- Read the command validator and noticed the docker list omitted build/pull/push/cp/commit, npx only blocked `-y`, and the path regex failed on `//`; then built PoCs [E1](https://bugbountylibrary.com/r/ghsa%3AGHSA-m99r-2hxc-cp3q.md)
- Read the authz path showing a nil authenticator authorizes all UI endpoints, then read the SFTP code where `sshArguments` is space-split into ssh argv, and recalled OpenSSH `-oProxyCommand` shell semantics [E2](https://bugbountylibrary.com/r/ghsa%3AGHSA-2q4c-3mrw-63c3.md)
- Noticed `authToken` defaults to empty and the guard is `if (this.accessToken)`, a falsy check that skips enforcement; then traced `/bridge` body into command execution [E3](https://bugbountylibrary.com/r/ghsa%3AGHSA-wvr4-3wq4-gpc5.md)
- Noticed `.includes()` rather than `.startsWith()` and that the branch skips `isParameterEnabled()`; then audited the env blocklist and found `NODE_OPTIONS` missing [E4](https://bugbountylibrary.com/r/ghsa%3AGHSA-cvrr-qhgw-2mm6.md)

## Variants seen
- Incomplete per-command denylist plus regex path-guard bypass [E1](https://bugbountylibrary.com/r/ghsa%3AGHSA-m99r-2hxc-cp3q.md)
- Space-split argument injection into ssh argv via `-oProxyCommand` [E2](https://bugbountylibrary.com/r/ghsa%3AGHSA-2q4c-3mrw-63c3.md)
- Falsy-default auth token disabling enforcement on an unauthenticated endpoint [E3](https://bugbountylibrary.com/r/ghsa%3AGHSA-wvr4-3wq4-gpc5.md)
- Substring sentinel bypassing parameter authorization, chained to env-var injection [E4](https://bugbountylibrary.com/r/ghsa%3AGHSA-cvrr-qhgw-2mm6.md)

## Impact and severity
All four reach remote code execution. Severity rises with reach and privilege: unauthenticated endpoints [E2](https://bugbountylibrary.com/r/ghsa%3AGHSA-2q4c-3mrw-63c3.md)[E3](https://bugbountylibrary.com/r/ghsa%3AGHSA-wvr4-3wq4-gpc5.md)[E4](https://bugbountylibrary.com/r/ghsa%3AGHSA-cvrr-qhgw-2mm6.md) outrank the authenticated-only path [E1](https://bugbountylibrary.com/r/ghsa%3AGHSA-m99r-2hxc-cp3q.md). Where the process runs as root or can deploy privileged containers, execution enables host takeover, secret theft, and lateral movement [E1](https://bugbountylibrary.com/r/ghsa%3AGHSA-m99r-2hxc-cp3q.md)[E4](https://bugbountylibrary.com/r/ghsa%3AGHSA-cvrr-qhgw-2mm6.md); otherwise it is RCE as the service user. Chaining a validation bypass with a missing env-var blocklist turned a parameter-override flaw into command execution [E4](https://bugbountylibrary.com/r/ghsa%3AGHSA-cvrr-qhgw-2mm6.md).

## Evidence
- E1: https://bugbountylibrary.com/r/ghsa%3AGHSA-m99r-2hxc-cp3q.md
- E2: https://bugbountylibrary.com/r/ghsa%3AGHSA-2q4c-3mrw-63c3.md
- E3: https://bugbountylibrary.com/r/ghsa%3AGHSA-wvr4-3wq4-gpc5.md
- E4: https://bugbountylibrary.com/r/ghsa%3AGHSA-cvrr-qhgw-2mm6.md
