Do not open a public issue for a security problem. Contact the repository maintainer privately (GitHub Security Advisories or direct message).
- Set
AUTH_SECRETto a strong value (openssl rand -hex 32; 32 characters minimum in development and production). - Never commit
.envordata/hobbyhoops.db(or its associated WAL files). - Expose the application behind an HTTPS reverse proxy; leave
COOKIE_SECUREat its default or forcetrue. - Enable
TRUST_PROXY=trueonly if the reverse proxy rewritesX-Forwarded-For/X-Forwarded-Proto(otherwise rate limits share a single key). - Set
BOOTSTRAP_TOKEN(required in production) and send theX-Bootstrap-Tokenheader to create the first account, then remove or rotate the token after bootstrap. GET /api/healthreturns only{ ok }(no version or DB metadata).- Misconfigured
AUTH_SECRETreturns HTTP 503 (not 401) on protected routes. - Restrict network access to the container (port bound to
127.0.0.1indocker-compose.yml). - HTTP hardening headers (
HSTS,X-Content-Type-Options, etc.) are handled by the reverse proxy. - Back up
data/hobbyhoops.dbregularly on the host withsqlite3 … ".backup '…'"(consistent snapshot, WAL-safe). Keep at least 14 days indata/backups/(gitignored) and ideally an off-site copy. On restore, stop the app, replace the.dbfile, and deletehobbyhoops.db-wal/hobbyhoops.db-shmbefore restarting — see README.md. Backup scripts stay local, outside the repository.
Unauthenticated visitors see the login form at / (internal rewrite, no redirect). /login permanently redirects to /. Other protected paths redirect once to /?from=<path> for post-login return.
Every authenticated user can access /admin and write APIs. This model fits a personal or family instance; multi-user deployments with roles would require evolving the user schema.
- Session cookie:
httpOnly,Secure(production / HTTPS proxy),SameSite=strict. - A new login revokes other sessions for the same user.
POST /api/auth/loginandPOST /api/auth/bootstrap: CSRF protection (Origin/Sec-Fetch-Site).- All API mutations require
OriginorSec-Fetch-Site(requireFetchMetadata). - Rate limiting on login, bootstrap, bootstrap discovery, current-password verification (profile), card / reference / guide writes, and
GET /api/admin/data. POST /api/auth/bootstrapis rejected once an account exists.
- Rate limits stored in SQLite: sufficient for a single instance; replace with a shared store for multi-replica deployments.
- Strict CSP with nonces (
src/proxy.ts): in development only,'unsafe-eval'(React DevTools) and'unsafe-inline'for styles; not used in production. - Languages: French (default) and English (US),
hh_localecookie, switch via the sidebar or login screen.