Files
Shade/THREAT-MODEL.md

100 lines
5.3 KiB
Markdown
Raw Normal View History

# Threat Model
This document describes what Shade protects against and what it doesn't. Read this before deploying Shade in any context where the answers matter.
## Assets
The thing we're protecting:
- **Message plaintext** — the actual content of encrypted messages between peers
- **Identity private keys** — long-term Ed25519 signing key + X25519 DH key
- **Session state** — Double Ratchet root keys, chain keys, DH keypairs
## Adversaries we consider
### 1. Network attacker (active)
Can intercept, modify, drop, replay, and inject network traffic between clients and the prekey server, and between two clients.
**Mitigations:**
- All identity-key writes to the prekey server are signed (Ed25519). Tampering is detected.
- Signed requests have a 5-minute replay window.
- The Double Ratchet binds message headers to ciphertext via AES-GCM AAD, so header tampering breaks decryption.
- Forward secrecy: even if an attacker captures all traffic, compromising a key later doesn't help them read past messages.
**NOT mitigated:**
- Initial session establishment can be MITM'd if users don't verify identity fingerprints. The prekey server could distribute a fake bundle on first contact. Always compare safety numbers out-of-band for high-stakes communications.
### 2. Malicious or compromised prekey server
The server holds identity public keys and prekey bundles. It can serve them to anyone.
**Mitigations:**
- The server only stores PUBLIC keys, never private ones.
- Write operations are signed with the identity private key, so the server can't forge new identities or replenishments without the user's key.
- Bundle fetches are unauthenticated, so a malicious server can serve fake bundles. Detection requires out-of-band fingerprint comparison.
**NOT mitigated:**
- A malicious server can substitute one user's prekey bundle with the server operator's own keys, enabling MITM at session establishment. Users must verify safety numbers to detect this.
### 3. Compromised endpoint (post-compromise)
Attacker briefly gains code execution or filesystem access on a user's device, exfiltrates session state, then loses access.
**Mitigations:**
- Forward secrecy: messages sent BEFORE the compromise cannot be decrypted with the leaked state. Old chain keys are zeroed after use.
- Post-compromise security: as soon as a peer initiates a new DH ratchet step, the leaked state becomes useless for new messages.
- Memory zeroization: message keys and chain keys are wiped from JS memory after use (best-effort — V8 may retain copies).
**NOT mitigated:**
- An ongoing endpoint compromise can read messages in real time and exfiltrate identity private keys.
- Attackers with persistent access can intercept new identity rotations.
### 4. Compromised device storage
Attacker gains access to the persistent storage (e.g., steals the SQLite file or dumps the PostgreSQL table).
**Mitigations:**
- Stored data includes private keys but is unencrypted at rest. Shade does NOT encrypt the storage layer — it assumes the database is in a trusted environment.
**NOT mitigated:**
- Filesystem-level encryption (LUKS, FileVault) is the user's responsibility.
- Database TLS in transit is the user's responsibility.
### 5. Side-channel attacks (timing)
Attacker measures timing of identity verification operations to recover key bits.
**Mitigations:**
- All comparisons of secret material use constant-time XOR-accumulator comparison (`constantTimeEqual`).
- AES-GCM and the underlying primitives are constant-time as implemented by SubtleCrypto and @noble/curves.
**NOT mitigated:**
- JavaScript JIT compilation can introduce timing variability that's hard to control.
- We don't claim resistance to power-analysis or fault-injection attacks (out of scope for a JS library).
### 6. Denial of service
Attacker floods the prekey server to exhaust resources or one-time prekeys.
**Mitigations:**
- Per-IP rate limiting on registration and bundle fetches.
- Per-identity rate limiting on replenish and delete.
- 64KB body size limit on POST endpoints.
- Address validation rejects path traversal and malformed inputs.
**NOT mitigated:**
- Application-level DDoS at the network layer is your hosting platform's responsibility.
## Assumptions
1. **The user has a secure way to bootstrap trust.** Either:
- Trust on first use (TOFU) — accept the first identity key seen for a peer
- Out-of-band verification — compare safety numbers in person/video before trusting
2. **Cryptographic primitives are sound.** We trust X25519, Ed25519, AES-256-GCM, HKDF-SHA256, HMAC-SHA256.
3. **The runtime is honest.** A malicious Bun/Node/browser runtime can defeat any JS library.
4. **The prekey server is reachable.** If it's offline, new sessions can't be established (but existing sessions continue working).
## Residual risks
| Risk | Severity | Mitigation |
|------|----------|------------|
| MITM at first session establishment | High | Compare safety numbers out-of-band |
| Identity private key theft from device | Critical | Filesystem encryption, secure enclave (future) |
| Prekey server operator runs a "key oracle" attack | Medium | Distributed/federated prekey servers (future) |
| Side-channel via JIT timing variability | Low | Constant-time primitives reduce but don't eliminate |
| Metadata visibility to prekey server | Low | Acceptable for most use cases; mix networks for stronger metadata protection |