Skip to content

fix(security): prevent shell injection in sudo password piping - #65

Merged
teknium1 merged 1 commit into
NousResearch:mainfrom
leonsgithub:fix/sudo-password-shell-injection
Feb 27, 2026
Merged

fix(security): prevent shell injection in sudo password piping#65
teknium1 merged 1 commit into
NousResearch:mainfrom
leonsgithub:fix/sudo-password-shell-injection

Conversation

@leonsgithub

Copy link
Copy Markdown

Problem

The sudo password in _transform_sudo_command() was embedded in a shell command using single-quote interpolation:

return f"echo '{sudo_password}' | sudo -S -p ''"

If the password contained shell metacharacters (single quotes, $(), backticks), they would escape the quoting and be interpreted by the shell — enabling arbitrary command execution.

Example — a password like test'; rm -rf / # produces:

echo 'test'; rm -rf / #' | sudo -S -p ''
       ^^^^^^^^^^^ executed as a separate command

Fix

Use shlex.quote() which properly handles all shell-special characters:

import shlex
return f"echo {shlex.quote(sudo_password)} | sudo -S -p ''"

The same attack payload now produces:

echo 'test'"'"'; rm -rf / #' | sudo -S -p ''
      ^^^^^^^^^^^^^^^^^^^^^^^^ entire string treated as echo argument

Scope

Single file, 3-line change in tools/terminal_tool.py. No behavior change for normal passwords — shlex.quote() is a no-op for simple alphanumeric strings.

The sudo password was embedded in shell commands via single-quote
interpolation: echo '{password}' | sudo -S

If the password contained shell metacharacters (single quotes,
$(), backticks), they would be interpreted by the shell, enabling
arbitrary command execution.

Fix: use shlex.quote() which properly escapes all shell-special
characters, ensuring the password is always treated as a literal
string argument to echo.
@teknium1
teknium1 merged commit 547ba73 into NousResearch:main Feb 27, 2026
angelburgosrosado pushed a commit to angelburgosrosado/hermes-agent that referenced this pull request Apr 27, 2026
…-shell-injection

fix(security): prevent shell injection in sudo password piping
alnimra added a commit to alnimra/hermes-agent that referenced this pull request May 3, 2026
jarvis-stark-ops added a commit to 1Team-Engineering/hermes-agent that referenced this pull request Jun 10, 2026
…arch#34, NousResearch#65)

- NousResearch#33 GH_TOKEN propagation: _inject_gh_token_into_env runs `gh auth
  token` before each worker subprocess.Popen and injects into env if
  the worker doesn't have GH_TOKEN/GITHUB_TOKEN.
- NousResearch#34 respawn_guarded active_pr exempts review roles (tony/tchalla/
  vision/reviewer). Bounded: exemption only applies while
  consecutive_failures < max_retries; once exhausted the guard fires.
- NousResearch#65 fabricated github-auth block claims rejected:
  FabricatedAuthClaimError raised when kanban_block reason matches
  auth-claim pattern AND dispatcher's `gh auth status` succeeds.
  Strict leading-position regex with cause:/blocker:/reason:/infra:
  prefix exemption.

Context: hermes-jarvis#61. 33 tests pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
ohungerCH added a commit to ohungerCH/hermes-agent that referenced this pull request Jun 28, 2026
…ploy-durabel (setgid-Gruppendir)

Die Bridge (UID 10024) SCHREIBT cron/enqueue/<job>.json; die Engine (UID 10000) liest/claimt.
Der unbedingte `chown -R hermes:hermes cron`-Block setzt cron/enqueue bei JEDEM Boot auf
10000-only zurueck -> die Bridge EACCESt (RESEARCH_ENQUEUE_WRITE_FAILED). Das Image hat kein
`acl`-Paket -> Standard-POSIX statt ACL:

stage2-hook.sh: NACH dem `chown -R cron`-Block (sonst clobbert er) eine dedizierte shared-GID
(JARVIS_RESEARCH_GID, Default 10240) + setgid-Verzeichnis cron/enqueue mit Mode 2770 (rwx Owner,
rwx Gruppe, setgid -> neue Dateien erben die Gruppe, KEIN other-Bit = nicht world-writable).
hermes wird Mitglied der Gruppe; die Bridge erhaelt die GID per group_add (compose.bridge.yaml,
im Haupt-Repo). Loest zugleich den Subpath-Mount-CAVEAT (cron/enqueue muss existieren).

Test (tests/tools/test_stage2_hook_research_enqueue.py): Block vorhanden + NACH `chown -R cron`,
chmod 2770 (kein world-writable), idempotent, legt cron/enqueue an. bash -n gruen; das
Block-Verhalten ist via gestubbtem Harness validiert (python-build/pytest im Engine-Container
ist der gated Recreate-Verify-Schritt, hier nicht ausgefuehrt).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
ohungerCH added a commit to ohungerCH/hermes-agent that referenced this pull request Jun 28, 2026
…chaft zur Build-Zeit anlegen

Rootfs ist zur Laufzeit read-only -> groupadd/usermod im stage2-Hook scheitern
(/etc/group nicht schreibbar). Gruppe + Mitgliedschaft gehoeren in den Dockerfile
(Build-Zeit). stage2 macht dann nur noch chgrp 10240 + chmod 2770 aufs Volume-Dir
-> setgid greift, hermes ist Mitglied, Enqueue-Handoff fresh-volume-durabel.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
waefrebeorn pushed a commit to waefrebeorn/slermes that referenced this pull request Jul 2, 2026
…-shell-injection

fix(security): prevent shell injection in sudo password piping
Meraniya pushed a commit to Meraniya/hermes-agent that referenced this pull request Aug 6, 2026
…NousResearch#65)

- Add deploy_skill_scripts() to tools/skills_sync.py — copies .py files
  from skill scripts/ subdirectories to ~/.hermes/scripts/ when content
  has changed
- Call deploy_skill_scripts() at end of sync_skills() so it runs on
  every Hermes startup
- Move ugw-health-check.py into scripts/ subdirectory to match the
  convention used by other skills
- Fixes UGW Health Monitor cron job: on next startup, the correct script
  (which reads gateway_state not report) overwrites the stale broken copy


Claude-Session: https://claude.ai/code/session_01MnmdLAbTdbTo66Uc2tK31x

Co-authored-by: Claude <noreply@anthropic.com>
Soju06 added a commit to Soju06/hermes-agent that referenced this pull request Aug 19, 2026
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.

3 participants