Hardening guide
Ticketra ships with strong security defaults. This guide summarizes the built-in protections and gives you a checklist to follow before exposing a deployment.
Built-in protections
API layer
- CORS restricted to an explicit
ALLOWED_ORIGINSallowlist (no open wildcard). - Helmet with an explicit Content-Security-Policy, HSTS (1 year), and cross-origin isolation headers.
- CSRF protection via a double-submit cookie, compared in constant time.
- Global rate limiting per IP (health checks and SSE exempt).
- Generic 5xx errors — server errors never leak internal details; client (4xx) errors return actionable messages.
- Parameterized SQL everywhere — no ORM, no string-built queries with user input.
Authentication
- JWT sessions pinned to the
HS256algorithm (no algorithm-confusion). - Account lockout with tiered backoff and per-account/per-IP login rate limits.
- Forced password change for the seed admin on first login.
- Immediate session revocation — disabling a user or revoking sessions drops live SSE streams.
- Identical error messages for unknown user vs. wrong password (no message-based enumeration).
Real-time (SSE)
- Authenticated by the same httpOnly cookie as REST (no token in the URL).
- Per-user and global connection caps; 8-hour session TTL; tenant-isolated broadcasts.
- Events carry only IDs — clients refetch over REST with full RBAC.
Data & secrets
- CTI API keys encrypted at rest (AES-256-GCM, scrypt-derived key).
- Secrets read from Docker secrets, never hardcoded.
- Attachment/avatar/report downloads defended against path traversal.
Container & network
no-new-privileges,cap_drop: ALL, and read-only root filesystems with tmpfs for writable paths.- Network segmentation: a
frontend-netand an internal-onlybackend-net(databases are not reachable from outside).
NGINX
server_tokens off, a restrictivePermissions-Policy,Referrer-Policy, and a strong SPA Content-Security-Policy.
Production checklist
Use this before going live:
- Strong, unique secrets generated for
jwt_secret(≥32 chars),db_password,admin_password(≥12 chars), andintegration_encryption_key. -
secrets/and.envare never committed. - Changed the seed admin password on first login.
-
ALLOWED_ORIGINSset to your real origin(s) only. - Valid TLS certificate in place (internal CA for air-gap), not the self-signed default.
-
trust proxydepth matches your actual proxy chain — an incorrect value lets clients spoofX-Forwarded-Forand weaken per-IP rate limiting and audit IPs. - Dependencies patched — run
npm auditin CI and keep them current. - If LDAP is enabled, keep the connect timeout low to reduce login-timing differences (a username-enumeration consideration), and rely on rate limiting + lockout.
- Backups scheduled, monitored, and test-restored; archives stored off-host on encrypted media.
- Audit log retention configured per your policy.
Reporting a vulnerability
Found a security issue? Please report it responsibly via the contact published at ticketra.net rather than opening a public issue. A coordinated-disclosure window lets us protect deployments before details are public.
Related
Was this page helpful?