Security

Security

CSRF protection

State-changing requests are guarded by CsrfMiddleware for POST, PUT, and DELETE.

$token = (string) ($request->input('_csrf')
    ?? $request->headers['X-CSRF-Token']
    ?? $request->headers['x-csrf-token']
    ?? $_SERVER['HTTP_X_CSRF_TOKEN']
    ?? '');

Use \Keel\Core\Csrf::field() for forms or the csrf-token meta tag for fetch requests.

Rate limiting

ThrottleMiddleware applies an IP + route key and uses the rate_limits table.

$key = strtolower($ipAddress . '|' . $request->uri);
RateLimiter::attempt($key, 30, 1);

On overflow, JSON requests get a 429 JSON response; web requests abort with 429.

Error handling

Unknown routes render 404 via ErrorHandler::render(404); uncaught exceptions render 500.

In production, detailed exception output is hidden unless APP_DEBUG=true.

Baseline security headers

  • X-Content-Type-Options: nosniff
  • X-Frame-Options: DENY
  • Referrer-Policy: strict-origin-when-cross-origin