High

Agent Auto-Execute Command Injection via Process Substitution

Some AI coding assistants let a user approve a shell command before it runs, but the approval only looks at the command as a whole, not at hidden extra commands stitched into it. An attacker who can influence what the model outputs can slip a second, unrelated command into the approved one using bash/zsh tricks, and it runs silently with the agent's permissions.

How the attack works

The attacker crafts a prompt so the model generates a shell command containing process substitution syntax (<(...) or >(...)) or a single '&' followed by another program. The user or auto-approve feature sees what looks like one normal command and approves it. When the shell actually runs it, the hidden segment executes as a separate process alongside the intended one. If that hidden segment launches an interpreter, a network tool, or a credential-reading utility, the attacker gains code execution or data access using the agent's privileges, without a second approval prompt.

Netzilo detection

Netzilo reports this behaviour when it is observed.

Signature ID
7c1a4e62-5b93-4f8d-a2d1-9e3f6b04c8a7
Severity
High

Why it matters

An attacker gets arbitrary command execution or credential/data exfiltration on the machine running the agent, disguised inside a command the operator believed they had reviewed and approved.

What you can do

  • Do not rely on a single free-text approval step for agent-generated shell commands; parse and display the actual command tree, including substitutions and backgrounded segments, before execution.
  • Restrict or flag agent-issued commands that include <(...), >(...) or a lone '&' combined with interpreters (bash, python, node, etc.), network clients (curl, wget, nc) or credential tools (cat ~/.ssh, aws configure, etc.).
  • Run agent shell sessions under a reduced-privilege account so a smuggled command has limited reach even if it executes.
  • Log and review executed process trees for agent sessions, not just the approved command text, so injected child processes are visible after the fact.

Known benign look-alikes

  • Developer bootstrap one-liners that legitimately use process substitution to run a remote installer, e.g. `bash <(curl -fsSL ...)` for nvm, rustup or oh-my-zsh, executed intentionally by the user through the agent terminal.
  • Comparison workflows that pipe interpreter output through process substitution, e.g. `diff <(python -m json.tool a.json) <(python -m json.tool b.json)` or `<(env)`.
  • Build and dev-server workflows that background one task with a single ampersand and immediately start an interpreter, e.g. `npm run watch & node server.js` or `tsc -w & python manage.py runserver`.
  • Security research or rule-development sessions where the literal injection syntax is passed as an argument to a scanner or grep. Partially suppressed by filter_scanner_inline_pattern; plain `grep`/`rg` invocations are intentionally NOT suppressed because that filter would be trivially abusable as a bypass.
  • Documentation, commit messages and README snippets echoed to a terminal. Suppressed by filter_quoted_literal when the metacharacter is inside the quoted string.
  • Shell scripts that background a cleanup job and then reference a helper under /tmp, e.g. `long_job & /tmp/notify.sh`.

References

Related threats