Skip to content

fix(security): expand subprocess env blocklist to include gateway and tool secrets #1264

@smkrv

Description

@smkrv

Summary

_build_provider_env_blocklist() in tools/environments/local.py (and its consumers in process_registry.py) only strips LLM provider keys from subprocess environments. All gateway and tool API secrets pass through unfiltered and are trivially readable via printenv, env, or cat /proc/self/environ in agent terminal sessions.

PRs #1157 and #1172 fixed the LLM provider side — this is the remaining gap.

Affected variables (non-exhaustive)

Category Variables
Telegram TELEGRAM_BOT_TOKEN, TELEGRAM_ALLOWED_USERS, TELEGRAM_HOME_CHANNEL
Discord DISCORD_BOT_TOKEN, DISCORD_ALLOWED_USERS
Slack SLACK_BOT_TOKEN, SLACK_APP_TOKEN, SLACK_ALLOWED_USERS
Signal SIGNAL_ACCOUNT, SIGNAL_ALLOWED_USERS
WhatsApp WHATSAPP_ALLOWED_USERS
Email EMAIL_PASSWORD, EMAIL_ALLOWED_USERS
Voice/TTS VOICE_TOOLS_OPENAI_KEY
Browser BROWSERBASE_API_KEY, BROWSERBASE_PROJECT_ID
Web tools FIRECRAWL_API_KEY
Image gen FAL_KEY
Integrations HONCHO_API_KEY, GITHUB_TOKEN, WANDB_API_KEY, TINKER_API_KEY, HASS_TOKEN
System SUDO_PASSWORD
Gateway GATEWAY_ALLOW_ALL_USERS

Attack scenario

  1. User sends a message to the Telegram bot
  2. Agent decides (or is prompt-injected) to run printenv or echo $TELEGRAM_BOT_TOKEN
  3. Bot token is returned in the tool output — enables full bot impersonation
  4. With SUDO_PASSWORD (if set), attacker gains root on the host

Suggested fix

Extend the blocklist in _build_provider_env_blocklist():

# Gateway and tool secrets — not in the provider registry
blocked.update({
    # Messaging platform tokens
    "TELEGRAM_BOT_TOKEN", "TELEGRAM_ALLOWED_USERS", "TELEGRAM_HOME_CHANNEL",
    "DISCORD_BOT_TOKEN", "DISCORD_ALLOWED_USERS", "DISCORD_HOME_CHANNEL",
    "SLACK_BOT_TOKEN", "SLACK_APP_TOKEN", "SLACK_ALLOWED_USERS",
    "SIGNAL_ACCOUNT", "SIGNAL_ALLOWED_USERS", "SIGNAL_GROUP_ALLOWED_USERS",
    "WHATSAPP_ALLOWED_USERS",
    "EMAIL_PASSWORD", "EMAIL_ALLOWED_USERS",
    # Tool API keys
    "VOICE_TOOLS_OPENAI_KEY",
    "BROWSERBASE_API_KEY", "BROWSERBASE_PROJECT_ID",
    "FIRECRAWL_API_KEY",
    "FAL_KEY",
    "HONCHO_API_KEY",
    "GITHUB_TOKEN", "GITHUB_APP_PRIVATE_KEY_PATH",
    "WANDB_API_KEY",
    "TINKER_API_KEY",
    "HASS_TOKEN",
    # System
    "SUDO_PASSWORD",
    "GATEWAY_ALLOW_ALL_USERS",
})

Alternatively, consider switching to an allowlist model — only pass known-safe variables (PATH, HOME, USER, SHELL, LANG, TERM, HERMES_HOME, VIRTUAL_ENV, etc.) instead of trying to enumerate every secret.

Environment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions