AnyBot/docs/en/security.md

46 lines
3.2 KiB
Markdown
Raw Permalink Normal View History

# Security
One line: **the bot runs on your own machine; your data does not leave by default** — only the model API calls you choose, and (if you sign in to an account) the **ciphertext** of your backup.
**Reporting:** open a private security advisory on the repo (Gitea › Security) or write the owner. We aim to answer in 3 business days, fix in 90. No public disclosure of unfixed issues.
## Trust boundaries
- **Your computer** — the bot's brain, hands, `state.json`, vault. Your OS account is the boundary; shell commands run in the macOS sandbox (denies `~/.aws`, Keychain, AnyBot's own data).
- **The bot's cloud box** — a Docker container the bot roots; automatically switched to gVisor (`runsc`) when the host has it: the kernel joins the boundary.
- **Docker API** — no `docker.sock`: a docker-socket-proxy whitelist (containers/images/networks subset; no `exec`, no `privileged`).
- **Relay** — stores hashes only: argon2id passwords, hashed tokens/sessions; your backup arrives sealed with a key derived from your password (PBKDF2-HMAC-SHA256 120k → AES-256-GCM). The relay never sees plaintext, and it is self-hosted.
- **Model providers** — see the chats and screenshots you hand them, never your files, vault secrets, or keys.
## Where secrets live
| Thing | Where | What an attacker gets |
|---|---|---|
| Model API keys | `state.json` (0600) | that provider's bill — disk encryption, provider 2FA |
| Vault (logins/cards) | `vault.bin`: AES-256-GCM, key in the system keychain (0600 file fallback) | nothing without the keychain; the model never sees secrets — lists come blanked, every fill is approved per use |
| Account password | your app; relay keeps only argon2id (m=19MiB, t=2) | hashes; the backup stays sealed behind your password |
| 2FA | TOTP secret + 8 hashed recovery codes on the relay | disabling 2FA needs password + code in the same turn |
| Sessions | hashed rows; logout-everywhere | a stolen session file works until logout (relay is a trust point) |
## Prompt-injection defenses (layers, not walls)
1. Outside content is wrapped as `<untrusted>` — data, never orders.
2. Sensitive clicks (send/pay/transfer/…): asked **every time**, direct mode included — no grant silences it; the gate is in the harness, not the prompt.
3. First use of every app/computer needs your approval (policy at the data layer).
4. Card numbers and OTPs in screenshots are painted black before the model sees them.
5. Every turn's actions land in an auditable oplog → SQLite audit (30 days), with a phone timeline.
Honest limit: injection has no absolute defense — which is why the last line is a human at the approval gate. The model never issues its own passes.
## Network surface
Loopback by default; egress binds loopback plus detected Docker bridge gateways, never 0.0.0.0. The phone talks to your relay over Caddy HTTPS. LAN mode is opt-in and password-gated.
## Known limits
Same OS user = same trust; providers see chats/screenshots you send them; gVisor is optional on your box; backup security is bounded by your password; a breached relay leaks hashes and ciphertext, not plaintext.
## Hardening
Disk encryption, capped + 2FA'd provider keys, HTTPS-only relay with 2FA, gVisor on the box host, per-app "ask always" on your sensitive apps.