diff --git a/components/Posting/Posting.php b/components/Posting/Posting.php index d84d84011a..e851bf8c75 100644 --- a/components/Posting/Posting.php +++ b/components/Posting/Posting.php @@ -145,9 +145,18 @@ END; * * This can be used in the future to deduplicate images by visual content */ - public static function onHashFile(string $filename, ?string &$out_hash) + public function onHashFile(string $filename, ?string &$out_hash) { $out_hash = hash_file(Attachment::FILEHASH_ALGO, $filename); return Event::stop; } + + /** + * Fill the list of allowed sizes for an attachment, to prevent potential DoS'ing by requesting thousands of different thumbnail sizes + */ + public function onGetAllowedThumbnailSizes(?array &$sizes) + { + $sizes[] = ['width' => Common::config('thumbnail', 'width'), 'height' => Common::config('thumbnail', 'height')]; + return Event::next; + } } diff --git a/src/Controller/Attachment.php b/src/Controller/Attachment.php index 821b307328..ea6fc3b427 100644 --- a/src/Controller/Attachment.php +++ b/src/Controller/Attachment.php @@ -109,13 +109,16 @@ class Attachment extends Controller assert(false, 'Attachment scope not implemented'); } - // TODO rate limit, limit to known sizes + $default_width = Common::config('thumbnail', 'width'); + $default_height = Common::config('thumbnail', 'height'); + $width = $this->int('w') ?: $default_width; + $height = $this->int('h') ?: $default_height; + $crop = $this->bool('c') ?: false; - $max_width = Common::config('thumbnail', 'width'); - $max_height = Common::config('thumbnail', 'height'); - $width = Common::clamp($this->int('w') ?: $max_width, min: 0, max: $max_width); - $height = Common::clamp($this->int('h') ?: $max_height, min: 0, max: $max_height); - $crop = $this->bool('c') ?: false; + Event::handle('GetAllowedThumbnailSizes', [&$sizes]); + if (!in_array(['width' => $width, 'height' => $height], $sizes)) { + throw new ClientException('The requested thumbnail dimensions are not allowed', 400); // 400 Bad Request + } $thumbnail = AttachmentThumbnail::getOrCreate(attachment: $attachment, width: $width, height: $height, crop: $crop);