Relocate config.php with plaintext secrets outside the webroot; add per-IP rate limiting to the unauthenticated testimonial image upload endpoint

This commit is contained in:
2026-07-06 07:53:54 +00:00
parent 982a5dc5ff
commit 6c7344ec52
2 changed files with 20 additions and 2 deletions
+19 -1
View File
@@ -74,11 +74,29 @@ if ($method === 'DELETE' && $id) {
}
// POST upload testimonial image (public)
// POST upload testimonial image (public) - rate limited per IP to prevent
// unauthenticated storage/bandwidth abuse (this endpoint has no login requirement).
if ($method === "POST" && $id === "upload") {
$ip = $_SERVER['REMOTE_ADDR'] ?? 'unknown';
$limitRow = $db->prepare("SELECT upload_count, window_start FROM upload_rate_limits WHERE ip_address = ?");
$limitRow->execute([$ip]);
$limit = $limitRow->fetch();
$windowFresh = $limit && (strtotime($limit['window_start']) > time() - 3600);
if ($windowFresh && (int)$limit['upload_count'] >= 5) {
jsonResponse(["error" => "Too many uploads. Please try again later."], 429);
}
if (!isset($_FILES["file"])) jsonResponse(["error" => "No file uploaded"], 400);
$result = handleImageUpload($_FILES["file"]);
if (isset($result['error'])) jsonResponse(["error" => $result['error']], $result['status']);
if ($windowFresh) {
$db->prepare("UPDATE upload_rate_limits SET upload_count = upload_count + 1 WHERE ip_address = ?")->execute([$ip]);
} else {
$db->prepare("REPLACE INTO upload_rate_limits (ip_address, upload_count, window_start) VALUES (?, 1, NOW())")->execute([$ip]);
}
jsonResponse(["url" => $result['url']]);
}
+1 -1
View File
@@ -5,7 +5,7 @@
*/
// Load configuration and dependencies
require_once __DIR__ . '/config.php';
require_once '/home/epictravelexpeditions.com/api-secrets.php';
require_once __DIR__ . '/includes/database.php';
require_once __DIR__ . '/includes/jwt.php';
require_once __DIR__ . '/includes/functions.php';