API Security & Defense Layer
In a stateless API-First environment, traditional session cookies and CSRF tokens are replaced by high-throughput native defense layers: Nginx C-level rate limiting, deep file inspection (`Core\Upload`), and strict payload validation (`Core\Validate`).
1. C-Level DDoS & Brute-Force Protection (`limit_req`)
Our Nginx configuration (`docker/nginx/nginx.conf`) allocates a shared memory zone (`api_limit:10m`) tracking incoming client IPs in native C memory.
limit_req_zone $binary_remote_addr zone=api_limit:10m rate=60r/s;
server {
location /api/ {
limit_req zone=api_limit burst=30 nodelay;
limit_req_status 429;
...
}
}
If a client exceeds 60 requests per second with a burst threshold of 30, Nginx blocks the connection instantly and returns {"error":"Too Many Requests","code":429} without launching PHP workers.
2. Anti-Malware File Upload Scanner (`Core\Upload`)
Allowing users to upload files is one of the highest attack vectors in PHP. `Core\Upload` mitigates this by performing double verification: `finfo` deep MIME checks AND byte inspection to detect embedded PHP script blocks (`
use Core\Upload;
use Core\Response;
$savedFile = Upload::save($_FILES['attachment'], 5242880, [
'image/png' => 'png',
'image/webp' => 'webp',
'application/pdf' => 'pdf'
]);
if (!$savedFile) {
Response::json(['error' => 'Invalid file upload or embedded malware detected'], 422);
}
Response::json(['status' => 'uploaded', 'filename' => $savedFile]);
3. Stateless API Authentication (Bearer / API Keys)
For REST APIs, inspect `Authorization: Bearer
use Core\Request;
use Core\Response;
use Core\Cache;
$token = Request::bearerToken();
if (!$token) {
Response::error('Missing Authorization Bearer token', 401);
}
$user = Cache::api("auth_token_{$token}", fn() => User::all("api_token = ?", [$token])[0] ?? null, 120);
if (!$user) {
Response::error('Unauthorized or expired token', 401);
}
4. Zero-Dependency JSON Web Tokens (`Core\Jwt`)
LilaPHP includes Core\Jwt for generating and verifying HMAC-SHA256 (HS256) JWT tokens without external Composer packages. It signs payloads using your APP_KEY and verifies claim expiration in microsecond precision.
use Core\Jwt;
use Core\Request;
use Core\Response;
$token = Jwt::encode([
'user_id' => $user->id,
'username' => $user->username,
'role' => $user->role
], 86400);
Response::json([
'status' => 'success',
'token' => $token,
'token_type' => 'Bearer'
]);
$token = Request::bearerToken();
$claims = $token ? Jwt::decode($token) : false;
if ($claims === false) {
Response::error('Invalid or expired JWT token', 401);
}
$userId = $claims['user_id'];
$userRole = $claims['role'];
5. Encrypted Session Auth & Brute-Force Protection (`Services\AuthService`)
For web applications, dashboards, or session-based APIs, LilaPHP provides Services\AuthService. It combines AES-256 encrypted session payloads (`Core\Security::encrypt`), HTTP-only cookie flags, and automated brute-force login attempt lockout throttling.
Example: Session Auth Route (`app/routes/api/auth.php`)
<?php
use Core\Request;
use Core\Response;
use Services\AuthService;
Request::GET(function () {
$user = AuthService::validateAuth(false);
return [
'status' => 'success',
'authenticated' => $user !== false,
'user' => $user ?: null
];
});
Request::POST(function () {
$action = Request::input('action', 'login');
if ($action === 'logout') {
AuthService::logout();
return ['status' => 'success', 'message' => 'Logged out successfully'];
}
$username = trim((string) Request::input('username', ''));
$password = (string) Request::input('password', '');
if (empty($username) || empty($password)) {
Response::error('Username and password are required', 400);
}
$result = AuthService::login($username, $password);
if ($result['success']) {
return ['status' => 'success', 'user' => $result['user']];
}
Response::error(
$result['message'],
401,
[
'locked' => $result['locked'] ?? false,
'remaining_seconds' => $result['remaining_seconds'] ?? 0
]
);
});
6. CSRF Protection in Web Forms & Views
LilaPHP automatically injects $csrf_input, $csrf_token, and $csrf_meta into all view and layout scopes. Form submissions can be validated using Security::csrfVerify():
<!-- Inside app/views/contact.php -->
<form method="POST" action="/contact">
<?= $csrf_input ?>
<input type="email" name="email" required>
<button type="submit">Submit</button>
</form>
<?php
// Inside app/routes/contact.php
Request::POST(function () {
if (!Security::csrfVerify(Request::input('_csrf'))) {
abort(403, 'Invalid CSRF token');
}
// Process form
});