Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 15 additions & 3 deletions tui_gateway/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import logging
import os
import queue
import shlex
import subprocess
import sys
import threading
Expand Down Expand Up @@ -4954,9 +4955,20 @@ def _(rid, params: dict) -> dict:
if name in qcmds:
qc = qcmds[name]
if qc.get("type") == "exec":
cmd = qc.get("command", "")
try:
from tools.approval import detect_dangerous_command

is_dangerous, _, desc = detect_dangerous_command(cmd)
if is_dangerous:
return _err(
rid, 4005, f"blocked: {desc}. Use the agent for dangerous commands."
)
except ImportError:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This changes the documented quick-command contract from operator-authored shell snippets to a single argv invocation. For example, the current configuration guide uses cd ... && git pull && pip install -e .; shlex.split() would pass && literally and break it. The RPC arg is not interpolated into qc["command"], so it is not the claimed injection channel.

pass
r = subprocess.run(
qc.get("command", ""),
shell=True,
shlex.split(cmd),
shell=False,
capture_output=True,
text=True,
timeout=30,
Expand Down Expand Up @@ -6981,7 +6993,7 @@ def _(rid, params: dict) -> dict:
pass
try:
r = subprocess.run(
cmd, shell=True, capture_output=True, text=True, timeout=30, cwd=os.getcwd()
shlex.split(cmd), shell=False, capture_output=True, text=True, timeout=30, cwd=os.getcwd()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This portion is stale against current main: shell.exec now applies both detect_hardline_command and detect_dangerous_command, fails closed if approval support is unavailable, and uses stdin=subprocess.DEVNULL before its shell execution path.

)
return _ok(
rid,
Expand Down