diff options
Diffstat (limited to 'vendor/blueimp/jquery-file-upload/server')
5 files changed, 150 insertions, 96 deletions
diff --git a/vendor/blueimp/jquery-file-upload/server/php/.dockerignore b/vendor/blueimp/jquery-file-upload/server/php/.dockerignore new file mode 100644 index 000000000..6f0168844 --- /dev/null +++ b/vendor/blueimp/jquery-file-upload/server/php/.dockerignore @@ -0,0 +1,2 @@ +* +!php.ini diff --git a/vendor/blueimp/jquery-file-upload/server/php/Dockerfile b/vendor/blueimp/jquery-file-upload/server/php/Dockerfile index 8633fee74..7f271b581 100644 --- a/vendor/blueimp/jquery-file-upload/server/php/Dockerfile +++ b/vendor/blueimp/jquery-file-upload/server/php/Dockerfile @@ -1,4 +1,4 @@ -FROM php:7-apache +FROM php:7.4-apache # Enable the Apache Headers module: RUN ln -s /etc/apache2/mods-available/headers.load \ @@ -11,28 +11,34 @@ RUN ln -s /etc/apache2/mods-available/rewrite.load \ # Install GD, Imagick and ImageMagick as image conversion options: RUN DEBIAN_FRONTEND=noninteractive \ apt-get update && apt-get install -y --no-install-recommends \ - libpng-dev \ - libjpeg-dev \ - libmagickwand-dev \ - imagemagick \ + libpng-dev \ + libjpeg-dev \ + libmagickwand-dev \ + imagemagick \ && pecl install \ - imagick \ + imagick \ && docker-php-ext-enable \ - imagick \ + imagick \ && docker-php-ext-configure \ - gd --with-jpeg-dir=/usr/include/ \ + gd --with-jpeg=/usr/include/ \ && docker-php-ext-install \ - gd \ + gd \ # Uninstall obsolete packages: && apt-get autoremove -y \ - libpng-dev \ - libjpeg-dev \ - libmagickwand-dev \ + libpng-dev \ + libjpeg-dev \ + libmagickwand-dev \ # Remove obsolete files: && apt-get clean \ && rm -rf \ - /tmp/* \ - /usr/share/doc/* \ - /var/cache/* \ - /var/lib/apt/lists/* \ - /var/tmp/* + /tmp/* \ + /usr/share/doc/* \ + /var/cache/* \ + /var/lib/apt/lists/* \ + /var/tmp/* + +# Use the default development configuration: +RUN mv "$PHP_INI_DIR/php.ini-development" "$PHP_INI_DIR/php.ini" + +# Add a custom configuration file: +COPY php.ini "$PHP_INI_DIR/conf.d/" diff --git a/vendor/blueimp/jquery-file-upload/server/php/UploadHandler.php b/vendor/blueimp/jquery-file-upload/server/php/UploadHandler.php index bc6f3a249..856e81b11 100644 --- a/vendor/blueimp/jquery-file-upload/server/php/UploadHandler.php +++ b/vendor/blueimp/jquery-file-upload/server/php/UploadHandler.php @@ -30,6 +30,7 @@ class UploadHandler 'min_file_size' => 'File is too small', 'accept_file_types' => 'Filetype not allowed', 'max_number_of_files' => 'Maximum number of files exceeded', + 'invalid_file_type' => 'Invalid file type', 'max_width' => 'Image exceeds maximum width', 'min_width' => 'Image requires a minimum width', 'max_height' => 'Image exceeds maximum height', @@ -38,9 +39,9 @@ class UploadHandler 'image_resize' => 'Failed to resize image' ); - const IMAGETYPE_GIF = 1; - const IMAGETYPE_JPEG = 2; - const IMAGETYPE_PNG = 3; + const IMAGETYPE_GIF = 'image/gif'; + const IMAGETYPE_JPEG = 'image/jpeg'; + const IMAGETYPE_PNG = 'image/png'; protected $image_objects = array(); protected $response = array(); @@ -393,7 +394,53 @@ class UploadHandler return $this->fix_integer_overflow($val); } - protected function validate($uploaded_file, $file, $error, $index) { + protected function validate_image_file($uploaded_file, $file, $error, $index) { + if ($this->imagetype($uploaded_file) !== $this->get_file_type($file->name)) { + $file->error = $this->get_error_message('invalid_file_type'); + return false; + } + $max_width = @$this->options['max_width']; + $max_height = @$this->options['max_height']; + $min_width = @$this->options['min_width']; + $min_height = @$this->options['min_height']; + if ($max_width || $max_height || $min_width || $min_height) { + list($img_width, $img_height) = $this->get_image_size($uploaded_file); + // If we are auto rotating the image by default, do the checks on + // the correct orientation + if ( + @$this->options['image_versions']['']['auto_orient'] && + function_exists('exif_read_data') && + ($exif = @exif_read_data($uploaded_file)) && + (((int) @$exif['Orientation']) >= 5) + ) { + $tmp = $img_width; + $img_width = $img_height; + $img_height = $tmp; + unset($tmp); + } + if (!empty($img_width) && !empty($img_height)) { + if ($max_width && $img_width > $max_width) { + $file->error = $this->get_error_message('max_width'); + return false; + } + if ($max_height && $img_height > $max_height) { + $file->error = $this->get_error_message('max_height'); + return false; + } + if ($min_width && $img_width < $min_width) { + $file->error = $this->get_error_message('min_width'); + return false; + } + if ($min_height && $img_height < $min_height) { + $file->error = $this->get_error_message('min_height'); + return false; + } + } + } + return true; + } + + protected function validate($uploaded_file, $file, $error, $index, $content_range) { if ($error) { $file->error = $this->get_error_message($error); return false; @@ -434,44 +481,8 @@ class UploadHandler $file->error = $this->get_error_message('max_number_of_files'); return false; } - $max_width = @$this->options['max_width']; - $max_height = @$this->options['max_height']; - $min_width = @$this->options['min_width']; - $min_height = @$this->options['min_height']; - if (($max_width || $max_height || $min_width || $min_height) - && $this->is_valid_image_file($uploaded_file)) { - list($img_width, $img_height) = $this->get_image_size($uploaded_file); - // If we are auto rotating the image by default, do the checks on - // the correct orientation - if ( - @$this->options['image_versions']['']['auto_orient'] && - function_exists('exif_read_data') && - ($exif = @exif_read_data($uploaded_file)) && - (((int) @$exif['Orientation']) >= 5) - ) { - $tmp = $img_width; - $img_width = $img_height; - $img_height = $tmp; - unset($tmp); - } - } - if (!empty($img_width) && !empty($img_height)) { - if ($max_width && $img_width > $max_width) { - $file->error = $this->get_error_message('max_width'); - return false; - } - if ($max_height && $img_height > $max_height) { - $file->error = $this->get_error_message('max_height'); - return false; - } - if ($min_width && $img_width < $min_width) { - $file->error = $this->get_error_message('min_width'); - return false; - } - if ($min_height && $img_height < $min_height) { - $file->error = $this->get_error_message('min_height'); - return false; - } + if (!$content_range && $this->has_image_file_extension($file->name)) { + return $this->validate_image_file($uploaded_file, $file, $error, $index); } return true; } @@ -497,7 +508,7 @@ class UploadHandler $name = $this->upcount_name($name); } // Keep an existing filename if this is part of a chunked upload: - $uploaded_bytes = $this->fix_integer_overflow((int)$content_range[1]); + $uploaded_bytes = $this->fix_integer_overflow((int)@$content_range[1]); while (is_file($this->get_upload_path($name))) { if ($uploaded_bytes === $this->get_file_size( $this->get_upload_path($name))) { @@ -508,6 +519,17 @@ class UploadHandler return $name; } + protected function get_valid_image_extensions($file_path) { + switch ($this->imagetype($file_path)) { + case self::IMAGETYPE_JPEG: + return array('jpg', 'jpeg'); + case self::IMAGETYPE_PNG: + return array('png'); + case self::IMAGETYPE_GIF: + return array('gif'); + } + } + protected function fix_file_extension($file_path, $name, $size, $type, $error, $index, $content_range) { // Add missing file extension for known image types: @@ -516,17 +538,7 @@ class UploadHandler $name .= '.'.$matches[1]; } if ($this->options['correct_image_extensions']) { - switch ($this->imagetype($file_path)) { - case self::IMAGETYPE_JPEG: - $extensions = array('jpg', 'jpeg'); - break; - case self::IMAGETYPE_PNG: - $extensions = array('png'); - break; - case self::IMAGETYPE_GIF: - $extensions = array('gif'); - break; - } + $extensions = $this->get_valid_image_extensions($file_path); // Adjust incorrect image file extensions: if (!empty($extensions)) { $parts = explode('.', $name); @@ -1094,12 +1106,13 @@ class UploadHandler } protected function is_valid_image_file($file_path) { - if (!preg_match('/\.(gif|jpe?g|png)$/i', $file_path)) { - return false; - } return !!$this->imagetype($file_path); } + protected function has_image_file_extension($file_path) { + return !!preg_match('/\.(gif|jpe?g|png)$/i', $file_path); + } + protected function handle_image_file($file_path, $file) { $failed_versions = array(); foreach ($this->options['image_versions'] as $version => $options) { @@ -1131,7 +1144,7 @@ class UploadHandler $index, $content_range); $file->size = $this->fix_integer_overflow((int)$size); $file->type = $type; - if ($this->validate($uploaded_file, $file, $error, $index)) { + if ($this->validate($uploaded_file, $file, $error, $index, $content_range)) { $this->handle_form_data($file, $index); $upload_dir = $this->get_upload_path(); if (!is_dir($upload_dir)) { @@ -1162,8 +1175,12 @@ class UploadHandler $file_size = $this->get_file_size($file_path, $append_file); if ($file_size === $file->size) { $file->url = $this->get_download_url($file->name); - if ($this->is_valid_image_file($file_path)) { - $this->handle_image_file($file_path, $file); + if ($this->has_image_file_extension($file->name)) { + if ($content_range && !$this->validate_image_file($file_path, $file, $error, $index)) { + unlink($file_path); + } else { + $this->handle_image_file($file_path, $file); + } } } else { $file->size = $file_size; @@ -1249,11 +1266,11 @@ class UploadHandler switch (strtolower(pathinfo($file_path, PATHINFO_EXTENSION))) { case 'jpeg': case 'jpg': - return 'image/jpeg'; + return self::IMAGETYPE_JPEG; case 'png': - return 'image/png'; + return self::IMAGETYPE_PNG; case 'gif': - return 'image/gif'; + return self::IMAGETYPE_GIF; default: return ''; } @@ -1394,7 +1411,7 @@ class UploadHandler $content_range_header = $this->get_server_var('HTTP_CONTENT_RANGE'); $content_range = $content_range_header ? preg_split('/[^0-9]+/', $content_range_header) : null; - $size = $content_range ? $content_range[3] : null; + $size = @$content_range[3]; $files = array(); if ($upload) { if (is_array($upload['tmp_name'])) { diff --git a/vendor/blueimp/jquery-file-upload/server/php/files/.htaccess b/vendor/blueimp/jquery-file-upload/server/php/files/.htaccess index 6f454afb9..be8cb1916 100644 --- a/vendor/blueimp/jquery-file-upload/server/php/files/.htaccess +++ b/vendor/blueimp/jquery-file-upload/server/php/files/.htaccess @@ -1,25 +1,49 @@ -# To enable the Headers module, execute the following command and reload Apache: +# If you have not done so already, please first read SECURITY.md in the root +# directory of this project or online: +# https://github.com/blueimp/jQuery-File-Upload/blob/master/SECURITY.md +# +# The settings in this file require Apache to support configuration overrides +# in .htaccess files, which is disabled by default since Apache v2.3.9 and needs +# to be enabled for the directives in this file to have any effect, see also: +# https://httpd.apache.org/docs/current/mod/core.html#allowoverride +# +# If you have full control over the web server, it is preferrable to define the +# settings in the Apache configuration (e.g. /etc/apache2/apache2.conf) itself. +# +# Some of the directives require the Apache Headers module. If it is not +# already enabled, please execute the following command and reload Apache: # sudo a2enmod headers +# +# Please note that the order of directives across configuration files matters, +# see also: +# https://httpd.apache.org/docs/current/sections.html#merging -# The following directives prevent the execution of script files -# in the context of the website. -# They also force the content-type application/octet-stream and -# force browsers to display a download dialog for non-image files. -SetHandler default-handler -ForceType application/octet-stream -Header set Content-Disposition attachment +# The following directive matches all files and forces them to be handled as +# static content, which prevents the server from parsing and executing files +# that are associated with a dynamic runtime, e.g. PHP files. +# It also forces their Content-Type header to "application/octet-stream" and +# adds a "Content-Disposition: attachment" header to force a download dialog, +# which prevents browsers from interpreting files in the context of the +# web server, e.g. HTML files containing JavaScript. +# Lastly it also prevents browsers from MIME-sniffing the Content-Type, +# preventing them from interpreting a file as a different Content-Type than +# the one sent by the webserver. +<FilesMatch ".*"> + SetHandler default-handler + ForceType application/octet-stream + Header set Content-Disposition attachment + Header set X-Content-Type-Options nosniff +</FilesMatch> -# The following unsets the forced type and Content-Disposition headers -# for known image files: -<FilesMatch "(?i)\.(gif|jpe?g|png)$"> +# The following directive matches known image files and unsets the forced +# Content-Type so they can be served with their original mime type. +# It also unsets the Content-Disposition header to allow displaying them +# inline in the browser. +<FilesMatch ".+\.(?i:(gif|jpe?g|png))$"> ForceType none Header unset Content-Disposition </FilesMatch> -# The following directive prevents browsers from MIME-sniffing the content-type. -# This is an important complement to the ForceType directive above: -Header set X-Content-Type-Options nosniff - # Uncomment the following lines to prevent unauthorized download of files: #AuthName "Authorization required" #AuthType Basic diff --git a/vendor/blueimp/jquery-file-upload/server/php/php.ini b/vendor/blueimp/jquery-file-upload/server/php/php.ini new file mode 100644 index 000000000..c04b5c653 --- /dev/null +++ b/vendor/blueimp/jquery-file-upload/server/php/php.ini @@ -0,0 +1,5 @@ +max_execution_time = 300 +memory_limit = 500M +post_max_size = 4G +upload_max_filesize = 4G +max_file_uploads = 50 |