Skip to content

Security: Rotstein007/twopointo

Security

docs/SECURITY.md

Security

Threat Model (STRIDE)

1. Identity & Authentication

Threat Category Mitigation
Account takeover via password Spoofing Mandatory TOTP 2FA; Argon2id password hashing
Brute-force 2FA codes Spoofing Rate limit TOTP attempts; lock account after N failures; 30s TOTP window
Stolen JWT Spoofing Short TTL (15 min); HTTPS-only; HttpOnly cookie or memory-only storage (no localStorage)
JWT algorithm confusion attack Spoofing Verify alg: RS256 header explicitly; reject none/HS256
Refresh token theft Spoofing Refresh tokens stored hashed; single-use rotation; revocation on suspicious reuse
JWKS substitution by rogue mirror Tampering Ed25519 signatures on JWKS; quorum (≥ 2 mirrors must agree); monotonic versioning
Offline validation of revoked token Elevation Short JWT TTL (15 min) limits exposure; denial list propagated to Edge at high frequency

2. Edge Proxy

Threat Category Mitigation
Routing to wrong server tunnel Spoofing server_id validated against tunnel registration; tunnels require valid server JWT
DDoS on Edge Denial of Service Per-server and per-IP rate limits; circuit breaker; CDN-level protection
Tenant isolation bypass Elevation Strict server_id scoping; no cross-tenant query paths
Tunnel hijack Tampering TLS mutual auth for tunnel establishment (server presents a server certificate)
7-day bypass (stale server) Tampering Version check at tunnel establishment + on each API call; cached manifest + 48h grace only

3. Direct Messages (E2EE)

Threat Category Mitigation
Server reads DM content Information Disclosure X3DH + Double Ratchet; server only stores ciphertext
Key impersonation Spoofing Identity keys bound to user account via Identity Service; TOFU with out-of-band verification option
Pre-key exhaustion Denial of Service One-time pre-keys + signed pre-keys; client generates batch and uploads proactively
Forward secrecy break Information Disclosure Double Ratchet provides per-message forward secrecy
Group DM re-add attack Information Disclosure Sender Keys rotation on member add/remove
DM asset linkage Information Disclosure Assets uploaded unencrypted; banner clearly discloses this; no mitigation — by product design
Client-side key exfiltration Information Disclosure Keys never leave the Web Worker; minimise attack surface; CSP headers

4. Assets & Storage

Threat Category Mitigation
Persistent links after deletion Information Disclosure Tokenized resolver; token revoked on asset delete; CDN no-store; signed URLs TTL 60s
Asset URL guessing Information Disclosure Tokens are cryptographically random (≥ 128 bits); ULIDs not used as tokens
CDN serving stale deleted content Information Disclosure Cache-Control: no-store on resolver; storage provider delete + cache purge event
Unauthorized asset access Elevation Resolver checks token validity + ref_count > 0; no auth bypass
CSAM / illegal content upload Compliance Detection hooks (v1.0); report flow; operator responsibility; ToS enforcement

5. Permissions & Authorization

Threat Category Mitigation
Permission bypass via BigInt overflow Elevation Parse permissions as BigInt; validate all bit operations; reject unknown bits
ADMINISTRATOR abuse Elevation ADMINISTRATOR grants all bits; only Owner can assign ADMINISTRATOR; audit log required
Channel overwrite race condition Tampering Overwrites applied atomically; DB transaction; optimistic locking
Role hierarchy bypass Elevation Users cannot assign roles with higher position than their own highest role
App bypassing permissions Elevation Apps always have all permissions by design; only admin can install/configure apps; channel subscriptions limit blast radius

6. Discovery & KYC

Threat Category Mitigation
Fake KYC submission Spoofing Third-party ID verification vendor; manual review fallback
KYC data breach Information Disclosure Data minimization: store only verification status + operator ID; no raw ID documents
Discovery spam Tampering KYC required for listing; report flow; operator contact required
Invite abuse (mass join) Denial of Service Server-side join rate limit; invite expiry + max-use options

7. App Gateway & Slash Commands

Threat Category Mitigation
Malicious App Agent sending false events Tampering App Agents authenticated with app token; token bound to app_id; server validates signature
Prompt injection via slash command Injection User input passed verbatim to App Agent; agents must treat all input as untrusted data; documented in App SDK
App Agent impersonation Spoofing App token required for App Gateway connection; tokens rotatable by owner
App installed without admin consent Elevation Requires MANAGE_GUILD permission to install
App reading unauthorized channels Information Disclosure Channel subscriptions enforced at Edge/App Gateway; apps only receive events for subscribed channels

Prompt Injection Warning

Slash commands forward user-supplied text to App Agents. App developers MUST treat all user input (options, message content via subscriptions) as untrusted. Specific risks:

  • If an App Agent calls an LLM, user input must be sanitized to prevent prompt injection (e.g., "ignore previous instructions and...").
  • App Agents should validate option values against expected types/ranges.
  • The twopointo platform cannot prevent injections at the app level; this is documented prominently in the App Developer documentation.

OWASP Top 10 Mapping

OWASP Mitigation
A01 Broken Access Control BigInt permission bitfield; channel overwrites; Edge auth on every request
A02 Cryptographic Failures Argon2id passwords; RS256 JWTs; Ed25519 mirror sigs; TLS everywhere
A03 Injection Parameterized queries (pgx); no raw SQL concat; slash command input treated as untrusted
A04 Insecure Design E2EE DMs by default; hard deletion guarantee; mandatory 2FA; minimal KYC data
A05 Security Misconfiguration Docker Compose .env.example with safe defaults; TLS required; no debug endpoints in prod
A06 Vulnerable Components Dependency pinning + automated updates (Dependabot); SBOM generation
A07 Auth Failures Mandatory 2FA; rate limiting; token rotation; JWKS offline validation
A08 Software Integrity Signed release manifests (Ed25519); SHA-256 binary checksums; 7-day update enforcement
A09 Logging Failures Structured audit log; all admin actions logged; Edge access log
A10 SSRF Asset upload uses presigned URLs (client → storage directly); no server-side URL fetch from user input

Token Revocation Strategy

Access Token (JWT, 15-min TTL)

  • Short TTL limits exposure window without revocation.
  • On explicit logout or suspicious activity: add jti to Edge deny-list (Redis, TTL = remaining JWT lifetime).
  • Edge checks deny-list on every request.
  • Signed mirrors distribute revoked jti list for offline-capable self-hosted servers (optional, near-real-time).

Refresh Token

  • Stored hashed in database.
  • Single-use rotation: each use issues a new refresh token; old one invalidated.
  • Reuse detection: if old refresh token reused, invalidate entire session family (potential theft).
  • User can revoke all sessions from device management UI.

Abuse & Reporting Flow

  1. User submits in-app report (POST /reports).
  2. Report stored with target metadata + reporter ID.
  3. Notification sent to server operator via contact channel (if Discovery-listed).
  4. twopointo trust & safety team reviews flagged reports (for officially hosted or Discovery-listed).
  5. Self-hosted servers: operators self-responsible for moderation; twopointo can de-list from Discovery.
  6. Mass-report abuse: rate limit on report submissions per user; dedup by target.

Failure Modes

Identity Service Down

  • New logins blocked. Registration and login endpoints return 503.
  • Existing sessions continue. JWT validation is offline via cached JWKS (from mirrors).
  • No new 2FA setups. TOTP verification endpoint unavailable.
  • Token refresh blocked. Clients with expired access tokens cannot get new ones; they are effectively logged out after JWT expiry.
  • Mitigation: JWKS cached by self-hosted servers and mirrors; JWT TTL set to 15 min to balance security and outage tolerance.

Edge Down

  • Hard outage for all API operations. Web clients cannot send new requests.
  • UI shows read-only mode. Last-loaded messages visible from in-memory cache.
  • No new messages, no realtime events. Everything stops.
  • Self-hosted servers: tunnel disconnected; no new client connections routed.
  • Honest statement: Edge is the single control-plane endpoint in MVP. Its outage is a full service outage.

Mirrors Down

  • All mirrors unavailable → use last-known-good cached artifacts (JWKS, manifest, directory snapshot, revocation list).
  • Grace TTL per artifact type (see SIGNED_MIRRORS.md).
  • After grace: JWKS validation fails hard (new validations rejected); manifest update check skipped; directory shows stale or unavailable.
  • Mirrors do NOT restore control-plane functionality when Edge is down.

Tunnel Drop (self-hosted server)

  • Server attempts reconnect with exponential backoff (base 1s, max 60s, jitter ±20%).
  • In-flight requests return 503 to clients during reconnect window.
  • On reconnect, Edge re-validates version compliance before routing resumes.

There aren’t any published security advisories