Security
Security is a first-class concern in Tracera, with protections at every layer.Authentication Security
CSRF Protection
All state-changing authenticated endpoints require a CSRF token:- Token is generated via
GET /api/v1/auth/csrf - Must be included as
X-CSRF-Tokenheader onPOSTrequests - Prevents cross-site request forgery attacks
Session Security
- Redis-backed sessions with SCS session manager
- 72-hour default lifetime (configurable via
SESSION_LIFETIME_HOURS) - Secure cookie attributes —
HttpOnly,SameSite=Lax,Secure(when using HTTPS) - Session secret requires minimum 32 bytes of entropy
OAuth Hardening
- State parameter validation on all OAuth callbacks to prevent CSRF
- Bounded HTTP client timeouts on outbound OAuth profile lookups
- Explicit status code checks on all provider API responses
Input Validation
- Magic link requests cap JSON body size and normalize email casing/whitespace
- Token format validation before Redis lookups (prevents injection)
- Steam OpenID validates claimed IDs for expected HTTPS scheme, host, path, and numeric SteamID64 format
API Security
Rate Limiting
Authentication endpoints are rate-limited to 20 requests per minute per IP to prevent brute-force attacks.Security Headers
The API sets comprehensive security headers:| Header | Value |
|---|---|
X-Content-Type-Options | nosniff |
X-Frame-Options | DENY |
Referrer-Policy | strict-origin-when-cross-origin |
X-XSS-Protection | 1; mode=block |
WebSocket Security
- Origin validation — Upgrade requests are accepted only from the configured
BASE_URLorigin (plus loopback in development) - Subscription sanitization — Client-sent
item_idsare bounded, deduplicated, and filtered to positive IDs - Prevents cross-site WebSocket hijacking
Runtime Hardening
Docker Security
Production containers run with:- Read-only root filesystems — prevents runtime file modifications
no-new-privileges— prevents privilege escalationcap_drop: ALL— drops all Linux capabilities- Non-root users — services run as unprivileged users
- Resource limits — CPU and memory constraints prevent runaway processes
Server Hardening
ReadHeaderTimeoutenabled to reduce slowloris-style header abuse- Strict environment validation at startup — rejects invalid ports, Redis DB indexes, and non-positive timing values
- Fail-closed design — cache errors in portfolio import cooldown checks fail closed to protect backend resources
Steam Inventory Protection
- SteamID format validation before URL construction
- Max response body reader caps inventory response size
- Per-user import cooldown enforced via Redis to protect Steam API rate limits