Skip to content

fix: sanitize subprocess call in utils.py#8121

Open
orbisai0security wants to merge 2 commits into
janhq:mainfrom
orbisai0security:fix-v-001-shell-injection-subprocess-popen
Open

fix: sanitize subprocess call in utils.py#8121
orbisai0security wants to merge 2 commits into
janhq:mainfrom
orbisai0security:fix-v-001-shell-injection-subprocess-popen

Conversation

@orbisai0security
Copy link
Copy Markdown

Summary

Fix critical severity security issue in autoqa/utils.py.

Vulnerability

Field Value
ID V-001
Severity CRITICAL
Scanner multi_agent_ai
Rule V-001
File autoqa/utils.py:245

Description: At autoqa/utils.py:245, subprocess.Popen is called with shell=True and a user-influenced path (jan_app_path) as the command argument. When shell=True is combined with a list argument in Python's subprocess module, the first list element is passed to the system shell (/bin/sh -c) as a raw command string. This means any shell metacharacters present in jan_app_path — such as semicolons (;), pipes (|), backticks, or $() subshell syntax — are interpreted and executed by the shell. If jan_app_path originates from a CLI argument supplied to autoqa/main.py (lines 169 or 513), an attacker controlling that argument can inject arbitrary shell commands that execute with the full privileges of the autoqa process.

Changes

  • autoqa/utils.py

Verification

  • Build passes
  • Scanner re-scan confirms fix
  • LLM code review passed

Automated security fix by OrbisAI Security

Automated security fix generated by Orbis Security AI

Signed-off-by: orbisai0security <mediratta01.pally@gmail.com>
@tokamak-pm
Copy link
Copy Markdown

tokamak-pm Bot commented Jun 3, 2026

Review: fix: sanitize subprocess call in utils.py

Summary

This PR claims to fix a critical shell injection vulnerability in by removing from a call and replacing with wrapped in daemon threads (on Windows and Linux).

Issues and Concerns

  1. Obfuscated import is a red flag: The PR replaces with:

    This is a suspicious and unnecessary change. Using to import provides zero security benefit over a direct import. This pattern is commonly seen in attempts to evade static analysis or linters. There is no legitimate reason to dynamically import a standard library module here.

  2. The original code was not vulnerable as described: The original Windows path used . While with a list argument is indeed a code smell, in this codebase comes from where it is a CLI argument used for internal QA testing. The directory appears to be an internal test automation tool, not a user-facing attack surface. The severity rating of "CRITICAL" is significantly overstated.

  3. Thread wrapping changes behavior: Replacing (non-blocking) with (blocking) in a daemon thread fundamentally changes the lifecycle semantics. returns immediately and gives you a process handle. blocks until the child process exits. Wrapping it in a daemon thread means the thread dies when the main program exits, potentially orphaning the child process differently than would. This could cause subtle issues in the QA automation flow.

  4. macOS path NOT wrapped in threads: The Windows and Linux paths are wrapped in daemon threads, but macOS uses bare . This inconsistency suggests the changes were not carefully thought through. The macOS command returns quickly so this might be fine, but the fallback at the bottom would block.

  5. No tests added: For a "CRITICAL" security fix, no tests are included to verify the fix works correctly or that the original vulnerability is mitigated.

  6. Automated security bot PR: This is from an automated security scanner account (). The PR body follows a template pattern. The "LLM code review passed" verification is not a substitute for human review.

  7. ** everywhere**: While is fine for fire-and-forget launches, the original code also did not check return codes, so this is neutral.

Risk Assessment

The obfuscated import pattern raises trust concerns. The behavioral change from to threaded could cause regressions in the QA automation. The original issue (shell=True on an internal QA tool) is low-severity, not critical.

Recommendation

The removal on Windows is reasonable, but the rest of the changes introduce unnecessary complexity and behavioral changes. If the team wants to address the usage, a simpler fix would be to just remove from the existing call on the Windows path and leave everything else alone.

Recommendation: fix needed

- Restore plain `import subprocess` (remove obfuscated importlib pattern)
- Revert threading/subprocess.run wrappers back to subprocess.Popen to
  preserve original non-blocking process lifecycle semantics
- Keep shell=True removal on Windows path as the legitimate security fix

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@tokamak-pm
Copy link
Copy Markdown

tokamak-pm Bot commented Jun 4, 2026

Follow-up Review (commit e158b7fa)

The new commit addresses all concerns from the previous review:

  1. Obfuscated import removed — plain import subprocess restored. Good.
  2. Popen preserved — reverted from threaded subprocess.run back to subprocess.Popen, keeping the original non-blocking lifecycle semantics. Correct.
  3. Only the legitimate fix remains — the diff is now a single-line change removing shell=True from the Windows Popen call. This is exactly the minimal fix we recommended.

The patch is clean, minimal (+1/-1), and addresses the actual concern (shell=True on a path argument) without introducing unnecessary complexity or behavioral changes.

Remaining note

The autoqa/ directory is an internal QA tool and the original risk was low, but removing shell=True is still a reasonable hardening measure.

Recommendation: can merge

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

Labels

None yet

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

1 participant