mirror of
https://github.com/kuhyx/signal-bot.git
synced 2026-11-10 20:27:17 +01:00
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
54 lines
2.4 KiB
Markdown
54 lines
2.4 KiB
Markdown
# 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.
|