Skip to content

Security Guide

Ilyes BEN BRIK edited this page Jul 18, 2026 · 1 revision

Security Guide

Production Checklist

Before exposing the app to the internet:

  • Generate strong secrets in .env (DB_PASSWORD, JWT_SECRET, APP_KEY)
  • Change default admin password (Admin1234!)
  • Set APP_DEBUG=false
  • Set CORS_ORIGIN to your actual domain
  • Deploy behind HTTPS (reverse proxy with TLS)
  • Database port is NOT exposed (default ✓)
  • Consider disabling open registration
  • Enable backup encryption

HTTPS Deployment

Use a reverse proxy with Let's Encrypt:

With Caddy (simplest)

yourdomain.com {
    reverse_proxy localhost:3000
}
api.yourdomain.com {
    reverse_proxy localhost:8080
}

With nginx

server {
    listen 443 ssl;
    server_name yourdomain.com;
    ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;
    
    location / {
        proxy_pass http://localhost:3000;
    }
}

Security Features

Feature Implementation
SQL Injection All queries use PDO prepared statements
XSS Vue.js auto-escaping + htmlspecialchars() in PHP
CSRF Token-based auth (JWT in header, not cookies)
Brute Force Rate limiting: 5 login attempts per 15 minutes
Registration Spam Rate limited to 3 per hour per IP
CORS Restricted to configured CORS_ORIGIN only
JWT Security 8-hour expiry, iss/aud claims, fails if secret not set
Password Policy Min 10 chars + uppercase + lowercase + number
Headers CSP, X-Content-Type-Options, X-Frame-Options, Referrer-Policy
Command Injection escapeshellarg() on all shell commands
SSRF ISBN lookup validates format, no redirects, 5s timeout
Info Leakage Generic error messages, display_errors=Off
Container Security Resource limits, restricted filesystem, non-exposed DB
Backup Security .pgpass auth, chmod 600 on files

JWT Token Details

  • Algorithm: HS256
  • Expiry: 8 hours
  • Claims: id, username, email, role, iat, exp, iss, aud
  • Frontend checks expiry before each request
  • 401 response clears token and redirects to login

Rate Limiting

Endpoint Limit Window
/api/auth/login 5 attempts 15 minutes
/api/auth/register 3 attempts 1 hour

Tracked by IP + username combination. Resets on successful login.

Reporting Vulnerabilities

If you find a security issue, please email directly rather than opening a public issue. See CONTRIBUTING.md.


Next: Troubleshooting

Clone this wiki locally