36 lines
1.1 KiB
PHP
36 lines
1.1 KiB
PHP
<?php
|
|
// Rate limiter for chatbot API - 10 req/min per IP
|
|
$ip = $_SERVER['REMOTE_ADDR'] ?? 'unknown';
|
|
// Whitelist localhost (nonreg tests)
|
|
if(in_array($ip,['127.0.0.1','::1'])) return;
|
|
$rateFile = '/tmp/rate_' . md5($ip) . '.json';
|
|
$limit = 10; // requests per minute
|
|
$window = 60; // seconds
|
|
|
|
$now = time();
|
|
$data = [];
|
|
if (file_exists($rateFile)) {
|
|
$data = json_decode(file_get_contents($rateFile), true) ?: [];
|
|
}
|
|
|
|
// Clean old entries
|
|
$data = array_filter($data, function($t) use ($now, $window) {
|
|
return ($now - $t) < $window;
|
|
});
|
|
|
|
if (count($data) >= $limit) {
|
|
header('Content-Type: application/json');
|
|
header('Retry-After: 60');
|
|
http_response_code(429);
|
|
echo json_encode(['error' => 'Trop de requetes. Reessayez dans 1 minute.', 'code' => 429]);
|
|
exit;
|
|
}
|
|
|
|
$data[] = $now;
|
|
file_put_contents($rateFile, json_encode(array_values($data)));
|
|
|
|
// Also add security headers
|
|
header('X-Content-Type-Options: nosniff');
|
|
header('X-Frame-Options: DENY');
|
|
header('Referrer-Policy: strict-origin-when-cross-origin');
|
|
header('Permissions-Policy: camera=(), microphone=(), geolocation=()'); |