Security is implemented with multiple layers in bootstrap, Security, Router, and controller/model logic.
- HTTP security headers
- HTTPS enforcement in production
- Hardened session cookies and renewal strategy
- CSRF token checks for POST routes
- Route-level auth and permission checks
- Prepared SQL and output escaping in views
- Security::setHeaders() applies browser hardening headers
- Security::enforceHttps() redirects HTTP in production contexts
- HTTPS detection supports reverse proxy scenarios
- HttpOnly cookies enabled
- Secure cookies enabled for HTTPS/production
- SameSite policy configurable via .env
- Session timeout and periodic ID regeneration enabled
- POST requests are validated against csrf_token
- Token lifetime configurable via CSRF_TOKEN_LIFETIME
- Invalid token results in 403 error handling
- Route metadata defines auth and permission requirements
- validateSession() checks user session existence
- checkPermission() supports numeric threshold and explicit allowed lists
- Unauthorized access attempts are logged
- Password hashing uses bcrypt in user/auth flows
- Login flow includes throttling helpers
- Secrets are loaded from .env and must never be committed
- SMTP subject is normalized to prevent header injection
- Both HTML and text/plain bodies are generated for client compatibility and safer fallback
- TLS mode is configurable with
MAIL_ENCRYPTION(ssl/tls) - Certificate verification is configurable and enabled by default
- Sender and recipient addresses are validated before transmission
- SMTP timeout is bounded to avoid hung worker processes
- APP_ENV=production and APP_DEBUG=false in production
- COOKIE_SECURE=true under HTTPS
- .env inaccessible from web
- uploads/ does not execute PHP files
- All state-changing forms include csrf_token
- Role-sensitive routes tested with low/high permission accounts
- SMTP credentials rotated immediately after any accidental exposure
Use names from screenshots/README.md for security evidence captures.