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: nosniffX-Frame-Options: DENYReferrer-Policy: strict-origin-when-cross-origin