Configuration

Security

Cleanmails implements multiple layers of security to protect your data and infrastructure.

Encryption

  • Passwords at rest: All sender SMTP/IMAP passwords and integration tokens are encrypted with AES using your MASTER_KEY
  • User passwords: Hashed with bcrypt (cost 10)
  • Session tokens: 32 bytes of cryptographic randomness (hex-encoded)

Authentication

  • HttpOnly cookies: Session tokens are delivered via HttpOnly cookies (not in JSON responses) to prevent XSS theft
  • Secure flag: Cookies are marked Secure in production (HTTPS only)
  • SameSite: Lax mode prevents CSRF attacks
  • Bearer tokens: Also supported via Authorization header for API clients

Brute-Force Protection

  • 10 failed login attempts per IP → 15-minute lockout
  • Counter resets after 10 minutes of inactivity
  • Locked IPs are logged for monitoring

HTTP Security Headers

Every response includes:

  • X-Content-Type-Options: nosniff
  • X-Frame-Options: DENY
  • X-XSS-Protection: 1; mode=block
  • Referrer-Policy: strict-origin-when-cross-origin
  • Permissions-Policy: geolocation=(), microphone=(), camera=()
  • Strict-Transport-Security (production only)
  • Content-Security-Policy — restricts script/style/font sources

Input Validation

  • Request body limit: 10 MB max (configurable)
  • Email validation: RFC-compliant regex on all email inputs
  • Domain validation: Format check on domain names
  • File uploads: Extension whitelist + content-type sniffing (no SVG to prevent XSS)
  • Callback URLs: SSRF protection — validates against internal/private IPs

Webhook Security

  • Outgoing webhooks: Signed with HMAC-SHA256 using per-subscription secrets
  • Incoming bounce webhooks: Require valid HMAC signature (configurable secret)
  • Unsubscribe links: HMAC-signed to prevent enumeration attacks

Session Management

  • Max 50 sessions per user (oldest pruned on new login)
  • Expired sessions cleaned up hourly
  • Password change invalidates all other sessions
  • 7-day session expiry

Data Isolation

  • Workspace-scoped queries prevent cross-workspace data access
  • Members can only access assigned workspaces
  • Campaign list/sender assignment validates workspace ownership