Skip to content

fix(security): deny WhatsApp Baileys session directory in media delivery - #51247

Open
srojk34 wants to merge 1 commit into
NousResearch:mainfrom
srojk34:fix/whatsapp-session-denylist
Open

fix(security): deny WhatsApp Baileys session directory in media delivery#51247
srojk34 wants to merge 1 commit into
NousResearch:mainfrom
srojk34:fix/whatsapp-session-denylist

Conversation

@srojk34

@srojk34 srojk34 commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

Summary

The media-delivery denylist (_media_delivery_denied_paths() in gateway/platforms/base.py) was missing the WhatsApp Baileys auth-state directory (whatsapp/session/). Files under this path — notably creds.json (noise key, signed identity/pre-keys, registration) — could be auto-attached to a chat reply via prompt injection in non-strict (default) mode, leaking a full WhatsApp account credential.

The session directory is created by hermes_cli/main.py:2570 (get_hermes_home() / "whatsapp" / "session") and read by gateway/whatsapp_identity.py:136 and hermes_cli/gateway.py:4569. It was not covered by any existing denylist entry, nor by the sibling PRs (#37222 for mcp-tokens/, #41071 for state.db/kanban.db).

Changes

  • gateway/platforms/base.py: add whatsapp/session to _ROOT_CREDENTIAL_DIRS alongside the existing pairing/ entry.
  • tests/gateway/test_platform_base.py: 2 regression tests — creds.json and lid-mapping-*.json both blocked.

Validation

Path Before After
~/.hermes/whatsapp/session/creds.json delivered rejected
~/.hermes/whatsapp/session/lid-mapping-12345.json delivered rejected
~/.hermes/cache/documents/report.pdf delivered delivered (allowlist wins)
  • tests/gateway/test_platform_base.py → 162 passed, 0 failed.
  • Negative check: both new tests fail on main without the fix. ✓
  • ruff check clean.

Sibling of #51055. Follows the per-file/per-dir enumeration shape accepted by maintainers (#32090, #34425).

…ery (NousResearch#51055 sibling)

The media-delivery denylist in _media_delivery_denied_paths() was missing
the WhatsApp Baileys auth-state directory (whatsapp/session/).  Files
under this path — notably creds.json (noise key, signed identity and
pre-keys, registration) — could be auto-attached to a chat reply via
prompt injection in non-strict (default) mode, leaking a full WhatsApp
account credential.

Add whatsapp/session to _ROOT_CREDENTIAL_DIRS alongside the existing
pairing/ entry.  Two regression tests (creds.json + lid-mapping-*.json).
162/162 passing, 0 failed.  Negative check confirms tests fail on main.
@alt-glitch alt-glitch added type/security Security vulnerability or hardening P2 Medium — degraded but workaround exists comp/gateway Gateway runner, session dispatch, delivery platform/whatsapp WhatsApp Business adapter sweeper:risk-security-boundary Sweeper risk: may affect sandboxing, auth, credentials, or sensitive data labels Jun 23, 2026

@teknium1 teknium1 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.

Thanks for identifying the Baileys credential-delivery risk. The targeted denylist approach fits the existing media-delivery design, but the current patch misses the session directory used by fresh installs.

Problems

  • gateway/platforms/base.py adds only whatsapp/session. The Baileys adapter defaults to get_hermes_dir("platforms/whatsapp/session", "whatsapp/session") at plugins/platforms/whatsapp/adapter.py:404-407; get_hermes_dir() returns the modern path unless the legacy directory has content (hermes_constants.py:226-253). platforms/whatsapp/session is still absent from _ROOT_CREDENTIAL_DIRS at gateway/platforms/base.py:1194-1197, while default-mode validation permits existing files not under that denylist (gateway/platforms/base.py:1264-1325).
  • The added tests cover only the legacy layout. Please cover platforms/whatsapp/session too; tests/gateway/test_unauthorized_dm_behavior.py:103-120 already establishes it as the modern layout.

Suggested changes

  • Deny both modern and legacy session paths, and add tests for each.

Automated hermes-sweeper review.

Comment thread gateway/platforms/base.py
# WhatsApp Baileys auth state (noise key, signed identity/pre-keys,
# registration). creds.json + session keys let an attacker hijack
# the paired WhatsApp account.
os.path.join("whatsapp", "session"),

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.

This covers only the legacy path. The current Baileys adapter defaults to get_hermes_dir("platforms/whatsapp/session", "whatsapp/session") (plugins/platforms/whatsapp/adapter.py:404-407), so fresh installs still permit platforms/whatsapp/session/creds.json. Please deny both layouts.

@teknium1 teknium1 added sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform area/sessions Session lifecycle, resume, persistence, history labels Jul 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/sessions Session lifecycle, resume, persistence, history comp/gateway Gateway runner, session dispatch, delivery P2 Medium — degraded but workaround exists platform/whatsapp WhatsApp Business adapter sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:risk-security-boundary Sweeper risk: may affect sandboxing, auth, credentials, or sensitive data type/security Security vulnerability or hardening

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants