2.5 KiB
2.5 KiB
Security
Authentication and sessions
| Mechanism | Details |
|---|---|
| Login | username/email + password + image CAPTCHA |
| Access JWT | Short-lived (~15 minutes) |
| Refresh | Hashed in DB; remember-me ≈ 30 days, short session ≈ 24 hours |
| Browser cookies | pargar_access / pargar_refresh — HttpOnly, SameSite=Lax, Secure when PUBLIC_URL is https |
| Frontend storage | Only user in localStorage (pargar.auth); tokens are not persisted |
| API | credentials: "include"; optional Bearer for tests/clients |
| Logout | Revoke refresh + clear cookies |
Public password recovery (/api/auth/recovery/* and /recovery) is disabled for students (404). Resets are admin-only and require the target account’s security answer.
Secrets
- Outside
DEV_MODE,Validate()rejects values likechange-me/local-dev-onlyand JWTs shorter than 32 characters. - Local Helm: generate-once; production:
existingSecretrequired. ADMIN_PASSWORDonly bootstraps when the admin user is missing; restarts do not overwrite the password.
Proxy and CORS
- Only peers in
TRUSTED_PROXY_CIDRSare trusted forX-Forwarded-*/X-Real-IP. - CORS:
FRONTEND_ORIGINS+PUBLIC_URLwithAllowCredentials: true.
Rate limiting
| Scope | Approximate behavior |
|---|---|
| Auth (login/register/captcha/refresh/recovery) | Redis per-IP budget; tighter after failures |
Global /api/* |
~240 req/min/IP; 429 + user message + Retry-After; does not revoke tokens |
| External chat export | ~10/min/IP |
| Per-user uploads | Separately limited |
/api/health is excluded from the global ceiling.
Uploads
| Type | Controls |
|---|---|
| Admin video | Extension + MIME + magic (MP4/WebM) |
| Avatar | JPEG/PNG/WebP via magic only; client Content-Type is not trusted |
| Chat | Extension allow-list + sniff for image/video/audio/PDF/Office; raw public zip removed |
Certificates and privacy
- Certificate URLs are unlisted; noindex via API, Traefik, Next, and robots.txt.
- Chat-export tokens are single-use, revocable, and redacted from logs/metric labels.
Known trade-offs (current model)
- SameSite=Lax + same-origin instead of a separate CSRF token (adequate for this model; revisit if FE and API split domains).
- Donations and physical certificates have no online payment gateway — intentional.
- XSS remains dangerous; HttpOnly cookies reduce token theft from localStorage but do not eliminate XSS.