Merge pull request #1 from hobostay/fix/security-hardening-tool-exec

Security & robustness: command injection, path traversal, approval bypass in tool/market layer
This commit is contained in:
LZH-YS1998
2026-07-04 18:34:49 +08:00
14 changed files with 207 additions and 14 deletions
+15 -2
View File
@@ -3131,6 +3131,11 @@ class WSHandler:
data = json.loads(raw)
except json.JSONDecodeError:
return
# ``json.loads`` succeeds for non-object frames (null/number/array/string);
# ``data.get`` would then raise AttributeError, escape this method, and drop the
# whole WS connection. Ignore anything that is not a JSON object.
if not isinstance(data, dict):
return
msg_type = data.get("type", "")
if self._shutting_down:
@@ -3667,8 +3672,16 @@ class WSHandler:
"""Write a custom prompt file and return its relative path as a prompt_ref."""
prompts_dir = Path(self.engine.opc_home) / "prompts" / "custom"
prompts_dir.mkdir(parents=True, exist_ok=True)
filename = f"{employee_id}.md"
filepath = prompts_dir / filename
# ``employee_id`` is derived from user-supplied role id/name and previously flowed
# unchecked into the path, enabling traversal (e.g. "../../tmp/pwn"). Reduce it to
# a single safe path component and confirm containment before writing.
safe_id = Path(str(employee_id or "")).name.replace("..", "")
safe_id = safe_id.replace("/", "").replace("\\", "").strip() or "agent"
filename = f"{safe_id}.md"
filepath = (prompts_dir / filename).resolve()
base = prompts_dir.resolve()
if base not in filepath.parents and filepath != base:
raise ValueError(f"Custom prompt filename escapes prompts directory: {employee_id!r}")
filepath.write_text(f"# {name}\n\n{prompt_text}\n", encoding="utf-8")
return f"prompts/custom/{filename}"