signal-bot/SECURITY.md
2026-08-29 15:30:08 +02:00

2.4 KiB

Security Policy

Scope depends on whose account it runs as

Two deployments, two very different blast radii:

  • Its own registered number (scripts/register_bot.sh). A separate identity with no DMs and no history of its own. The groups it can see are exactly the groups somebody added it to, so it watches all of them and discovers new ones by itself. .env gets no GROUP_IDS.
  • A linked device (scripts/live_smoke.sh). It rides a personal account: it can read every DM and every group on it, and anything it sends is sent as the account owner. .env therefore gets GROUP_IDS pinned to the single group chosen during setup, and signal_write_env writes that automatically — the mode decides, not the operator's memory.

Anyone who can add the bot's number to a group can make it active there. That is the intended trade for zero-step setup on a dedicated account; pin GROUP_IDS if you want the old behaviour back.

The bot therefore:

  • writes the pinning decision at setup time, from the mode, so an unpinned linked device is not something you can arrive at by forgetting a step;
  • refuses to start when GROUP_IDS names a group it is not a joined member of, naming the group;
  • drops messages with no groupInfo (direct messages) explicitly, in counting.watched_group, rather than relying on a falsy comparison;
  • resolves a message's group once, and uses that one answer as the reply address and the key for all per-group state, so the scoping gate and the reply router cannot disagree and answer in the wrong group;
  • ships a scoping scenario asserting that direct messages and other groups produce zero outbound messages, run by scripts/e2e.sh in CI.

If you widen that boundary, the scoping scenario is what should fail.

Secrets

.env is gitignored and never committed. .env.sample contains no real values. The bot reads no credentials of its own: authentication is the signal-cli data directory mounted into the container, which stays on the host.

Reporting a vulnerability

Open an issue at https://github.com/kuhyx/signal-bot/issues. If the issue would expose message content or account access, say so without a working proof of concept in the public issue.

Dependencies

Every dependency is exact-pinned at its newest stable release and checked by scripts/check_dependency_freshness.sh in pre-commit and CI. There are no pre-release pins.