Security
Security overview
Last updated: 27 April 2026
Authentication
- Passwords stored only as bcrypt hashes (cost factor 10 minimum); we never see plaintext after the moment of submission.
- Minimum 10 characters; no maximum that matters; no composition rules - length matters more than complexity.
- Rate limiting: 5 failed sign-ins per IP per 15 minutes; 10 per account per hour. Beyond that, the account is briefly locked and the user is emailed.
- Session cookies: HttpOnly, Secure, SameSite=Strict, with rotation on login, password change and privilege escalation.
- Optional TOTP 2FA for any user; mandatory for admin accounts.
Data protection
- TLS 1.2+ on every connection. HTTP Strict Transport Security with one-year max-age + includeSubDomains + preload.
- All SQL via prepared statements with bound parameters - never string-concat. Reviewed at every PR.
- Output encoding: HTML escape on every variable, JSON encode with restricted flags, URL-encode on every parameter.
- Per-user authorisation enforced at the repository layer (every query takes user_id and returns null if the entity isn't owned).
Network & infrastructure
- Cloudflare in front: WAF, bot fight mode, rate limiting at the edge.
- cPanel hosting in the UK; backups daily, retained 30 days.
- Strict CSP: no third-party JavaScript except Stripe Elements; no third-party stylesheets except Google Fonts; no inline scripts.
Operational
- Audit log for every sensitive action (login, password change, site delete, GDPR export, billing change, admin impersonation) retained for 2 years.
- Secrets stored in a `.env` file outside the webroot, mode 600. Logger redacts known sensitive keys before writing log lines.
- API keys rotated quarterly.
Disclosure
Found a security issue? Email security@llmsubmitter.com. We acknowledge within 24 hours, give a triage decision within 72 hours, and credit you in the changelog if you'd like.