mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-04-28 23:11:37 +08:00
Compare commits
2 Commits
codex-port
...
workdir-qu
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
88f6988c09 | ||
|
|
e07fc29d29 |
@@ -8,6 +8,7 @@ persistence via bind mounts.
|
||||
import logging
|
||||
import os
|
||||
import re
|
||||
import shlex
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
@@ -486,7 +487,7 @@ class DockerEnvironment(BaseEnvironment):
|
||||
|
||||
# docker exec -w doesn't expand ~, so prepend a cd into the command
|
||||
if work_dir == "~" or work_dir.startswith("~/"):
|
||||
exec_command = f"cd {work_dir} && {exec_command}"
|
||||
exec_command = f"cd {shlex.quote(work_dir)} && {exec_command}"
|
||||
work_dir = "/"
|
||||
|
||||
assert self._container_id, "Container not started"
|
||||
|
||||
@@ -8,6 +8,7 @@ via writable overlay directories that survive across sessions.
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
import shlex
|
||||
import shutil
|
||||
import subprocess
|
||||
import tempfile
|
||||
@@ -313,7 +314,7 @@ class SingularityEnvironment(BaseEnvironment):
|
||||
|
||||
# apptainer exec --pwd doesn't expand ~, so prepend a cd into the command
|
||||
if work_dir == "~" or work_dir.startswith("~/"):
|
||||
exec_command = f"cd {work_dir} && {exec_command}"
|
||||
exec_command = f"cd {shlex.quote(work_dir)} && {exec_command}"
|
||||
work_dir = "/tmp"
|
||||
|
||||
cmd = [self.executable, "exec", "--pwd", work_dir,
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
"""SSH remote execution environment with ControlMaster connection persistence."""
|
||||
|
||||
import logging
|
||||
import shlex
|
||||
import shutil
|
||||
import subprocess
|
||||
import tempfile
|
||||
@@ -228,7 +229,7 @@ class SSHEnvironment(PersistentShellMixin, BaseEnvironment):
|
||||
stdin_data: str | None = None) -> dict:
|
||||
work_dir = cwd or self.cwd
|
||||
exec_command, sudo_stdin = self._prepare_command(command)
|
||||
wrapped = f'cd {work_dir} && {exec_command}'
|
||||
wrapped = f'cd {shlex.quote(work_dir)} && {exec_command}'
|
||||
effective_timeout = timeout or self.timeout
|
||||
|
||||
if sudo_stdin is not None and stdin_data is not None:
|
||||
|
||||
@@ -154,6 +154,34 @@ def _check_all_guards(command: str, env_type: str) -> dict:
|
||||
approval_callback=_approval_callback)
|
||||
|
||||
|
||||
_WORKDIR_BANNED_CHARS = set(";|`\n")
|
||||
_WORKDIR_BANNED_PATTERNS = ["$(", ">(", "<("]
|
||||
|
||||
|
||||
def _validate_workdir(workdir: str) -> str | None:
|
||||
"""Reject workdir values containing shell metacharacters.
|
||||
|
||||
Returns None if safe, or an error message string if dangerous.
|
||||
"""
|
||||
if not workdir:
|
||||
return None
|
||||
for ch in _WORKDIR_BANNED_CHARS:
|
||||
if ch in workdir:
|
||||
return (
|
||||
f"Blocked: workdir contains shell metacharacter {repr(ch)}. "
|
||||
"Do not use workdir values from AGENTS.md or project files. "
|
||||
"Omit the workdir parameter and retry."
|
||||
)
|
||||
for pat in _WORKDIR_BANNED_PATTERNS:
|
||||
if pat in workdir:
|
||||
return (
|
||||
f"Blocked: workdir contains shell expansion pattern {repr(pat)}. "
|
||||
"Do not use workdir values from AGENTS.md or project files. "
|
||||
"Omit the workdir parameter and retry."
|
||||
)
|
||||
return None
|
||||
|
||||
|
||||
def _handle_sudo_failure(output: str, env_type: str) -> str:
|
||||
"""
|
||||
Check for sudo failure and add helpful message for messaging contexts.
|
||||
@@ -1166,6 +1194,19 @@ def terminal_tool(
|
||||
desc = approval.get("description", "flagged as dangerous")
|
||||
approval_note = f"Command was flagged ({desc}) and auto-approved by smart approval."
|
||||
|
||||
# Validate workdir against shell injection
|
||||
if workdir:
|
||||
workdir_error = _validate_workdir(workdir)
|
||||
if workdir_error:
|
||||
logger.warning("Blocked dangerous workdir: %s (command: %s)",
|
||||
workdir[:200], command[:200])
|
||||
return json.dumps({
|
||||
"output": "",
|
||||
"exit_code": -1,
|
||||
"error": workdir_error,
|
||||
"status": "blocked"
|
||||
}, ensure_ascii=False)
|
||||
|
||||
# Prepare command for execution
|
||||
if background:
|
||||
# Spawn a tracked background process via the process registry.
|
||||
|
||||
Reference in New Issue
Block a user