# Agent Auto-Execute Command Injection via Process Substitution

- **Severity:** High
- **Signature ID:** `7c1a4e62-5b93-4f8d-a2d1-9e3f6b04c8a7`
- **OWASP:** LLM05 (Improper Output Handling), LLM06 (Excessive Agency)

## Summary

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.

## 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

- https://attack.mitre.org/techniques/T1059/004/
- https://owasp.org/Top10/A03_2021-Injection/
- https://genai.owasp.org/llmrisk/llm052025-improper-output-handling/

---
Source: https://www.netzilo.com/threats/roo-code-process-substitution-injection
