# Security notes

## Controls implemented

| Area | Control |
|---|---|
| Authentication | PHP sessions, strict cookie mode, HTTP-only cookies, SameSite=Lax, secure cookies on HTTPS, session ID rotation |
| Passwords | `password_hash()` and `password_verify()`, automatic rehash, 12-character complexity policy |
| Authorization | Server-side role and permission checks for every admin section and mutation |
| CSRF | Session-bound token checked on every state-changing public and admin form |
| SQL injection | PDO prepared statements and explicit table/field allowlists |
| XSS | Contextual output escaping and allowlist HTML sanitization for managed rich text |
| Login abuse | Email/IP-hash attempt tracking and a configurable lock window |
| File upload | `finfo` MIME detection, allowlist, byte limit, randomized filename, non-public metadata, executable file blocking |
| Sessions | 30-minute inactivity timeout and logout session destruction |
| Transport/browser | HTTPS redirect, HSTS, CSP, frame protection, MIME sniff protection, referrer and permissions policies |
| Logging | Authentication, content, settings, media, role, user, lead, and backup activity logs |
| Privacy | Hashed IP identifiers for analytics, activity, and submission rate limiting |
| Errors | Production-safe error response; detailed stack traces stored outside the public root |
| Backups | Manual history and confirmed restore with an automatic pre-restore safety snapshot |

## Operational requirements

- Keep `APP_DEBUG=false`.
- Keep `private`, `database`, and backup files outside the domain document root.
- Remove the installer directory after installation.
- Use a unique database password and APP_KEY.
- Enforce multi-factor authentication at cPanel and Cloudflare even though application-level MFA is planned for Version 2.0.
- Review users, roles, activity logs, and error logs monthly.
- Test restore procedures on staging at least quarterly.
- Patch PHP and the hosting environment promptly.
- Keep daily off-site backups in addition to application database snapshots.
- Keep `trust_cloudflare_headers` disabled unless the origin server accepts traffic exclusively from Cloudflare IP ranges.

## Incident response

1. Disable the affected account.
2. Rotate the account, database, cPanel, email, and Cloudflare credentials as applicable.
3. Export activity/error logs and preserve evidence before cleanup.
4. Restore only from a verified clean backup.
5. Review uploads, DNS, cron jobs, `.htaccess`, and administrator accounts.
6. Notify affected parties when required by contract or law.

## Version 2.0 security roadmap

- Application-level MFA/passkeys
- Asynchronous email notifications and security alerts
- Encrypted secret vault integration
- Granular audit-log exports and retention policies
- Queue-backed media processing
- Laravel migration path with policies, form requests, jobs, and automated test coverage
