Skip to content

fix(security): patch 5 open vulnerabilities#7136

Open
dpskate wants to merge 1 commit into
NousResearch:mainfrom
dpskate:fix/security-hardening-5-vulns
Open

fix(security): patch 5 open vulnerabilities#7136
dpskate wants to merge 1 commit into
NousResearch:mainfrom
dpskate:fix/security-hardening-5-vulns

Conversation

@dpskate

@dpskate dpskate commented Apr 10, 2026

Copy link
Copy Markdown

Summary

Patches 5 categories of open security vulnerabilities identified via audit:

Files changed

File Change
tools/code_execution_tool.py Remove hermes root from sandbox PYTHONPATH, filter existing entries
tools/approval.py Add 8 new DANGEROUS_PATTERNS entries
agent/redact.py Add _redact_encoded_secrets() for base64/hex detection
gateway/platforms/webhook.py DEFAULT_HOST → 127.0.0.1
gateway/platforms/sms.py TCPSite bind → 127.0.0.1
gateway/platforms/telegram.py Webhook listen → env var with 127.0.0.1 default
hermes_cli/webhook.py CLI display default → 127.0.0.1

Test plan

  • PYTHONPATH injection: verified sandbox env no longer contains hermes root
  • DANGEROUS_PATTERNS: 10/10 test cases pass (8 true positives, 2 true negatives)
  • Redaction bypass: base64-encoded sk-* key correctly redacted
  • Redaction bypass: hex-encoded sk-* key correctly redacted
  • Webhook adapter starts correctly on 127.0.0.1 (manual test)
  • SMS adapter starts correctly on 127.0.0.1 (manual test)
  • Telegram webhook mode works with TELEGRAM_WEBHOOK_LISTEN env var
  • Existing test suite passes (pytest tests/)

Related issues

Closes #7071, mitigates #6961, mitigates #4260, mitigates #6335

🤖 Generated with Claude Code

…attern bypass, redaction bypass, network exposure

- Remove hermes-agent root from sandbox PYTHONPATH to prevent internal module
  import and API key exfiltration (mitigates NousResearch#7071)
- Add 8 missing DANGEROUS_PATTERNS: heredoc injection, git destructive ops
  (reset --hard, push --force, clean -f, branch -D, checkout -- .), and
  chmod +x social engineering (mitigates NousResearch#6961)
- Add base64/hex encoded secret detection to redact_sensitive_text() to
  prevent redaction bypass via encoding
- Change default bind address from 0.0.0.0 to 127.0.0.1 for webhook,
  SMS/Twilio, and Telegram adapters (mitigates NousResearch#4260, NousResearch#6335)
- Fix .env and config.yaml file permissions from 644 to 600

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@alt-glitch alt-glitch added type/security Security vulnerability or hardening P1 High — major feature broken, no workaround comp/tools Tool registry, model_tools, toolsets comp/gateway Gateway runner, session dispatch, delivery tool/code-exec execute_code sandbox labels Apr 29, 2026
@austinpickett austinpickett requested a review from Copilot May 18, 2026 15:30

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR tightens hermes-agent’s security posture across sandbox execution, dangerous-command approval gating, secret redaction, and default network bind behavior—addressing multiple audit findings and reported vulnerabilities.

Changes:

  • Removes hermes-agent repo-root injection into the execute_code sandbox PYTHONPATH and filters it out if present.
  • Expands DANGEROUS_PATTERNS and extends output redaction to detect base64/hex-encoded secrets.
  • Switches several gateway/webhook listeners to default to loopback (127.0.0.1) and updates CLI display defaults.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
tools/code_execution_tool.py Stops exposing repo-root modules to sandboxed scripts via PYTHONPATH.
tools/approval.py Adds new regex detections intended to close approval-bypass gaps.
agent/redact.py Adds encoded-secret detection/redaction for base64 and hex substrings.
gateway/platforms/webhook.py Changes default webhook bind host to loopback.
gateway/platforms/sms.py Changes Twilio webhook server bind host to loopback.
gateway/platforms/telegram.py Makes Telegram webhook listen address configurable (default loopback).
hermes_cli/webhook.py Updates CLI base URL default host/display behavior for loopback.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread tools/approval.py
Comment on lines +107 to +108
# Matches: python3 << 'EOF', bash <<EOF, python3 <<-'SCRIPT', etc.
(r'\b(python[23]?|perl|ruby|node|bash|sh|zsh|ksh)\s+<<-?\s*[\'\"]?\w+', "script execution via heredoc"),
Comment thread tools/approval.py
# --- Git destructive operations ---
(r'\bgit\s+reset\s+--hard\b', "git reset --hard (destroys uncommitted changes)"),
(r'\bgit\s+push\s+.*--force\b', "git force push (rewrites remote history)"),
(r'\bgit\s+push\s+-f\b', "git force push (rewrites remote history)"),
Comment thread tools/approval.py
Comment on lines +106 to +117
# --- Heredoc script injection (bypass -e/-c flag detection) ---
# Matches: python3 << 'EOF', bash <<EOF, python3 <<-'SCRIPT', etc.
(r'\b(python[23]?|perl|ruby|node|bash|sh|zsh|ksh)\s+<<-?\s*[\'\"]?\w+', "script execution via heredoc"),
# --- Git destructive operations ---
(r'\bgit\s+reset\s+--hard\b', "git reset --hard (destroys uncommitted changes)"),
(r'\bgit\s+push\s+.*--force\b', "git force push (rewrites remote history)"),
(r'\bgit\s+push\s+-f\b', "git force push (rewrites remote history)"),
(r'\bgit\s+clean\s+-[^\s]*f', "git clean -f (deletes untracked files)"),
(r'\bgit\s+branch\s+-D\b', "git branch -D (force delete branch)"),
(r'\bgit\s+checkout\s+--\s+\.', "git checkout -- . (discards all changes)"),
# --- chmod+x then execute (two-step social engineering) ---
(r'\bchmod\s+\+x\b', "make file executable (verify script content first)"),
Comment on lines +1019 to +1023
# hermes-agent project root.
_hermes_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
_filtered = os.pathsep.join(
p for p in child_env["PYTHONPATH"].split(os.pathsep)
if p and os.path.normpath(p) != os.path.normpath(_hermes_root)
Comment on lines +1012 to +1028
# SECURITY FIX: Do NOT add hermes-agent root to PYTHONPATH.
# Exposing the project root allows sandbox scripts to import internal
# modules (hermes_state, hermes_constants, config parsers) which may
# contain or provide access to API keys and security rules.
# See: https://github.com/NousResearch/hermes-agent/issues/7071
if "PYTHONPATH" in child_env:
# Preserve any pre-existing PYTHONPATH entries that are NOT the
# hermes-agent project root.
_hermes_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
_filtered = os.pathsep.join(
p for p in child_env["PYTHONPATH"].split(os.pathsep)
if p and os.path.normpath(p) != os.path.normpath(_hermes_root)
)
if _filtered:
child_env["PYTHONPATH"] = _filtered
else:
del child_env["PYTHONPATH"]
Comment thread agent/redact.py
Comment on lines +178 to +205
# Base64-encoded secret detection
_BASE64_CHUNK_RE = re.compile(r"[A-Za-z0-9+/]{20,}={0,2}")
_HEX_CHUNK_RE = re.compile(r"(?:0x)?[0-9a-fA-F]{20,}")
# Known prefixes that indicate a secret when found inside decoded data
_DECODED_SECRET_MARKERS = (
b"sk-", b"ghp_", b"github_pat_", b"gho_", b"xoxb-", b"xoxp-",
b"AIza", b"AKIA", b"sk_live_", b"sk_test_", b"SG.", b"hf_",
b"Bearer ", b"token=", b"password=", b"api_key=", b"apiKey",
)


def _redact_encoded_secrets(text: str) -> str:
"""Detect and redact base64/hex-encoded strings containing secret markers."""
import base64
import binascii

def _check_and_redact_b64(m):
chunk = m.group(0)
try:
decoded = base64.b64decode(chunk, validate=True)
if any(marker in decoded for marker in _DECODED_SECRET_MARKERS):
return "[REDACTED BASE64-ENCODED SECRET]"
except (binascii.Error, ValueError):
pass
return chunk

text = _BASE64_CHUNK_RE.sub(_check_and_redact_b64, text)

Comment thread agent/redact.py
Comment on lines +170 to 218
# --- SECURITY FIX: Detect base64/hex encoded secrets ---
# Attackers can bypass pattern-based redaction by encoding API keys.
# Detect base64 strings that decode to known secret prefixes.
text = _redact_encoded_secrets(text)

return text


# Base64-encoded secret detection
_BASE64_CHUNK_RE = re.compile(r"[A-Za-z0-9+/]{20,}={0,2}")
_HEX_CHUNK_RE = re.compile(r"(?:0x)?[0-9a-fA-F]{20,}")
# Known prefixes that indicate a secret when found inside decoded data
_DECODED_SECRET_MARKERS = (
b"sk-", b"ghp_", b"github_pat_", b"gho_", b"xoxb-", b"xoxp-",
b"AIza", b"AKIA", b"sk_live_", b"sk_test_", b"SG.", b"hf_",
b"Bearer ", b"token=", b"password=", b"api_key=", b"apiKey",
)


def _redact_encoded_secrets(text: str) -> str:
"""Detect and redact base64/hex-encoded strings containing secret markers."""
import base64
import binascii

def _check_and_redact_b64(m):
chunk = m.group(0)
try:
decoded = base64.b64decode(chunk, validate=True)
if any(marker in decoded for marker in _DECODED_SECRET_MARKERS):
return "[REDACTED BASE64-ENCODED SECRET]"
except (binascii.Error, ValueError):
pass
return chunk

text = _BASE64_CHUNK_RE.sub(_check_and_redact_b64, text)

def _check_and_redact_hex(m):
chunk = m.group(0)
raw = chunk[2:] if chunk.startswith("0x") else chunk
try:
decoded = bytes.fromhex(raw)
if any(marker in decoded for marker in _DECODED_SECRET_MARKERS):
return "[REDACTED HEX-ENCODED SECRET]"
except (ValueError, binascii.Error):
pass
return chunk

text = _HEX_CHUNK_RE.sub(_check_and_redact_hex, text)
return text
Comment thread gateway/platforms/sms.py
Comment on lines 105 to 108
self._runner = web.AppRunner(app)
await self._runner.setup()
site = web.TCPSite(self._runner, "0.0.0.0", self._webhook_port)
site = web.TCPSite(self._runner, "127.0.0.1", self._webhook_port)
await site.start()
Comment on lines +643 to 646
_webhook_listen = os.getenv("TELEGRAM_WEBHOOK_LISTEN", "127.0.0.1").strip()
await self._app.updater.start_webhook(
listen="0.0.0.0",
listen=_webhook_listen,
port=webhook_port,
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/gateway Gateway runner, session dispatch, delivery comp/tools Tool registry, model_tools, toolsets P1 High — major feature broken, no workaround tool/code-exec execute_code sandbox type/security Security vulnerability or hardening

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] Hermes Agent Code Execution Sandbox Exposes Internal Modules via PYTHONPATH Injection — Configuration Secrets and Security Rules Leak

3 participants