Skip to content

fix(security): sanitize workdir parameter in terminal tool backends#5629

Merged
teknium1 merged 1 commit into
mainfrom
hermes/hermes-7a93e2c7
Apr 6, 2026
Merged

fix(security): sanitize workdir parameter in terminal tool backends#5629
teknium1 merged 1 commit into
mainfrom
hermes/hermes-7a93e2c7

Conversation

@teknium1

@teknium1 teknium1 commented Apr 6, 2026

Copy link
Copy Markdown
Contributor

Summary

Fixes shell injection vulnerability where the workdir parameter is interpolated unquoted into cd {work_dir} && ... shell commands in docker, singularity, and SSH backends. A malicious AGENTS.md could poison workdir values to execute arbitrary commands (e.g. workdir: "~/;id").

Salvaged from PR #5620 by @entropidelic with the following improvements:

Fixes applied on top of #5620

  1. Tilde-aware quoting — The original PR used shlex.quote(work_dir) which wraps the entire path in single quotes, breaking tilde expansion (cd '~/project' → tilde does NOT expand). Fixed to keep ~ unquoted and quote only the subpath: cd ~/{shlex.quote(subpath)}.
  2. Allowlist instead of deny-list — The original _WORKDIR_BANNED_CHARS missed &, >, <, quotes, and other metacharacters. Replaced with a strict regex allowlist ([A-Za-z0-9/_\-.~ +@=,]) so novel metacharacters can't slip through.

Changes

  • tools/environments/docker.py — tilde-aware shlex.quote for ~/ workdir paths
  • tools/environments/singularity.py — same
  • tools/environments/ssh.py — tilde-aware quoting for all workdir paths in _execute_oneshot
  • tools/terminal_tool.py_validate_workdir() allowlist as defense-in-depth

Backends NOT affected

  • Local — passes workdir via cwd= parameter to subprocess.run(), not shell-interpolated
  • Modal/Daytona — no unquoted workdir interpolation
  • Persistent shell (SSH primary path) — already uses shlex.quote in persistent_shell.py

Test plan

  • E2E tested: 11 safe paths pass, 16 attack vectors blocked (including &, quotes, backticks, etc.)
  • Verified tilde expansion works with quoting in bash
  • All existing terminal tests pass (48/48)

Closes #5620

Shell injection via unquoted workdir interpolation in docker, singularity,
and SSH backends.  When workdir contained shell metacharacters (e.g.
~/;id), arbitrary commands could execute.

Changes:
- Add shlex.quote() at each interpolation point in docker.py,
  singularity.py, and ssh.py with tilde-aware quoting (keep ~
  unquoted for shell expansion, quote only the subpath)
- Add _validate_workdir() allowlist in terminal_tool.py as
  defense-in-depth before workdir reaches any backend

Original work by Mariano A. Nicolini (PR #5620).  Salvaged with fixes
for tilde expansion (shlex.quote breaks cd ~/path) and replaced
incomplete deny-list with strict character allowlist.

Co-authored-by: Mariano A. Nicolini <entropidelic@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants