From d6a9fd1c32f07b993cb8ecc3c1b7c22f7a0ce848 Mon Sep 17 00:00:00 2001 From: Thomas Vanbesien Date: Sun, 22 Mar 2026 13:34:47 +0100 Subject: Add upload security: size limit, per-user and site-wide post caps Reject base64 payloads over 10 MB, limit users to 50 posts each, and cap total posts at 10,000 (~650 MB on disk). Document upload security model in README. --- src/app/Controllers/EditorController.php | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'src/app/Controllers') diff --git a/src/app/Controllers/EditorController.php b/src/app/Controllers/EditorController.php index c7dd9fc..c8cae0d 100644 --- a/src/app/Controllers/EditorController.php +++ b/src/app/Controllers/EditorController.php @@ -12,6 +12,13 @@ use App\Models\Post; class EditorController { + // Per-user and site-wide caps prevent disk exhaustion — even if someone + // creates multiple accounts, the total limit still applies. + // Each composited image is a 640×640 JPEG at quality 85, averaging ~65 KB. + // 50 posts/user ≈ 3.2 MB per user, 10 000 total ≈ 650 MB on disk. + private const MAX_POSTS_PER_USER = 50; + private const MAX_POSTS_TOTAL = 10000; + private Post $post; public function __construct() @@ -60,7 +67,28 @@ class EditorController return; } + if ($this->post->countByUserId($_SESSION['user_id']) >= self::MAX_POSTS_PER_USER) { + http_response_code(400); + echo json_encode(['error' => 'You have reached the maximum number of posts.']); + return; + } + + if ($this->post->countAll() >= self::MAX_POSTS_TOTAL) { + http_response_code(400); + echo json_encode(['error' => 'The site has reached its storage limit.']); + return; + } + $imageData = $input['image_data'] ?? ''; + + // Reject oversized payloads before doing any processing — base64 adds ~33% + // overhead, so 10 MB base64 ≈ 7.5 MB image, which is more than enough + if (\strlen($imageData) > 10 * 1024 * 1024) { + http_response_code(400); + echo json_encode(['error' => 'Image too large.']); + return; + } + $overlayName = $input['overlay'] ?? ''; $overlayScale = (float) ($input['overlay_scale'] ?? 1.0); -- cgit v1.2.3