diff options
| -rw-r--r-- | app/controllers/admin/banner.php | 17 | ||||
| -rw-r--r-- | app/controllers/admin/login_style.php | 10 | ||||
| -rw-r--r-- | lib/classes/Avatar.class.php | 2 | ||||
| -rw-r--r-- | lib/classes/JsonApi/Routes/StockImages/StockImagesUpload.php | 9 | ||||
| -rw-r--r-- | lib/classes/Services/ImageValidator.php | 51 |
5 files changed, 75 insertions, 14 deletions
diff --git a/app/controllers/admin/banner.php b/app/controllers/admin/banner.php index 5199bbc..e41eab6 100644 --- a/app/controllers/admin/banner.php +++ b/app/controllers/admin/banner.php @@ -264,17 +264,16 @@ class Admin_BannerController extends AuthenticatedController } //Dateiendung bestimmen - $dot = mb_strrpos($img_name, '.'); - if ($dot) { - $l = mb_strlen($img_name) - $dot; - $ext = mb_strtolower(mb_substr($img_name, $dot + 1, $l)); - } + $ext = pathinfo($img_name, PATHINFO_EXTENSION); + $ext = strtolower($ext); //passende Endung ? - if (!in_array($ext, words('gif jpeg jpg png'))) { - $errors[] = sprintf(_('Der Dateityp der Bilddatei ist falsch (%s).<br>' - .'Es sind nur die Dateiendungen .gif, .png und .jpg erlaubt!') - , htmlReady($ext)); + if (!app(\Studip\Services\ImageValidator::class)->validateName($img_name)) { + $errors[] = sprintf( + _('Der Dateityp der Bilddatei ist falsch (%s).<br>' + .'Es sind nur die Dateiendungen .gif, .png, .jpg und .webp erlaubt!'), + htmlReady($ext) + ); return false; } diff --git a/app/controllers/admin/login_style.php b/app/controllers/admin/login_style.php index 35cd7d8..74cc259 100644 --- a/app/controllers/admin/login_style.php +++ b/app/controllers/admin/login_style.php @@ -65,18 +65,22 @@ class Admin_LoginStyleController extends AuthenticatedController public function add_pic_action() { CSRFProtection::verifyRequest(); + + $image_validator = app(\Studip\Services\ImageValidator::class); + $success = 0; foreach ($_FILES['pictures']['name'] as $index => $filename) { if ($_FILES['pictures']['error'][$index] !== UPLOAD_ERR_OK) { continue; } - $extension = pathinfo($filename, PATHINFO_EXTENSION); - $extension = strtolower($extension); - if (!in_array($extension, ['gif', 'jpeg', 'jpg', 'png'])) { + if (!$image_validator->validateName($filename)) { continue; } + $extension = pathinfo($filename, PATHINFO_EXTENSION); + $extension = strtolower($extension); + $entry = new LoginBackground(); $entry->filename = $filename; $entry->desktop = Request::int('desktop', 0); diff --git a/lib/classes/Avatar.class.php b/lib/classes/Avatar.class.php index 959523f..7178e1a 100644 --- a/lib/classes/Avatar.class.php +++ b/lib/classes/Avatar.class.php @@ -367,7 +367,7 @@ class Avatar $ext = mb_strtolower($pathinfo['extension']); // passende Endung ? - if (!in_array($ext, words('jpg jpeg gif png webp'))) { + if (!app(\Studip\Services\ImageValidator::class)->validateName($_FILES[$userfile]['name'])) { throw new Exception(sprintf( _('Der Dateityp der Bilddatei ist falsch (%s). Es sind nur die Dateiendungen .gif, .png, .jpeg, .jpg oder .webp erlaubt!'), $ext diff --git a/lib/classes/JsonApi/Routes/StockImages/StockImagesUpload.php b/lib/classes/JsonApi/Routes/StockImages/StockImagesUpload.php index b05b370..b09c3eb 100644 --- a/lib/classes/JsonApi/Routes/StockImages/StockImagesUpload.php +++ b/lib/classes/JsonApi/Routes/StockImages/StockImagesUpload.php @@ -9,6 +9,7 @@ use JsonApi\NonJsonApiController; use Psr\Http\Message\ResponseInterface as Response; use Psr\Http\Message\ServerRequestInterface as Request; use Slim\Psr7\UploadedFile; +use Studip\Services\ImageValidator; use Studip\StockImages\Scaler; use Studip\StockImages\PaletteCreator; @@ -115,8 +116,14 @@ class StockImagesUpload extends NonJsonApiController */ private function validate(UploadedFile $file) { + $validator = $this->container->get(ImageValidator::class); + $mimeType = $file->getClientMediaType(); - if (!in_array($mimeType, ['image/gif', 'image/jpeg', 'image/png', 'image/webp'])) { + $fileName = $file->getClientFilename(); + if ( + !$validator->validateMimeType($mimeType) + || !$validator->validateName($fileName) + ) { return 'Unsupported media type.'; } } diff --git a/lib/classes/Services/ImageValidator.php b/lib/classes/Services/ImageValidator.php new file mode 100644 index 0000000..c26377c --- /dev/null +++ b/lib/classes/Services/ImageValidator.php @@ -0,0 +1,51 @@ +<?php +namespace Studip\Services; + +final class ImageValidator +{ + public const VALID_EXTENSIONS = [ + 'gif', + 'jpeg', 'jpg', + 'png', + 'webp', + ]; + + public const VALID_MIMETYPES = [ + 'image/gif', + 'image/jpeg', + 'image/png', + 'image/webp', + ]; + + public function validate(string $filename): bool + { + return $this->validateName($filename) + && $this->validateMimeType(get_mime_type($filename)) + && $this->validateContents($filename); + } + + public function validateMimeType(string $mime_type): bool + { + return str_starts_with($mime_type, 'image/') + && in_array($mime_type, self::VALID_MIMETYPES); + } + + public function validateName(string $filename): bool + { + $extension = pathinfo($filename, PATHINFO_EXTENSION); + $extension = strtolower($extension); + return in_array($extension, self::VALID_EXTENSIONS); + } + + public function validateContents(string $filename): bool + { + $check = imagecreatefromstring(file_get_contents($filename)); + if ($check === false) { + return false; + } + + imagedestroy($check); + + return true; + } +} |
