harden(env_passthrough): apply GHSA-rhgp-j443-p4rf filter to config.yaml path (#27794)

register_env_passthrough() (the skill-declared path) filters out names in
_HERMES_PROVIDER_ENV_BLOCKLIST and logs a warning citing GHSA-rhgp-j443-p4rf.
_load_config_passthrough() (the config.yaml path) did not. Both feed the
same is_env_passthrough() allowlist that local.py and code_execution_tool.py
consult before stripping a variable from the child env.

A skill that wanted to leak ANTHROPIC_API_KEY or OPENAI_API_KEY into
execute_code could no longer self-register the name (the GHSA fix
blocks it), but the same outcome was still reachable by asking the
operator to add the name to terminal.env_passthrough in config.yaml,
or by any in-process actor with write access to ~/.hermes/config.yaml.

Apply the same _is_hermes_provider_credential filter inside
_load_config_passthrough, mirroring the skill-path warning so operators
see the same explanation. Non-Hermes API keys (TENOR_API_KEY,
NOTION_TOKEN, etc.) are unaffected since they are not in the blocklist.
This commit is contained in:
Dennis Vorobyov 2026-05-25 11:35:23 +01:00 committed by GitHub
parent 0219b0408a
commit 3ab7e2aa91
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -113,8 +113,26 @@ def _load_config_passthrough() -> frozenset[str]:
passthrough = cfg_get(cfg, "terminal", "env_passthrough")
if isinstance(passthrough, list):
for item in passthrough:
if isinstance(item, str) and item.strip():
result.add(item.strip())
if not isinstance(item, str) or not item.strip():
continue
name = item.strip()
# Mirror the skill-path filter in register_env_passthrough:
# Hermes-managed provider credentials must not be passed
# through to execute_code / terminal children, regardless of
# whether the request came from a skill or from config.yaml.
# See GHSA-rhgp-j443-p4rf.
if _is_hermes_provider_credential(name):
logger.warning(
"env passthrough: refusing to register Hermes "
"provider credential %r from config.yaml (blocked "
"by _HERMES_PROVIDER_ENV_BLOCKLIST). Operator "
"configuration must not override the execute_code "
"sandbox's credential scrubbing; see "
"GHSA-rhgp-j443-p4rf.",
name,
)
continue
result.add(name)
except Exception as e:
logger.debug("Could not read tools.env_passthrough from config: %s", e)