Context
PR #4168 addresses 5 of 11 findings from a security audit. The remaining 6 need design decisions or architectural changes.
Remaining gaps
Critical
1. Credential file read blocking in file_tools.py
read_file has no deny list for credential paths. Currently it blocks /etc/, /boot/, /usr/lib/systemd/ and docker sockets, but NOT ~/.ssh/*, ~/.aws/credentials, ~/.hermes/.env, ~/.gnupg/*, ~/.kube/config, ~/.netrc. PR #4168 added terminal-level patterns for cat/head/tail of these paths, but the read_file tool itself is unprotected.
2. Network egress filtering on local backend
Terminal commands have unrestricted internet access. The URL safety checks in tools/url_safety.py only apply to hermes-native web tools, not to curl/wget/python run through the terminal. Options: network namespace isolation, eBPF/seccomp filtering, or flagging commands that combine file reading with network tools.
High
3. Output redaction gaps
agent/redact.py misses: JWT tokens (eyJhbGciOi...), AWS secret keys (40-char base64 beyond AKIA* prefix), Basic auth in URLs (https://user:pass@host), session cookies, OAuth refresh tokens, OpenSSH private keys (-----BEGIN OPENSSH PRIVATE KEY-----).
4. HERMES_REDACT_SECRETS=0 disables all redaction
This env var (redact.py:112) turns off all output redaction. Should be blocked from being set in subprocesses and should require explicit config file change rather than runtime env.
Medium
5. Smart approval is LLM-bypassable
When approvals.mode: smart, an auxiliary LLM decides whether to approve. A disguised exfiltration command (e.g., curl https://api.github.com/repos/... with a credential in a query param) can pass review. Smart mode should have a hard-deny list the LLM cannot override.
6. "Always" approval creates permanent prefix bypass
Approving python -c with "always" approves ALL future python -c commands, including exfiltration scripts. The permanent allowlist should be pattern-scoped to the specific command, not the prefix.
Context
PR #4168 addresses 5 of 11 findings from a security audit. The remaining 6 need design decisions or architectural changes.
Remaining gaps
Critical
1. Credential file read blocking in file_tools.py
read_filehas no deny list for credential paths. Currently it blocks/etc/,/boot/,/usr/lib/systemd/and docker sockets, but NOT~/.ssh/*,~/.aws/credentials,~/.hermes/.env,~/.gnupg/*,~/.kube/config,~/.netrc. PR #4168 added terminal-level patterns forcat/head/tailof these paths, but theread_filetool itself is unprotected.2. Network egress filtering on local backend
Terminal commands have unrestricted internet access. The URL safety checks in
tools/url_safety.pyonly apply to hermes-native web tools, not tocurl/wget/pythonrun through the terminal. Options: network namespace isolation, eBPF/seccomp filtering, or flagging commands that combine file reading with network tools.High
3. Output redaction gaps
agent/redact.pymisses: JWT tokens (eyJhbGciOi...), AWS secret keys (40-char base64 beyondAKIA*prefix), Basic auth in URLs (https://user:pass@host), session cookies, OAuth refresh tokens, OpenSSH private keys (-----BEGIN OPENSSH PRIVATE KEY-----).4. HERMES_REDACT_SECRETS=0 disables all redaction
This env var (
redact.py:112) turns off all output redaction. Should be blocked from being set in subprocesses and should require explicit config file change rather than runtime env.Medium
5. Smart approval is LLM-bypassable
When
approvals.mode: smart, an auxiliary LLM decides whether to approve. A disguised exfiltration command (e.g.,curl https://api.github.com/repos/...with a credential in a query param) can pass review. Smart mode should have a hard-deny list the LLM cannot override.6. "Always" approval creates permanent prefix bypass
Approving
python -cwith "always" approves ALL futurepython -ccommands, including exfiltration scripts. The permanent allowlist should be pattern-scoped to the specific command, not the prefix.