fix(security): guard cron script against path traversal and redact output
Relative script paths resolved against HERMES_HOME/scripts/ were not validated to stay within that directory. Paths like '../../etc/passwd' could escape and be executed as Python. Fix: resolve the path and verify it stays within scripts_dir using Path.relative_to(). Also apply redact_sensitive_text() to script stdout before LLM injection — same pattern as execute_code sandbox output. Cherry-picked from PR #5093 by memosr (fixes 1 and 3; absolute path restriction dropped as too restrictive for the feature's design intent).
This commit is contained in:
@@ -248,7 +248,13 @@ def _run_job_script(script_path: str) -> tuple[bool, str]:
|
|||||||
path = Path(script_path).expanduser()
|
path = Path(script_path).expanduser()
|
||||||
if not path.is_absolute():
|
if not path.is_absolute():
|
||||||
# Resolve relative paths against HERMES_HOME/scripts/
|
# Resolve relative paths against HERMES_HOME/scripts/
|
||||||
path = get_hermes_home() / "scripts" / path
|
scripts_dir = get_hermes_home() / "scripts"
|
||||||
|
path = (scripts_dir / path).resolve()
|
||||||
|
# Guard against path traversal (e.g. "../../etc/passwd")
|
||||||
|
try:
|
||||||
|
path.relative_to(scripts_dir.resolve())
|
||||||
|
except ValueError:
|
||||||
|
return False, f"Script path escapes the scripts directory: {script_path!r}"
|
||||||
|
|
||||||
if not path.exists():
|
if not path.exists():
|
||||||
return False, f"Script not found: {path}"
|
return False, f"Script not found: {path}"
|
||||||
@@ -274,6 +280,13 @@ def _run_job_script(script_path: str) -> tuple[bool, str]:
|
|||||||
parts.append(f"stdout:\n{stdout}")
|
parts.append(f"stdout:\n{stdout}")
|
||||||
return False, "\n".join(parts)
|
return False, "\n".join(parts)
|
||||||
|
|
||||||
|
# Redact any secrets that may appear in script output before
|
||||||
|
# they are injected into the LLM prompt context.
|
||||||
|
try:
|
||||||
|
from agent.redact import redact_sensitive_text
|
||||||
|
stdout = redact_sensitive_text(stdout)
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
return True, stdout
|
return True, stdout
|
||||||
|
|
||||||
except subprocess.TimeoutExpired:
|
except subprocess.TimeoutExpired:
|
||||||
|
|||||||
Reference in New Issue
Block a user