1 Security
Maurice edited this page 2026-04-03 22:52:24 +02:00

Security

Authentication

TREK supports three authentication methods:

Local Password Auth

  • Passwords hashed with bcrypt (12 rounds, salted)
  • JWT tokens (HS256, 24-hour expiry) stored in trek_session httpOnly cookie
  • Rate limiting: 10 login attempts per 15 minutes per IP

OIDC / Single Sign-On

  • See Single Sign-On for full setup
  • Group-based admin role mapping via claims
  • First OIDC login can auto-promote to admin when OIDC_ONLY=true

Two-Factor Authentication (MFA)

  • TOTP-based (works with Google Authenticator, Authy, etc.)
  • QR code setup with 10 encrypted backup codes
  • Admins can enforce MFA for all users via Admin Panel → Security → Require MFA
  • Users without MFA are blocked from all actions until they set it up

Encryption at Rest

Sensitive data is encrypted with AES-256-GCM before storage:

Data Encrypted
Google Maps API key Yes
Unsplash API key Yes
OpenWeather API key Yes
Immich API key Yes
MFA TOTP secrets Yes
MFA backup codes Yes
OIDC client secret Yes
SMTP password Yes

Encrypted values are stored with an enc:v1: prefix. The encryption key is configured via the ENCRYPTION_KEY environment variable or auto-generated in data/.encryption_key.

To rotate the encryption key:

docker exec -it trek node --import tsx scripts/migrate-encryption.ts

Rate Limiting

Endpoint Limit
Login 10 attempts / 15 min per IP
MFA verification 5 attempts / 15 min per IP
Password change 5 attempts / 15 min
Backup creation 3 per 60 min
MCP API 60 requests / min per user
WebSocket messages 30 per 10 sec per connection

CSRF Protection

TREK uses SameSite: Lax cookies for session management. This prevents cross-site request forgery without requiring explicit CSRF tokens, as the browser only sends the cookie with same-site requests and top-level navigations.

CORS

  • Development: All origins allowed
  • Production (no ALLOWED_ORIGINS): Same-origin only (CORS disabled)
  • Production (with ALLOWED_ORIGINS): Only whitelisted origins allowed

SSRF Protection

Outbound requests (e.g. to Immich, webhook URLs) are validated:

  • Private IPs (RFC-1918: 10.x, 172.16-31.x, 192.168.x) blocked by default
  • Loopback (127.x) and link-local (169.254.x) always blocked
  • Set ALLOW_INTERNAL_NETWORK=true to allow LAN access (e.g. for Immich on the same network)

Container Security

The Docker image is hardened:

  • Runs as non-root user via su-exec
  • Read-only root filesystem
  • Drops all Linux capabilities except CHOWN, SETUID, SETGID
  • /tmp mounted with noexec,nosuid (64 MB)
  • dumb-init for proper signal handling
  • Health check on /api/health

Audit Logging

All security-relevant actions are logged to the audit_log table and viewable in Admin Panel → Audit:

  • User registration, login, password change, account deletion
  • Trip create/update/delete
  • Admin actions (user management, permission changes, OIDC config)
  • Backup create/restore/delete
  • Each entry includes: timestamp, user ID, action, resource, IP address, details

Content Security Policy

TREK sets CSP headers via Helmet:

  • script-src 'self'
  • img-src 'self' https: (plus known tile providers)
  • connect-src 'self' https: (plus maps/weather APIs)

Reporting Vulnerabilities

Email mauriceboe@icloud.com with details. Response within 48 hours.