Update Modules/Shell_Command.py
Browse files- Modules/Shell_Command.py +54 -0
Modules/Shell_Command.py
CHANGED
|
@@ -96,6 +96,60 @@ def Shell_Command(
|
|
| 96 |
_log_call_end("Shell_Command", _truncate_for_log(result))
|
| 97 |
return result
|
| 98 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 99 |
# Capture shell used for transparency
|
| 100 |
_, shell_name = _detect_shell()
|
| 101 |
stdout, stderr, code = _run_command(command, cwd=abs_cwd, timeout=timeout)
|
|
|
|
| 96 |
_log_call_end("Shell_Command", _truncate_for_log(result))
|
| 97 |
return result
|
| 98 |
|
| 99 |
+
# Heuristic check for absolute paths in arguments if sandboxing is strictly enforced
|
| 100 |
+
# We look for typical absolute path patterns: "/..." or "C:\..."
|
| 101 |
+
# This is not perfect (e.g., inside strings) but helps enforce "Impossible" rule.
|
| 102 |
+
from .File_System import ALLOW_ABS
|
| 103 |
+
import re
|
| 104 |
+
if not ALLOW_ABS:
|
| 105 |
+
# Regex for Unix-style absolute path (start with /)
|
| 106 |
+
# or Windows-style absolute path (start with drive letter)
|
| 107 |
+
# We look for these patterns preceded by space or start of string
|
| 108 |
+
# to avoid matching arguments like --flag=/value (though those might be paths too!)
|
| 109 |
+
# Actually, matching ANY absolute path substring is safer for "Impossible".
|
| 110 |
+
# Patterns:
|
| 111 |
+
# Unix: / followed by non-space
|
| 112 |
+
# Win: X:\ followed by non-space
|
| 113 |
+
|
| 114 |
+
# Simple heuristic: if command contains potential absolute path
|
| 115 |
+
unix_abs = r"(?:\s|^)/[a-zA-Z0-9_.]"
|
| 116 |
+
win_abs = r"(?:\s|^)[a-zA-Z]:\\"
|
| 117 |
+
|
| 118 |
+
if re.search(unix_abs, command) or re.search(win_abs, command):
|
| 119 |
+
# We allow a few exceptions if needed, but for "Impossible" we block.
|
| 120 |
+
# Note: This might block flags like /C, but we run powershell/cmd separately.
|
| 121 |
+
# Wait, Windows flags start with /. 'dir /s'. This heuristic is dangerous for Windows flags.
|
| 122 |
+
# We should refine it.
|
| 123 |
+
pass
|
| 124 |
+
|
| 125 |
+
# Refined check:
|
| 126 |
+
# On Windows, flags start with /, so checking for / is bad.
|
| 127 |
+
# But paths in Windows usually use \ or /.
|
| 128 |
+
# Let's focus on Unix roots and Windows Drive roots.
|
| 129 |
+
|
| 130 |
+
has_abs_path = False
|
| 131 |
+
if platform.system().lower() == "windows":
|
| 132 |
+
# Look for Drive:\ - anchored to start of string, space, or quote to avoid matching URLs like https://
|
| 133 |
+
if re.search(r"(?:\s|^|['\"])[a-zA-Z]:[\\/]", command):
|
| 134 |
+
has_abs_path = True
|
| 135 |
+
# On Windows with PowerShell, /path is valid too, but confusing with flags.
|
| 136 |
+
# We'll trust that Drive:\ is the main vector to save OUTSIDE tool root (which is likely C: or P:).
|
| 137 |
+
# If tool root is P:/Code..., writing to C:/... requires Drive arg.
|
| 138 |
+
else:
|
| 139 |
+
# Unix: Look for / at start of token, but exclude common flags?
|
| 140 |
+
# Actually, just looking for " /" or start "/" is decent.
|
| 141 |
+
# But flags like /dev/null are common.
|
| 142 |
+
# Maybe we just warn or block known dangerous patterns?
|
| 143 |
+
# User said "Make it impossible". a broad block is better than a leak.
|
| 144 |
+
if re.search(r"(?:\s|^)/", command):
|
| 145 |
+
# This blocks flags like /bin/bash or paths.
|
| 146 |
+
has_abs_path = True
|
| 147 |
+
|
| 148 |
+
if has_abs_path:
|
| 149 |
+
result = "Error: Absolute paths are not allowed in commands to ensure sandbox safety. Use relative paths."
|
| 150 |
+
_log_call_end("Shell_Command", _truncate_for_log(result))
|
| 151 |
+
return result
|
| 152 |
+
|
| 153 |
# Capture shell used for transparency
|
| 154 |
_, shell_name = _detect_shell()
|
| 155 |
stdout, stderr, code = _run_command(command, cwd=abs_cwd, timeout=timeout)
|