teteffd / docs /security.md
Developer
WormGPT - production-grade AI chat platform
276ef31
|
Raw History Blame Contribute Delete
3.8 kB
# Security Model
## Threat model
| Threat | Mitigation |
|----------------------------------------------|----------------------------------------------------------------------------------|
| Credential stuffing / brute force | bcrypt + account lockout after 8 failures (15 min) |
| Session hijack | Short access TTL (30 min) + refresh rotation + device fingerprint + revoke UI |
| CSRF | Double-submit cookie pattern; `CSRFMiddleware` blocks unsafe w/o header |
| XSS via rich text | `rehype-sanitize` on all markdown + safe Prism highlighter + KaTeX |
| Secret exfiltration to browser | API responses never include `apiKey` plaintext; only `hasApiKey` flag |
| System prompt leakage | Admin-only endpoints; `SystemPromptOut` field names strip content for non-admins|
| SSRF via web search | Only outbound GET to `http(s)` URLs; HTML cleaned, no JS executed |
| Rate limit abuse | Redis fixed-window per (user\|IP) on all sensitive endpoints |
| Mass assignment | Strict Pydantic models; `exclude_none` on updates; `extra=ignore` config |
| Mongo injection | BSON ObjectId validation; no raw `$where`/`$function` |
| Log injection | Structured `structlog` JSON, request ID propagated, secrets redacted in logger |
| TLS downgrade | Nginx forces HSTS, TLS 1.2+ ciphers, HTTP → HTTPS redirect |
| Clickjacking | `X-Frame-Options: DENY` + CSP `frame-ancestors 'none'` |
| Open redirect | Login redirects stay on same origin via Next.js route guards |
| Memory poisoning | Memory items stored per-user; only owners can list/delete; admins audit access |
| Prompt injection | System prompt assembled server-side from admin-curated content + user memory; user message never injected into the system block; tool/function calls not yet exposed |
## Encryption at rest
- **API keys** stored in `models.encryptedApiKey` as Fernet tokens.
- **System prompts** stored in plaintext (they are not secrets) but **never sent** to non-admin clients.
- **Refresh tokens** stored hashed (sha256) so DB leak does not enable session replay.
## Transport
- TLS terminated at Nginx; backend listens plain HTTP behind the proxy.
- Cookies: `Secure` (production), `HttpOnly` (refresh), `SameSite=Lax` by default.
- Security headers: CSP, HSTS (1y, includeSubDomains), X-Content-Type-Options=nosniff, X-Frame-Options=DENY, Referrer-Policy=strict-origin-when-cross-origin, Permissions-Policy.
## Logging
- `structlog` JSON to stdout.
- `x-request-id` propagated from client or generated, returned in response.
- Timing header `x-response-time-ms`.
- `audit_logs` collection is append-only from the application's perspective; only superadmin can soft-archive (out of scope for v1).
## Rate limiting
- Fixed-window per (user id, IP fallback), configurable via `RATE_LIMIT_PER_MIN`.
- Default 120/min.
- Returns `429` with `Retry-After`.
## Future hardening (out of scope for v1)
- Argon2id migration path (config flag).
- WebAuthn / passkeys.
- mTLS for admin endpoints.
- Per-IP WAF rules.
- Vector-based prompt-injection classifier on user inputs.