Table of Contents
Security
Passkey/WebAuthn (Gallery)
- One-time password registration (
S3G_REGISTRATION_OTPenvironment variable) - Attestation verification via lbuchs/webauthn
- Counter validation during authentication (protection against cloned authenticators)
- Tokens stored as JSON
Session Management
-secure
— HTTPS-only in production (configurable viaAPP_SECURE_COOKIES
)
-httponly
— No JavaScript access
-samesite=Lax
— CSRF mitigation
-session_regenerate_id(true)
on login/logout
CSRF Protection
-
Tokens per session:
bin2hex(random_bytes(32)) -
Timing-secure validation via
hash_equals() -
Required for: Login, Logout, Upload, Delete, Gallery creation
HTTP Headers (Nginx)
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
Referrer-Policy: strict-origin-when-cross-origin
Permissions-Policy: camera=(), microphone=(), geolocation=()
Content-Security-Policy: default-src 'self'; script-src/style-src 'unsafe-inline'
Gallery-FotoBattle Integration
- HMAC-SHA256 tokens for the Submit/Withdraw API
- Shared secret (
BATTLE_SUBMIT_SECRET) between both containers - Timing-secure validation via
hash_equals()
FotoBattle-specific
- Password hashing with bcrypt
- Rate limiting: 5 failed logins → 15-minute lockout per IP hash
- Optimistic locking in the event store (version conflicts)
Input validation
- MIME type check (only image/jpeg, image/png, image/webp)
- File extension whitelist
- File format validation (event galleries)
- Directory traversal protection (
basename/Path normalization)
S3 security
- Credentials exclusively via environment variables
- Image proxy: Client never accesses RustFS directly
- ETag headers for client-side caching