You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Hermes strips sensitive env vars (API keys, tokens) from tool subprocess environments via _sanitize_subprocess_env() and _SECRET_SUBSTRINGS filtering. A subprocess can recover every stripped variable by reading /proc/<parent_pid>/environ, which is readable by any same-UID process on Linux.
Reproduction
Using Hermes's own _sanitize_subprocess_env() from tools/environments/local.py:
=== Hermes strips SLACK tokens from subprocess env ===
Parent SLACK_BOT_TOKEN: xoxb-FAKE-SECRET-12345
Sanitized has SLACK_BOT_TOKEN: False
Sanitized has SLACK_APP_TOKEN: False
=== Child with sanitized env recovers tokens via /proc ===
env SLACK_BOT_TOKEN: STRIPPED
/proc/1/environ SLACK_BOT_TOKEN: xoxb-FAKE-SECRET-12345
/proc/1/environ SLACK_APP_TOKEN: xapp-FAKE-APP-SECRET-99999
PoC (two files, run in the official Hermes Docker image):
Any code the agent executes via terminal or execute_code can recover all stripped secrets
This includes LLM-generated code, skill scripts, and third-party tools
The security docs list "Code execution sandbox: execute_code child process runs with API keys stripped from environment" as a protection — this protection does not hold
Tested mitigation
PID namespaces (unshare --user --pid --fork --mount-proc) prevent this. Inside the namespace, the child's /proc is remounted — the parent's PID doesn't exist, and brute-scanning all /proc/*/environ finds nothing. Tested in the official Hermes Docker image.
Summary
Hermes strips sensitive env vars (API keys, tokens) from tool subprocess environments via
_sanitize_subprocess_env()and_SECRET_SUBSTRINGSfiltering. A subprocess can recover every stripped variable by reading/proc/<parent_pid>/environ, which is readable by any same-UID process on Linux.Reproduction
Using Hermes's own
_sanitize_subprocess_env()fromtools/environments/local.py:PoC (two files, run in the official Hermes Docker image):
poc.py (parent):
poc_child.py (child — simulates what a tool subprocess can do):
Impact
terminalorexecute_codecan recover all stripped secretsexecute_codechild process runs with API keys stripped from environment" as a protection — this protection does not holdTested mitigation
PID namespaces (
unshare --user --pid --fork --mount-proc) prevent this. Inside the namespace, the child's/procis remounted — the parent's PID doesn't exist, and brute-scanning all/proc/*/environfinds nothing. Tested in the official Hermes Docker image.