From 2882bffe3562d35e7badc810b7aefd67589b365a Mon Sep 17 00:00:00 2001 From: Tegaki Date: Wed, 22 Mar 2023 21:08:23 +0100 Subject: [PATCH] implement MIME checks on upload --- ext/transcode/main.php | 12 ++++++++++++ ext/upload/config.php | 2 ++ ext/upload/main.php | 19 +++++++++++++++++++ 3 files changed, 33 insertions(+) diff --git a/ext/transcode/main.php b/ext/transcode/main.php index e284e81e..bc6abe30 100644 --- a/ext/transcode/main.php +++ b/ext/transcode/main.php @@ -167,6 +167,18 @@ class TranscodeImage extends Extension { global $config; + // this onDataUpload happens earlier (or could happen earlier) than handle_pixel.onDataUpload + // it mutates the image such that the incorrect mime type is not checked (checking against + // the post-transcode mime type instead). This is to give user feedback on what the mime type + // was before potential transcoding (the original) at the time of upload, and that it failed if not allowed. + // does it break bulk image importing? ZIP? SVG? there are a few flows that are untested! + if ($config->get_bool(UploadConfig::MIME_CHECK_ENABLED) == true) { + $allowed_mimes = $config->get_array(UploadConfig::ALLOWED_MIME_STRINGS); + if (!MimeType::matches_array($event->mime, $allowed_mimes)) { + throw new UploadException("MIME type not supported: " . $event->mime); + } + } + if ($config->get_bool(TranscodeConfig::UPLOAD) == true) { if ($event->mime === MimeType::GIF&&MimeType::is_animated_gif($event->tmpname)) { return; diff --git a/ext/upload/config.php b/ext/upload/config.php index 8f4b5124..313b0536 100644 --- a/ext/upload/config.php +++ b/ext/upload/config.php @@ -11,4 +11,6 @@ class UploadConfig public const MIN_FREE_SPACE = "upload_min_free_space"; public const TLSOURCE = "upload_tlsource"; public const TRANSLOAD_ENGINE = "transload_engine"; + public const MIME_CHECK_ENABLED = "mime_check_enabled"; + public const ALLOWED_MIME_STRINGS = "allowed_mime_strings"; } diff --git a/ext/upload/main.php b/ext/upload/main.php index 8ebc2f2d..d02a1f55 100644 --- a/ext/upload/main.php +++ b/ext/upload/main.php @@ -98,6 +98,12 @@ class Upload extends Extension } } } + + $config->set_default_bool(UploadConfig::MIME_CHECK_ENABLED, false); + $config->set_default_array( + UploadConfig::ALLOWED_MIME_STRINGS, + DataHandlerExtension::get_all_supported_mimes() + ); } public function onSetupBuilding(SetupBuildingEvent $event) @@ -119,8 +125,21 @@ class Upload extends Extension $sb->add_label("PHP Limit = " . ini_get('upload_max_filesize') . ""); $sb->add_choice_option(UploadConfig::TRANSLOAD_ENGINE, $tes, "
Transload: "); $sb->add_bool_option(UploadConfig::TLSOURCE, "
Use transloaded URL as source if none is provided: "); + + $sb->start_table(); + $sb->add_bool_option(UploadConfig::MIME_CHECK_ENABLED, "Enable upload MIME checks", true); + $sb->add_multichoice_option(UploadConfig::ALLOWED_MIME_STRINGS, $this->get_mime_options(), "Allowed MIME uploads", true); + $sb->end_table(); } + private function get_mime_options(): array + { + $output = []; + foreach (DataHandlerExtension::get_all_supported_mimes() as $mime) { + $output[MimeMap::get_name_for_mime($mime)] = $mime; + } + return $output; + } public function onPageNavBuilding(PageNavBuildingEvent $event) {