hermes - 💡(How to fix) Fix Command injection via shell=True in tui_gateway/server.py [1 comments, 2 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
NousResearch/hermes-agent#16560Fetched 2026-04-28 06:52:32
View on GitHub
Comments
1
Participants
2
Timeline
5
Reactions
0
Timeline (top)
labeled ×3commented ×1referenced ×1

Two instances of command injection via subprocess.run(..., shell=True) in tui_gateway/server.py.

Root Cause

Two instances of command injection via subprocess.run(..., shell=True) in tui_gateway/server.py.

Code Example

qcmds = _load_cfg().get("quick_commands", {})
if name in qcmds:
    qc = qcmds[name]
    if qc.get("type") == "exec":
        r = subprocess.run(qc.get("command", ""), shell=True, capture_output=True, text=True, timeout=30)

---

r = subprocess.run(cmd, shell=True, capture_output=True, text=True, timeout=30, cwd=os.getcwd())
RAW_BUFFERClick to expand / collapse

Description

Two instances of command injection via subprocess.run(..., shell=True) in tui_gateway/server.py.

Instance 1: Quick commands (line 2308)

qcmds = _load_cfg().get("quick_commands", {})
if name in qcmds:
    qc = qcmds[name]
    if qc.get("type") == "exec":
        r = subprocess.run(qc.get("command", ""), shell=True, capture_output=True, text=True, timeout=30)

The command value comes from user config (_load_cfg()) with zero sanitization.

Instance 2: HTTP command execution (line 3131)

r = subprocess.run(cmd, shell=True, capture_output=True, text=True, timeout=30, cwd=os.getcwd())

User-supplied command from HTTP request params is passed directly to a shell. The safety check (detect_dangerous_command) is wrapped in except ImportError: pass, so if the import fails, all commands run unfiltered.

Impact

Severity: Critical — Direct shell command injection.

Suggested Fix

  • Replace shell=True with subprocess.run(shlex.split(cmd), shell=False, ...)
  • For quick commands, validate/sanitize before execution
  • Change except ImportError: pass to block execution when the safety module is unavailable

🤖 Generated with Claude Code

extent analysis

TL;DR

Replace shell=True with shell=False and properly sanitize user input to prevent command injection vulnerabilities.

Guidance

  • Identify and validate all user-supplied input that is passed to subprocess.run() to ensure it does not contain malicious commands.
  • Use shlex.split() to split the command into arguments instead of relying on the shell to split it, which can help prevent injection attacks.
  • Remove the except ImportError: pass block and instead ensure that the detect_dangerous_command module is properly imported and configured to handle safety checks.
  • Consider implementing additional security measures, such as whitelisting allowed commands or using a more secure alternative to subprocess.run().

Example

import shlex
# ...
r = subprocess.run(shlex.split(qc.get("command", "")), capture_output=True, text=True, timeout=30)

Notes

The provided code snippets are vulnerable to command injection attacks, and the suggested fixes aim to mitigate these risks. However, a comprehensive security audit and testing are recommended to ensure the fixes are effective and do not introduce new vulnerabilities.

Recommendation

Apply the suggested fixes, including replacing shell=True with shell=False and sanitizing user input, to prevent command injection attacks. This approach is more secure than relying on the detect_dangerous_command module alone, which may not catch all potential threats.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

hermes - 💡(How to fix) Fix Command injection via shell=True in tui_gateway/server.py [1 comments, 2 participants]