Bug Description
The TCP server (autoagent/tcp_server.py) and local environment runner (autoagent/environment/local_env.py) both construct shell commands by directly interpolating user-supplied strings into a shell command template, then executing with subprocess.Popen(..., shell=True).
Any input containing shell metacharacters (;, |, $(), backticks) will be interpreted by the shell, enabling arbitrary command execution.
Location
autoagent/tcp_server.py:38-39
autoagent/environment/local_env.py:76-77
autoagent/environment/tcp_server.py:42-43
Reproduction
For tcp_server.py, a client connected to the TCP socket can send:
echo hello; id; cat /etc/passwd
This gets interpolated into:
/bin/bash -c 'source ... && conda activate autogpt && cd /workplace && echo hello; id; cat /etc/passwd'
The id and cat /etc/passwd commands execute on the host.
For local_env.py, any command passed to run_command() is similarly interpolated:
modified_command = f"/bin/bash -c 'source {self.conda_sh} && conda activate auto && cd {self.docker_workplace} && {command}'"
Impact
Remote Code Execution (RCE). An attacker who can send commands to the TCP server or trigger run_command() can execute arbitrary system commands with the process's privileges. This is especially critical because AutoAgent is designed to execute LLM-generated commands — a compromised or jailbroken LLM could exploit this to escape the intended execution boundary.
Suggested Fix
Use subprocess.run() with shell=False and pass arguments as a list:
# Instead of shell=True with string interpolation:
process = subprocess.Popen(
["/bin/bash", "-c",
f"source {conda_sh} && conda activate auto && cd {workplace} && exec \"$@\"",
"--", command],
stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True
)
Or better yet, use shlex.quote() to escape the command:
import shlex
safe_command = shlex.quote(command)
modified_command = f"/bin/bash -c 'source {self.conda_sh} && conda activate auto && cd {self.docker_workplace} && {safe_command}'"
Found via codebase analysis. Happy to submit a PR if confirmed.
Bug Description
The TCP server (
autoagent/tcp_server.py) and local environment runner (autoagent/environment/local_env.py) both construct shell commands by directly interpolating user-supplied strings into a shell command template, then executing withsubprocess.Popen(..., shell=True).Any input containing shell metacharacters (
;,|,$(), backticks) will be interpreted by the shell, enabling arbitrary command execution.Location
autoagent/tcp_server.py:38-39autoagent/environment/local_env.py:76-77autoagent/environment/tcp_server.py:42-43Reproduction
For
tcp_server.py, a client connected to the TCP socket can send:This gets interpolated into:
/bin/bash -c 'source ... && conda activate autogpt && cd /workplace && echo hello; id; cat /etc/passwd'The
idandcat /etc/passwdcommands execute on the host.For
local_env.py, any command passed torun_command()is similarly interpolated:Impact
Remote Code Execution (RCE). An attacker who can send commands to the TCP server or trigger
run_command()can execute arbitrary system commands with the process's privileges. This is especially critical because AutoAgent is designed to execute LLM-generated commands — a compromised or jailbroken LLM could exploit this to escape the intended execution boundary.Suggested Fix
Use
subprocess.run()withshell=Falseand pass arguments as a list:Or better yet, use
shlex.quote()to escape the command:Found via codebase analysis. Happy to submit a PR if confirmed.