From 55d64d8af80c227323f858dac396c7f6957d1790 Mon Sep 17 00:00:00 2001 From: philayres Date: Thu, 19 Jul 2018 13:04:19 +0100 Subject: [PATCH 001/195] Add beforechunksend handler --- js/jquery.fileupload-angular.js | 1 + js/jquery.fileupload.js | 2 ++ 2 files changed, 3 insertions(+) diff --git a/js/jquery.fileupload-angular.js b/js/jquery.fileupload-angular.js index 1c2055276..1d059ab01 100644 --- a/js/jquery.fileupload-angular.js +++ b/js/jquery.fileupload-angular.js @@ -315,6 +315,7 @@ 'fileuploadpaste', 'fileuploaddrop', 'fileuploaddragover', + 'fileuploadbeforechunksend', 'fileuploadchunksend', 'fileuploadchunkdone', 'fileuploadchunkfail', diff --git a/js/jquery.fileupload.js b/js/jquery.fileupload.js index 629f57a25..aa2effe5c 100644 --- a/js/jquery.fileupload.js +++ b/js/jquery.fileupload.js @@ -766,6 +766,8 @@ // Expose the chunk bytes position range: o.contentRange = 'bytes ' + ub + '-' + (ub + o.chunkSize - 1) + '/' + fs; + // Trigger beforechunksend to allow form data to be updated for this chunk + that._trigger('beforechunksend', null, o); // Process the upload data (the blob and potential form data): that._initXHRData(o); // Add progress listeners for this chunk upload: From 8335871e2a21e0eda57791343dea09edda8f6ede Mon Sep 17 00:00:00 2001 From: philayres Date: Thu, 19 Jul 2018 13:21:45 +0100 Subject: [PATCH 002/195] Provide chunkbeforesend event handler --- js/jquery.fileupload-angular.js | 2 +- js/jquery.fileupload.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/js/jquery.fileupload-angular.js b/js/jquery.fileupload-angular.js index 1d059ab01..185907d36 100644 --- a/js/jquery.fileupload-angular.js +++ b/js/jquery.fileupload-angular.js @@ -315,7 +315,7 @@ 'fileuploadpaste', 'fileuploaddrop', 'fileuploaddragover', - 'fileuploadbeforechunksend', + 'fileuploadchunkbeforesend', 'fileuploadchunksend', 'fileuploadchunkdone', 'fileuploadchunkfail', diff --git a/js/jquery.fileupload.js b/js/jquery.fileupload.js index aa2effe5c..096c29b92 100644 --- a/js/jquery.fileupload.js +++ b/js/jquery.fileupload.js @@ -766,8 +766,8 @@ // Expose the chunk bytes position range: o.contentRange = 'bytes ' + ub + '-' + (ub + o.chunkSize - 1) + '/' + fs; - // Trigger beforechunksend to allow form data to be updated for this chunk - that._trigger('beforechunksend', null, o); + // Trigger chunkbeforesend to allow form data to be updated for this chunk + that._trigger('chunkbeforesend', null, o); // Process the upload data (the blob and potential form data): that._initXHRData(o); // Add progress listeners for this chunk upload: From aeb47e51c67df8a504b7726595576c1c66b5dc2f Mon Sep 17 00:00:00 2001 From: Sebastian Tschan Date: Sat, 13 Oct 2018 16:27:32 +0200 Subject: [PATCH 003/195] SECURITY FIX: Only allow image file types by default. This prevents remote code execution in Apache servers version 2.3.9+ with the default configuration (AllowOverride None). Since Apache version 2.3.9, .htaccess support is disabled by default: https://httpd.apache.org/docs/current/mod/core.html#allowoverride Without the configuration in the .htaccess file, allowing uploads of all file types allows remote code execution. Thanks to @lcashdol for reporting the vulnerability (Closes #3514). --- server/php/index.php | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/server/php/index.php b/server/php/index.php index 6caabb710..c1dbcaf66 100644 --- a/server/php/index.php +++ b/server/php/index.php @@ -12,4 +12,17 @@ error_reporting(E_ALL | E_STRICT); require('UploadHandler.php'); -$upload_handler = new UploadHandler(); +$upload_handler = new UploadHandler(array( + + // SECURITY NOTICE: + // Only change the accept_file_types setting after making sure that any + // allowed file types cannot be executed by the webserver in the files + // directory (e.g. PHP scripts), nor executed by the browser when downloaded + // (e.g. HTML files with embedded JavaScript code). + // e.g. in Apache, make sure the provided .htaccess file is present in the + // files directory and .htaccess support has been enabled: + // https://httpd.apache.org/docs/current/howto/htaccess.html + + // By default, only allow file uploads with image file extensions: + 'accept_file_types' => '/\.(gif|jpe?g|png)$/i' +)); From e3687064b91955fa4558cdb9bd307f7361e7e236 Mon Sep 17 00:00:00 2001 From: Sebastian Tschan Date: Sat, 13 Oct 2018 16:28:06 +0200 Subject: [PATCH 004/195] 9.22.1 --- bower.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bower.json b/bower.json index c1152560a..f31b6b61e 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "blueimp-file-upload", - "version": "9.22.0", + "version": "9.22.1", "title": "jQuery File Upload", "description": "File Upload widget with multiple file selection, drag&drop support, progress bar, validation and preview images.", "keywords": [ diff --git a/package.json b/package.json index 465458069..ebaf51037 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "blueimp-file-upload", - "version": "9.22.0", + "version": "9.22.1", "title": "jQuery File Upload", "description": "File Upload widget with multiple file selection, drag&drop support, progress bar, validation and preview images, audio and video for jQuery. Supports cross-domain, chunked and resumable file uploads. Works with any server-side platform (Google App Engine, PHP, Python, Ruby on Rails, Java, etc.) that supports standard HTML form file uploads.", "keywords": [ From 3dd18f9318d6fd9b7d26beac10fa79c2db883e1f Mon Sep 17 00:00:00 2001 From: Sebastian Tschan Date: Sun, 14 Oct 2018 18:49:27 +0200 Subject: [PATCH 005/195] Explicit deinitialization of progress listeners. This addresses a memory leak with Microsoft Edge. Thanks @butonic for the report, investigation and fix. Closes #3508 --- js/jquery.fileupload.js | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/js/jquery.fileupload.js b/js/jquery.fileupload.js index 629f57a25..8f00b0dc0 100644 --- a/js/jquery.fileupload.js +++ b/js/jquery.fileupload.js @@ -434,6 +434,13 @@ } }, + _deinitProgressListener: function (options) { + var xhr = options.xhr ? options.xhr() : $.ajaxSettings.xhr(); + if (xhr.upload) { + $(xhr.upload).unbind('progress'); + } + }, + _isInstanceOf: function (type, obj) { // Cross-frame instanceof check return Object.prototype.toString.call(obj) === '[object ' + type + ']'; @@ -812,6 +819,9 @@ o.context, [jqXHR, textStatus, errorThrown] ); + }) + .always(function () { + that._deinitProgressListener(o); }); }; this._enhancePromise(promise); @@ -913,6 +923,7 @@ }).fail(function (jqXHR, textStatus, errorThrown) { that._onFail(jqXHR, textStatus, errorThrown, options); }).always(function (jqXHRorResult, textStatus, jqXHRorError) { + that._deinitProgressListener(options); that._onAlways( jqXHRorResult, textStatus, From 965e300db3cf5218e0d4bebb3f4dd229bc24e865 Mon Sep 17 00:00:00 2001 From: Sebastian Tschan Date: Sun, 14 Oct 2018 18:50:41 +0200 Subject: [PATCH 006/195] 9.22.2 --- bower.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bower.json b/bower.json index f31b6b61e..9ebf2e77f 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "blueimp-file-upload", - "version": "9.22.1", + "version": "9.22.2", "title": "jQuery File Upload", "description": "File Upload widget with multiple file selection, drag&drop support, progress bar, validation and preview images.", "keywords": [ diff --git a/package.json b/package.json index ebaf51037..aa45d7746 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "blueimp-file-upload", - "version": "9.22.1", + "version": "9.22.2", "title": "jQuery File Upload", "description": "File Upload widget with multiple file selection, drag&drop support, progress bar, validation and preview images, audio and video for jQuery. Supports cross-domain, chunked and resumable file uploads. Works with any server-side platform (Google App Engine, PHP, Python, Ruby on Rails, Java, etc.) that supports standard HTML form file uploads.", "keywords": [ From 6d8e0792443ac1d99b68c1b8485d60c593cc4b4e Mon Sep 17 00:00:00 2001 From: Sebastian Tschan Date: Sun, 14 Oct 2018 18:59:03 +0200 Subject: [PATCH 007/195] Add chunkbeforesend to callback list. --- js/jquery.fileupload.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/js/jquery.fileupload.js b/js/jquery.fileupload.js index 978f89f09..700f9013c 100644 --- a/js/jquery.fileupload.js +++ b/js/jquery.fileupload.js @@ -261,6 +261,9 @@ // Callback for dragover events of the dropZone(s): // dragover: function (e) {}, // .bind('fileuploaddragover', func); + // Callback before the start of each chunk upload request (before form data initialization): + // chunkbeforesend: function (e, data) {}, // .bind('fileuploadchunkbeforesend', func); + // Callback for the start of each chunk upload request: // chunksend: function (e, data) {}, // .bind('fileuploadchunksend', func); From 0ab8ffb49c23640c730881056e26c17c76b95491 Mon Sep 17 00:00:00 2001 From: Sebastian Tschan Date: Sun, 14 Oct 2018 18:59:17 +0200 Subject: [PATCH 008/195] 9.23.0 --- bower.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bower.json b/bower.json index 9ebf2e77f..4f4cd8adb 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "blueimp-file-upload", - "version": "9.22.2", + "version": "9.23.0", "title": "jQuery File Upload", "description": "File Upload widget with multiple file selection, drag&drop support, progress bar, validation and preview images.", "keywords": [ diff --git a/package.json b/package.json index aa45d7746..4801d7913 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "blueimp-file-upload", - "version": "9.22.2", + "version": "9.23.0", "title": "jQuery File Upload", "description": "File Upload widget with multiple file selection, drag&drop support, progress bar, validation and preview images, audio and video for jQuery. Supports cross-domain, chunked and resumable file uploads. Works with any server-side platform (Google App Engine, PHP, Python, Ruby on Rails, Java, etc.) that supports standard HTML form file uploads.", "keywords": [ From eec742cf7dedf31e7659577da7f2e307f1498ead Mon Sep 17 00:00:00 2001 From: Sebastian Tschan Date: Sun, 14 Oct 2018 20:03:55 +0200 Subject: [PATCH 009/195] Update for compatibility with the gcloud CLI. --- server/gae-go/app.yaml | 2 -- server/gae-go/{app => }/main.go | 0 server/gae-python/app.yaml | 2 -- 3 files changed, 4 deletions(-) rename server/gae-go/{app => }/main.go (100%) diff --git a/server/gae-go/app.yaml b/server/gae-go/app.yaml index 2d09daa56..b5ac1a2e1 100644 --- a/server/gae-go/app.yaml +++ b/server/gae-go/app.yaml @@ -1,5 +1,3 @@ -application: jquery-file-upload -version: 2 runtime: go api_version: go1 diff --git a/server/gae-go/app/main.go b/server/gae-go/main.go similarity index 100% rename from server/gae-go/app/main.go rename to server/gae-go/main.go diff --git a/server/gae-python/app.yaml b/server/gae-python/app.yaml index 764449b74..0c49462fa 100644 --- a/server/gae-python/app.yaml +++ b/server/gae-python/app.yaml @@ -1,5 +1,3 @@ -application: jquery-file-upload -version: 1 runtime: python27 api_version: 1 threadsafe: true From 5d7a84ec86c7e83e02cf1f017c4693482996ed13 Mon Sep 17 00:00:00 2001 From: Alan Hogan Date: Sun, 21 Oct 2018 20:22:12 -0700 Subject: [PATCH 010/195] Alert visitors to security problem A highly visible notice seems warranted. --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 76bdf89d5..dffe1655e 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,9 @@ # jQuery File Upload Plugin +## ⚠️ Versions Before 9.22.1 are Vulnerable + +A serious exploit, [CVE-2018-9206](https://nvd.nist.gov/vuln/detail/CVE-2018-9206), exists in versions released before October 2018. [[MISC](http://www.vapidlabs.com/advisory.php?v=204)] + ## Demo [Demo File Upload](https://blueimp.github.io/jQuery-File-Upload/) From d3f323ffb7a455e0c3c99292ef12ffefb63ef4c3 Mon Sep 17 00:00:00 2001 From: Sebastian Tschan Date: Mon, 22 Oct 2018 13:11:53 +0200 Subject: [PATCH 011/195] Add security guidelines and list of fixed vulnerabilities. --- README.md | 12 +++++- SECURITY.md | 93 ++++++++++++++++++++++++++++++++++++++++++++++ VULNERABILITIES.md | 42 +++++++++++++++++++++ 3 files changed, 145 insertions(+), 2 deletions(-) create mode 100644 SECURITY.md create mode 100644 VULNERABILITIES.md diff --git a/README.md b/README.md index dffe1655e..1776c733e 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,13 @@ # jQuery File Upload Plugin -## ⚠️ Versions Before 9.22.1 are Vulnerable +## ⚠️ Security Notice +Security related releases: -A serious exploit, [CVE-2018-9206](https://nvd.nist.gov/vuln/detail/CVE-2018-9206), exists in versions released before October 2018. [[MISC](http://www.vapidlabs.com/advisory.php?v=204)] +* [v9.22.1](https://github.com/blueimp/jQuery-File-Upload/releases/tag/v9.22.1) Fixes a [Remote code execution vulnerability in the PHP component](VULNERABILITIES.md#remote-code-execution-vulnerability-in-the-php-component). +* v[9.10.1](https://github.com/blueimp/jQuery-File-Upload/releases/tag/9.10.1) Fixes an [Open redirect vulnerability in the GAE components](VULNERABILITIES.md#open-redirect-vulnerability-in-the-gae-components). +* Commit [4175032](https://github.com/blueimp/jQuery-File-Upload/commit/41750323a464e848856dc4c5c940663498beb74a) (*fixed in all tagged releases*) Fixes a [Cross-site scripting vulnerability in the Iframe Transport](VULNERABILITIES.md#cross-site-scripting-vulnerability-in-the-iframe-transport). + +Please read the [SECURITY](SECURITY.md) document for instructions on how to securely configure your Webserver for file uploads. ## Demo [Demo File Upload](https://blueimp.github.io/jQuery-File-Upload/) @@ -12,6 +17,9 @@ File Upload widget with multiple file selection, drag&drop support, progress Supports cross-domain, chunked and resumable file uploads and client-side image resizing. Works with any server-side platform (PHP, Python, Ruby on Rails, Java, Node.js, Go etc.) that supports standard HTML form file uploads. ## Setup +⚠️ **Notice:** +Please read the [Security recommendations](SECURITY.md) before setting up the project. + * [How to setup the plugin on your website](https://github.com/blueimp/jQuery-File-Upload/wiki/Setup) * [How to use only the basic plugin (minimal setup guide).](https://github.com/blueimp/jQuery-File-Upload/wiki/Basic-plugin) diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 000000000..cdafd5e89 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,93 @@ +# File Upload Security +For an in-depth understanding of the potential security risks of providing file uploads and possible mitigations, please refer to the [OWASP - Unrestricted File Upload](https://www.owasp.org/index.php/Unrestricted_File_Upload) documentation. + +To securely setup the project to serve uploaded files, please refer to the sample [Secure file upload serving configurations](#secure-file-upload-serving-configurations). + +By default, all sample upload handlers allow only upload of image files, which mitigates some attack vectors, but should not be relied on as the only protection. + +Please also have a look at the [list of fixed vulnerabilities](VULNERABILITIES.md) in jQuery File Upload. + +## Mitigations against file upload risks + +### Prevent code execution on the server +To prevent execution of scripts or binaries on server-side, the upload directory must be configured to not execute files in the upload directory (e.g. `server/php/files` as the default for the PHP upload handler) and only treat uploaded files as static content. + +The recommended way to do this is to configure the upload directory path to point outside of the web application root. +Then the Webserver can be configured to serve files from the upload directory with their default static files handler only. + +Limiting file uploads to a whitelist of safe file types (e.g. image files) also mitigates this issue, but should not be the only protection. + +### Prevent code execution in the browser +To prevent execution of scripts on client-side, the following headers must +be sent when delivering generic uploaded files to the client: + +``` +Content-Type: application/octet-stream +X-Content-Type-Options: nosniff +``` + +The `Content-Type: application/octet-stream` header instructs browsers to display a download dialog instead of parsing it and possibly executing script content e.g. in HTML files. + +The `X-Content-Type-Options: nosniff` header prevents browsers to try to detect the file mime type despite the given content-type header. + +For known safe files, the content-type header can be adjusted using a **whitelist**, e.g. sending `Content-Type: image/png` for PNG files. + +### Prevent distribution of malware +To prevent attackers from uploading and distributing malware (e.g. computer viruses), it is recommended to limit file uploads only to a whitelist of safe file types. + +Please note that the detection of file types in the sample file upload handlers is based on the file extension and not the actual file content. This makes it still possible for attackers to upload malware by giving their files an image file extension, but should prevent automatic execution on client computers when opening those files. + +It does not protect at all from exploiting vulnerabilities in image display programs, nor from users renaming file extensions to inadvertently execute the contained malicious code. + +## Secure file upload serving configurations + +### Apache config +Add the following directive to the Apache config, replacing the directory path with the absolute path to the upload directory: + +```ApacheConf + + # To enable the Headers module, execute the following command and reload Apache: + # sudo a2enmod headers + + # 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 unsets the forced type and Content-Disposition headers + # for known image files: + + ForceType none + Header unset Content-Disposition + + + # 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 + +``` + +### NGINX config +Add the following directive to the NGINX config, replacing the directory path with the absolute path to the upload directory: + +```Nginx +location ^~ /path/to/project/server/php/files { + root html; + default_type application/octet-stream; + types { + image/gif gif; + image/jpeg jpg; + image/png png; + } + add_header X-Content-Type-Options 'nosniff'; + if ($request_filename ~ /(((?!\.(jpg)|(png)|(gif)$)[^/])+$)) { + add_header Content-Disposition 'attachment; filename="$1"'; + # Add X-Content-Type-Options again, as using add_header in a new context + # dismisses all previous add_header calls: + add_header X-Content-Type-Options 'nosniff'; + } +} +``` diff --git a/VULNERABILITIES.md b/VULNERABILITIES.md new file mode 100644 index 000000000..8659a157a --- /dev/null +++ b/VULNERABILITIES.md @@ -0,0 +1,42 @@ +# ⚠️ List of fixed vulnerabilities + +## Remote code execution vulnerability in the PHP component +> Fixed: 2018-10-13 + +The sample [PHP upload handler](server/php/index.php) before [v9.22.1](https://github.com/blueimp/jQuery-File-Upload/releases/tag/v9.22.1) allowed to upload all file types by default. +This opens up a remote code execution vulnerability, unless the server is configured to not execute (PHP) files in the upload directory (`server/php/files`). + +The provided [.htaccess](server/php/files/.htaccess) file includes instructions for Apache to disable script execution, however [.htaccess support](https://httpd.apache.org/docs/current/howto/htaccess.html) is disabled by default since Apache `v2.3.9` via [AllowOverride Directive](https://httpd.apache.org/docs/current/mod/core.html#allowoverride). + +**You are affected if you:** +1. Uploaded jQuery File Upload `version < 9.22.1` on a Webserver that executes all PHP scripts in the project directory, e.g. Apache with `mod_php` enabled. +2. Did not actively configure your Webserver to not execute files in the upload directory (`server/php/files`). +3. Are running Apache `v2.3.9+` with the default `AllowOverride` Directive set to `None` or another Webserver with no `.htaccess` support. + +**How to fix it:** +1. Upgrade to the latest version of jQuery File Upload or limit file uploads to image file types - see [sample PHP code](server/php/index.php). +2. Configure your Webserver to not execute files in the upload directory, e.g. with the [sample Apache configuration](SECURITY.md#apache-config) + +**Further information:** +* Commit containing the security fix: [aeb47e5](https://github.com/blueimp/jQuery-File-Upload/commit/aeb47e51c67df8a504b7726595576c1c66b5dc2f) +* [Full disclosure post on Hacker News](https://news.ycombinator.com/item?id=18267309). +* [CVE-2018-9206](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-9206) +* [OWASP - Unrestricted File Upload](https://www.owasp.org/index.php/Unrestricted_File_Upload) + +## Open redirect vulnerability in the GAE components +> Fixed: 2015-06-12 + +The sample Google App Engine upload handlers before v[9.10.1](https://github.com/blueimp/jQuery-File-Upload/releases/tag/9.10.1) accepted any URL as redirect target, making it possible to use the Webserver's domain for phishing attacks. + +**Further information:** +* Commit containing the security fix: [f74d2a8](https://github.com/blueimp/jQuery-File-Upload/commit/f74d2a8c3e3b1e8e336678d2899facd5bcdb589f) +* [OWASP - Unvalidated Redirects and Forwards Cheat Sheet](https://www.owasp.org/index.php/Unvalidated_Redirects_and_Forwards_Cheat_Sheet) + +## Cross-site scripting vulnerability in the Iframe Transport +> Fixed: 2012-08-09 + +The [redirect page](cors/result.html) for the [Iframe Transport](js/jquery.iframe-transport.js) before commit [4175032](https://github.com/blueimp/jQuery-File-Upload/commit/41750323a464e848856dc4c5c940663498beb74a) (*fixed in all tagged releases*) allowed executing arbitrary JavaScript in the context of the Webserver. + +**Further information:** +* Commit containing the security fix: [4175032](https://github.com/blueimp/jQuery-File-Upload/commit/41750323a464e848856dc4c5c940663498beb74a) +* [OWASP - Cross-site Scripting (XSS)](https://www.owasp.org/index.php/Cross-site_Scripting_(XSS)) From 3e828564324cf5aea2b0d0c7f3a7a17996cb9a9a Mon Sep 17 00:00:00 2001 From: Sebastian Tschan Date: Mon, 22 Oct 2018 13:27:52 +0200 Subject: [PATCH 012/195] 9.24.0 --- bower.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bower.json b/bower.json index 4f4cd8adb..59e7a398e 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "blueimp-file-upload", - "version": "9.23.0", + "version": "9.24.0", "title": "jQuery File Upload", "description": "File Upload widget with multiple file selection, drag&drop support, progress bar, validation and preview images.", "keywords": [ diff --git a/package.json b/package.json index 4801d7913..79155a973 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "blueimp-file-upload", - "version": "9.23.0", + "version": "9.24.0", "title": "jQuery File Upload", "description": "File Upload widget with multiple file selection, drag&drop support, progress bar, validation and preview images, audio and video for jQuery. Supports cross-domain, chunked and resumable file uploads. Works with any server-side platform (Google App Engine, PHP, Python, Ruby on Rails, Java, etc.) that supports standard HTML form file uploads.", "keywords": [ From ad4aefd96e4056deab6fea2690f0d8cf56bb2d7d Mon Sep 17 00:00:00 2001 From: Sebastian Tschan Date: Tue, 23 Oct 2018 12:50:28 +0200 Subject: [PATCH 013/195] SECURITY FIX: Only allow image file types by default. This moves the image file types limit in the library file. This also adds a default setting to replace dots in filenames. --- server/php/UploadHandler.php | 31 +++++++++++++++++++++++++++++-- server/php/index.php | 15 +-------------- 2 files changed, 30 insertions(+), 16 deletions(-) diff --git a/server/php/UploadHandler.php b/server/php/UploadHandler.php index 285d046aa..f218f3f62 100755 --- a/server/php/UploadHandler.php +++ b/server/php/UploadHandler.php @@ -89,8 +89,25 @@ public function __construct($options = null, $initialize = true, $error_messages 'readfile_chunk_size' => 10 * 1024 * 1024, // 10 MiB // Defines which files can be displayed inline when downloaded: 'inline_file_types' => '/\.(gif|jpe?g|png)$/i', - // Defines which files (based on their names) are accepted for upload: - 'accept_file_types' => '/.+$/i', + // Defines which files (based on their names) are accepted for upload. + // By default, only allows file uploads with image file extensions. + // Only change this setting after making sure that any allowed file + // types cannot be executed by the webserver in the files directory, + // e.g. PHP scripts, nor executed by the browser when downloaded, + // e.g. HTML files with embedded JavaScript code. + // Please also read the SECURITY.md document in this repository. + 'accept_file_types' => '/\.(gif|jpe?g|png)$/i', + // Replaces dots in filenames with the given string. + // Can be disabled by setting it to false or an empty string. + // Note that this is a security feature for servers that support + // multiple file extensions, e.g. the Apache AddHandler Directive: + // https://httpd.apache.org/docs/current/mod/mod_mime.html#addhandler + // Before disabling it, make sure that files uploaded with multiple + // extensions cannot be executed by the webserver, e.g. + // "example.php.png" with embedded PHP code, nor executed by the + // browser when downloaded, e.g. "example.html.gif" with embedded + // JavaScript code. + 'replace_dots_in_filenames' => '-', // The php.ini settings upload_max_filesize and post_max_size // take precedence over the following max_file_size setting: 'max_file_size' => null, @@ -527,6 +544,16 @@ protected function trim_file_name($file_path, $name, $size, $type, $error, // into different directories or replacing hidden system files. // Also remove control characters and spaces (\x00..\x20) around the filename: $name = trim($this->basename(stripslashes($name)), ".\x00..\x20"); + // Replace dots in filenames to avoid security issues with servers + // that interpret multiple file extensions, e.g. "example.php.png": + $replacement = $this->options['replace_dots_in_filenames']; + if (!empty($replacement)) { + $parts = explode('.', $name); + if (count($parts) > 2) { + $ext = array_pop($parts); + $name = implode($replacement, $parts).'.'.$ext; + } + } // Use a timestamp for empty filenames: if (!$name) { $name = str_replace('.', '-', microtime(true)); diff --git a/server/php/index.php b/server/php/index.php index c1dbcaf66..6caabb710 100644 --- a/server/php/index.php +++ b/server/php/index.php @@ -12,17 +12,4 @@ error_reporting(E_ALL | E_STRICT); require('UploadHandler.php'); -$upload_handler = new UploadHandler(array( - - // SECURITY NOTICE: - // Only change the accept_file_types setting after making sure that any - // allowed file types cannot be executed by the webserver in the files - // directory (e.g. PHP scripts), nor executed by the browser when downloaded - // (e.g. HTML files with embedded JavaScript code). - // e.g. in Apache, make sure the provided .htaccess file is present in the - // files directory and .htaccess support has been enabled: - // https://httpd.apache.org/docs/current/howto/htaccess.html - - // By default, only allow file uploads with image file extensions: - 'accept_file_types' => '/\.(gif|jpe?g|png)$/i' -)); +$upload_handler = new UploadHandler(); From a513d514c390f8b4c149ff1720ee27054791f80d Mon Sep 17 00:00:00 2001 From: Sebastian Tschan Date: Tue, 23 Oct 2018 13:18:36 +0200 Subject: [PATCH 014/195] Update VULNERABILITIES documentation. --- README.md | 2 +- VULNERABILITIES.md | 19 ++++++++++++++----- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 1776c733e..f8a2b532a 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ ## ⚠️ Security Notice Security related releases: -* [v9.22.1](https://github.com/blueimp/jQuery-File-Upload/releases/tag/v9.22.1) Fixes a [Remote code execution vulnerability in the PHP component](VULNERABILITIES.md#remote-code-execution-vulnerability-in-the-php-component). +* [v9.24.1](https://github.com/blueimp/jQuery-File-Upload/releases/tag/v9.24.1) Fixes a [Remote code execution vulnerability in the PHP component](VULNERABILITIES.md#remote-code-execution-vulnerability-in-the-php-component). * v[9.10.1](https://github.com/blueimp/jQuery-File-Upload/releases/tag/9.10.1) Fixes an [Open redirect vulnerability in the GAE components](VULNERABILITIES.md#open-redirect-vulnerability-in-the-gae-components). * Commit [4175032](https://github.com/blueimp/jQuery-File-Upload/commit/41750323a464e848856dc4c5c940663498beb74a) (*fixed in all tagged releases*) Fixes a [Cross-site scripting vulnerability in the Iframe Transport](VULNERABILITIES.md#cross-site-scripting-vulnerability-in-the-iframe-transport). diff --git a/VULNERABILITIES.md b/VULNERABILITIES.md index 8659a157a..256e8f992 100644 --- a/VULNERABILITIES.md +++ b/VULNERABILITIES.md @@ -1,24 +1,33 @@ # ⚠️ List of fixed vulnerabilities ## Remote code execution vulnerability in the PHP component -> Fixed: 2018-10-13 +> Fixed: 2018-10-23 -The sample [PHP upload handler](server/php/index.php) before [v9.22.1](https://github.com/blueimp/jQuery-File-Upload/releases/tag/v9.22.1) allowed to upload all file types by default. +The sample [PHP upload handler](server/php/UploadHandler.php) before [v9.24.1](https://github.com/blueimp/jQuery-File-Upload/releases/tag/v9.24.1) allowed to upload all file types by default. This opens up a remote code execution vulnerability, unless the server is configured to not execute (PHP) files in the upload directory (`server/php/files`). The provided [.htaccess](server/php/files/.htaccess) file includes instructions for Apache to disable script execution, however [.htaccess support](https://httpd.apache.org/docs/current/howto/htaccess.html) is disabled by default since Apache `v2.3.9` via [AllowOverride Directive](https://httpd.apache.org/docs/current/mod/core.html#allowoverride). **You are affected if you:** -1. Uploaded jQuery File Upload `version < 9.22.1` on a Webserver that executes all PHP scripts in the project directory, e.g. Apache with `mod_php` enabled. +1. A) Uploaded jQuery File Upload < `v9.24.1` on a Webserver that executes files with `.php` as part of the file extension (e.g. "example.php.png"), e.g. Apache with `mod_php` enabled and the following directive (*not a recommended configuration*): + ```ApacheConf + AddHandler php5-script .php + ``` + B) Uploaded jQuery File Upload < `v9.22.1` on a Webserver that executes files with the file extension `.php`, e.g. Apache with `mod_php` enabled and the following directive: + ```ApacheConf + + SetHandler application/x-httpd-php + + ``` 2. Did not actively configure your Webserver to not execute files in the upload directory (`server/php/files`). 3. Are running Apache `v2.3.9+` with the default `AllowOverride` Directive set to `None` or another Webserver with no `.htaccess` support. **How to fix it:** -1. Upgrade to the latest version of jQuery File Upload or limit file uploads to image file types - see [sample PHP code](server/php/index.php). +1. Upgrade to the latest version of jQuery File Upload. 2. Configure your Webserver to not execute files in the upload directory, e.g. with the [sample Apache configuration](SECURITY.md#apache-config) **Further information:** -* Commit containing the security fix: [aeb47e5](https://github.com/blueimp/jQuery-File-Upload/commit/aeb47e51c67df8a504b7726595576c1c66b5dc2f) +* Commits containing the security fix: [aeb47e5](https://github.com/blueimp/jQuery-File-Upload/commit/aeb47e51c67df8a504b7726595576c1c66b5dc2f), [3e82856](https://github.com/blueimp/jQuery-File-Upload/commit/3e828564324cf5aea2b0d0c7f3a7a17996cb9a9a) * [Full disclosure post on Hacker News](https://news.ycombinator.com/item?id=18267309). * [CVE-2018-9206](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-9206) * [OWASP - Unrestricted File Upload](https://www.owasp.org/index.php/Unrestricted_File_Upload) From d17e60162b89810ba4096cac1549b8636b289a59 Mon Sep 17 00:00:00 2001 From: Sebastian Tschan Date: Tue, 23 Oct 2018 13:18:50 +0200 Subject: [PATCH 015/195] 9.24.1 --- bower.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bower.json b/bower.json index 59e7a398e..6ed453c24 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "blueimp-file-upload", - "version": "9.24.0", + "version": "9.24.1", "title": "jQuery File Upload", "description": "File Upload widget with multiple file selection, drag&drop support, progress bar, validation and preview images.", "keywords": [ diff --git a/package.json b/package.json index 79155a973..6356810aa 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "blueimp-file-upload", - "version": "9.24.0", + "version": "9.24.1", "title": "jQuery File Upload", "description": "File Upload widget with multiple file selection, drag&drop support, progress bar, validation and preview images, audio and video for jQuery. Supports cross-domain, chunked and resumable file uploads. Works with any server-side platform (Google App Engine, PHP, Python, Ruby on Rails, Java, etc.) that supports standard HTML form file uploads.", "keywords": [ From 286f25ce9646b7f699110ef877e346930b1b9cad Mon Sep 17 00:00:00 2001 From: Sebastian Tschan Date: Tue, 23 Oct 2018 13:22:36 +0200 Subject: [PATCH 016/195] Fix commit ID. --- VULNERABILITIES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VULNERABILITIES.md b/VULNERABILITIES.md index 256e8f992..f1fe261be 100644 --- a/VULNERABILITIES.md +++ b/VULNERABILITIES.md @@ -27,7 +27,7 @@ The provided [.htaccess](server/php/files/.htaccess) file includes instructions 2. Configure your Webserver to not execute files in the upload directory, e.g. with the [sample Apache configuration](SECURITY.md#apache-config) **Further information:** -* Commits containing the security fix: [aeb47e5](https://github.com/blueimp/jQuery-File-Upload/commit/aeb47e51c67df8a504b7726595576c1c66b5dc2f), [3e82856](https://github.com/blueimp/jQuery-File-Upload/commit/3e828564324cf5aea2b0d0c7f3a7a17996cb9a9a) +* Commits containing the security fix: [aeb47e5](https://github.com/blueimp/jQuery-File-Upload/commit/aeb47e51c67df8a504b7726595576c1c66b5dc2f), [ad4aefd](https://github.com/blueimp/jQuery-File-Upload/commit/ad4aefd96e4056deab6fea2690f0d8cf56bb2d7d) * [Full disclosure post on Hacker News](https://news.ycombinator.com/item?id=18267309). * [CVE-2018-9206](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-9206) * [OWASP - Unrestricted File Upload](https://www.owasp.org/index.php/Unrestricted_File_Upload) From 6fb12e3b5dbe58fb5c167f6e1fc3cea79ac44b9c Mon Sep 17 00:00:00 2001 From: Sebastian Tschan Date: Wed, 24 Oct 2018 12:49:13 +0200 Subject: [PATCH 017/195] Add info on purpose of this project. Add note to test security of configurations. --- SECURITY.md | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/SECURITY.md b/SECURITY.md index cdafd5e89..afa1da13c 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -5,7 +5,19 @@ To securely setup the project to serve uploaded files, please refer to the sampl By default, all sample upload handlers allow only upload of image files, which mitigates some attack vectors, but should not be relied on as the only protection. -Please also have a look at the [list of fixed vulnerabilities](VULNERABILITIES.md) in jQuery File Upload. +Please also have a look at the [list of fixed vulnerabilities](VULNERABILITIES.md) in jQuery File Upload, which relates mostly to the sample server-side upload handlers and how they have been configured. + +## Purpose of this project +Please note that this project is not a complete file management product, but foremost a client-side file upload library for [jQuery](https://jquery.com/). +The server-side sample upload handlers are just examples to demonstrate the client-side file upload functionality. + +To make this very clear, there is **no user authentication** by default: +* **everyone can upload files** +* **everyone can delete uploaded files** + +In some cases this can be acceptable, but for most projects you will want to extend the sample upload handlers to integrate user authentication, or implement your own. + +It is also up to you to configure your Webserver to securely serve the uploaded files, e.g. using the [sample server configurations](#secure-file-upload-serving-configurations). ## Mitigations against file upload risks @@ -40,6 +52,12 @@ Please note that the detection of file types in the sample file upload handlers It does not protect at all from exploiting vulnerabilities in image display programs, nor from users renaming file extensions to inadvertently execute the contained malicious code. ## Secure file upload serving configurations +The following configurations serve uploaded files as static files with the proper headers as [mitigation against file upload risks](#mitigations-against-file-upload-risks). +Please do not simply copy&paste these configurations, but make sure you understand what they are doing and that you have implemented them correctly. + +> Always test your own setup and make sure that it is secure! + +e.g. try uploading PHP scripts (as "example.php", "example.php.png" and "example.png") to see if they get executed by your Webserver. ### Apache config Add the following directive to the Apache config, replacing the directory path with the absolute path to the upload directory: From 56ebf0f4589c2b9116876f8f0ff26fe875d181e1 Mon Sep 17 00:00:00 2001 From: Sebastian Tschan Date: Wed, 24 Oct 2018 12:49:28 +0200 Subject: [PATCH 018/195] 9.25.0 --- bower.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bower.json b/bower.json index 6ed453c24..9e31381a8 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "blueimp-file-upload", - "version": "9.24.1", + "version": "9.25.0", "title": "jQuery File Upload", "description": "File Upload widget with multiple file selection, drag&drop support, progress bar, validation and preview images.", "keywords": [ diff --git a/package.json b/package.json index 6356810aa..6f5bfef40 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "blueimp-file-upload", - "version": "9.24.1", + "version": "9.25.0", "title": "jQuery File Upload", "description": "File Upload widget with multiple file selection, drag&drop support, progress bar, validation and preview images, audio and video for jQuery. Supports cross-domain, chunked and resumable file uploads. Works with any server-side platform (Google App Engine, PHP, Python, Ruby on Rails, Java, etc.) that supports standard HTML form file uploads.", "keywords": [ From fe44d34be43be32c6b8d507932f318dababb25dd Mon Sep 17 00:00:00 2001 From: Sebastian Tschan Date: Fri, 26 Oct 2018 00:32:14 +0200 Subject: [PATCH 019/195] SECURITY: Verify file signatures before image processing. This mitigates potential vulnerabilities in ImageMagick when handling input files other than GIF/JPEG/PNG. However this does not prevent all potential vulnerabilities with ImageMagick. It is therefore recommended to disable all non-required ImageMagick coders via policy.xml. See also: https://imagetragick.com/ https://www.kb.cert.org/vuls/id/332928 https://cve.mitre.org/cgi-bin/cvekey.cgi?keyword=imagemagick --- server/php/UploadHandler.php | 51 ++++++++++++++++++++++-------------- 1 file changed, 31 insertions(+), 20 deletions(-) diff --git a/server/php/UploadHandler.php b/server/php/UploadHandler.php index f218f3f62..e44004395 100755 --- a/server/php/UploadHandler.php +++ b/server/php/UploadHandler.php @@ -38,6 +38,10 @@ class UploadHandler 'image_resize' => 'Failed to resize image' ); + protected const IMAGETYPE_GIF = 1; + protected const IMAGETYPE_JPEG = 2; + protected const IMAGETYPE_PNG = 3; + protected $image_objects = array(); public function __construct($options = null, $initialize = true, $error_messages = null) { @@ -114,9 +118,7 @@ public function __construct($options = null, $initialize = true, $error_messages 'min_file_size' => 1, // The maximum number of files for the upload directory: 'max_number_of_files' => null, - // Defines which files are handled as image files: - 'image_file_types' => '/\.(gif|jpe?g|png)$/i', - // Use exif_imagetype on all files to correct file extensions: + // Reads first file bytes to identify and correct file extensions: 'correct_image_extensions' => false, // Image resolution restrictions: 'max_width' => null, @@ -163,7 +165,7 @@ public function __construct($options = null, $initialize = true, $error_messages 'max_width' => 800, 'max_height' => 600 ), - */ + */ 'thumbnail' => array( // Uncomment the following to use a defined directory for the thumbnails // instead of a subdirectory based on the version identifier. @@ -433,9 +435,8 @@ protected function validate($uploaded_file, $file, $error, $index) { $min_width = @$this->options['min_width']; $min_height = @$this->options['min_height']; if (($max_width || $max_height || $min_width || $min_height) - && preg_match($this->options['image_file_types'], $file->name)) { + && $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 ( @@ -449,7 +450,6 @@ function_exists('exif_read_data') && $img_height = $tmp; unset($tmp); } - } if (!empty($img_width)) { if ($max_width && $img_width > $max_width) { @@ -511,16 +511,15 @@ protected function fix_file_extension($file_path, $name, $size, $type, $error, preg_match('/^image\/(gif|jpe?g|png)/', $type, $matches)) { $name .= '.'.$matches[1]; } - if ($this->options['correct_image_extensions'] && - function_exists('exif_imagetype')) { - switch (@exif_imagetype($file_path)){ - case IMAGETYPE_JPEG: + if ($this->options['correct_image_extensions']) { + switch ($this->imagetype($file_path)) { + case self::IMAGETYPE_JPEG: $extensions = array('jpg', 'jpeg'); break; - case IMAGETYPE_PNG: + case self::IMAGETYPE_PNG: $extensions = array('png'); break; - case IMAGETYPE_GIF: + case self::IMAGETYPE_GIF: $extensions = array('gif'); break; } @@ -1063,15 +1062,27 @@ protected function destroy_image_object($file_path) { } } - protected function is_valid_image_file($file_path) { - if (!preg_match($this->options['image_file_types'], $file_path)) { - return false; + protected function imagetype($file_path) { + $fp = fopen($file_path, 'r'); + $data = fread($fp, 4); + fclose($fp); + // GIF: 47 49 46 + if (substr($data, 0, 3) === 'GIF') { + return self::IMAGETYPE_GIF; } - if (function_exists('exif_imagetype')) { - return @exif_imagetype($file_path); + // JPG: FF D8 + if (bin2hex(substr($data, 0, 2)) === 'ffd8') { + return self::IMAGETYPE_JPEG; } - $image_info = $this->get_image_size($file_path); - return $image_info && $image_info[0] && $image_info[1]; + // PNG: 89 50 4E 47 + if (bin2hex(@$data[0]).substr($data, 1, 4) === '89PNG') { + return self::IMAGETYPE_PNG; + } + return false; + } + + protected function is_valid_image_file($file_path) { + return !!$this->imagetype($file_path); } protected function handle_image_file($file_path, $file) { From 26bcba1f5e541163389aa955583bc4bc0f450421 Mon Sep 17 00:00:00 2001 From: Sebastian Tschan Date: Fri, 26 Oct 2018 01:21:31 +0200 Subject: [PATCH 020/195] Add info on mitigations of image processing vulnerabilities. --- README.md | 20 +++++++++----------- SECURITY.md | 22 ++++++++++++++++++++++ VULNERABILITIES.md | 20 +++++++++++++++++--- 3 files changed, 48 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index f8a2b532a..d2f104d5c 100644 --- a/README.md +++ b/README.md @@ -1,25 +1,23 @@ # jQuery File Upload Plugin +## Description +File Upload widget with multiple file selection, drag&drop support, progress bars, validation and preview images, audio and video for jQuery. +Supports cross-domain, chunked and resumable file uploads and client-side image resizing. Works with any server-side platform (PHP, Python, Ruby on Rails, Java, Node.js, Go etc.) that supports standard HTML form file uploads. + +## Demo +[Demo File Upload](https://blueimp.github.io/jQuery-File-Upload/) + ## ⚠️ Security Notice Security related releases: +* [v9.25.1](https://github.com/blueimp/jQuery-File-Upload/releases/tag/v9.25.1) Mitigates some [Potential vulnerabilities with PHP+ImageMagick](VULNERABILITIES.md#potential-vulnerabilities-with-php+imagemagick). * [v9.24.1](https://github.com/blueimp/jQuery-File-Upload/releases/tag/v9.24.1) Fixes a [Remote code execution vulnerability in the PHP component](VULNERABILITIES.md#remote-code-execution-vulnerability-in-the-php-component). * v[9.10.1](https://github.com/blueimp/jQuery-File-Upload/releases/tag/9.10.1) Fixes an [Open redirect vulnerability in the GAE components](VULNERABILITIES.md#open-redirect-vulnerability-in-the-gae-components). * Commit [4175032](https://github.com/blueimp/jQuery-File-Upload/commit/41750323a464e848856dc4c5c940663498beb74a) (*fixed in all tagged releases*) Fixes a [Cross-site scripting vulnerability in the Iframe Transport](VULNERABILITIES.md#cross-site-scripting-vulnerability-in-the-iframe-transport). Please read the [SECURITY](SECURITY.md) document for instructions on how to securely configure your Webserver for file uploads. -## Demo -[Demo File Upload](https://blueimp.github.io/jQuery-File-Upload/) - -## Description -File Upload widget with multiple file selection, drag&drop support, progress bars, validation and preview images, audio and video for jQuery. -Supports cross-domain, chunked and resumable file uploads and client-side image resizing. Works with any server-side platform (PHP, Python, Ruby on Rails, Java, Node.js, Go etc.) that supports standard HTML form file uploads. - ## Setup -⚠️ **Notice:** -Please read the [Security recommendations](SECURITY.md) before setting up the project. - * [How to setup the plugin on your website](https://github.com/blueimp/jQuery-File-Upload/wiki/Setup) * [How to use only the basic plugin (minimal setup guide).](https://github.com/blueimp/jQuery-File-Upload/wiki/Basic-plugin) @@ -27,7 +25,7 @@ Please read the [Security recommendations](SECURITY.md) before setting up the pr * **Multiple file upload:** Allows to select multiple files at once and upload them simultaneously. * **Drag & Drop support:** - Allows to upload files by dragging them from your desktop or filemanager and dropping them on your browser window. + Allows to upload files by dragging them from your desktop or file manager and dropping them on your browser window. * **Upload progress bar:** Shows a progress bar indicating the upload progress for individual files and for all uploads combined. * **Cancelable uploads:** diff --git a/SECURITY.md b/SECURITY.md index afa1da13c..db58f7dd7 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -3,6 +3,8 @@ For an in-depth understanding of the potential security risks of providing file To securely setup the project to serve uploaded files, please refer to the sample [Secure file upload serving configurations](#secure-file-upload-serving-configurations). +To mitigate potential vulnerabilities in image processing libraries, please refer to the [Secure image processing configurations](#secure-image-processing-configurations). + By default, all sample upload handlers allow only upload of image files, which mitigates some attack vectors, but should not be relied on as the only protection. Please also have a look at the [list of fixed vulnerabilities](VULNERABILITIES.md) in jQuery File Upload, which relates mostly to the sample server-side upload handlers and how they have been configured. @@ -109,3 +111,23 @@ location ^~ /path/to/project/server/php/files { } } ``` + +## Secure image processing configurations +The following configuration mitigates [potential image processing vulnerabilities with ImageMagick](VULNERABILITIES.md#potential-vulnerabilities-with-php+imagemagick) by limiting the attack vectors to a small subset of image types (`GIF/JPEG/PNG`). + +Please also consider using alternative, safer image processing libraries like [libvips](https://github.com/libvips/libvips) or [imageflow](https://github.com/imazen/imageflow). + +## ImageMagick config +It is recommended to disable all non-required ImageMagick coders via [policy.xml](https://wiki.debian.org/imagemagick/security). +To do so, locate the ImageMagick `policy.xml` configuration file and add the following policies: + +```xml + + + + + + + + +``` diff --git a/VULNERABILITIES.md b/VULNERABILITIES.md index f1fe261be..1561a1401 100644 --- a/VULNERABILITIES.md +++ b/VULNERABILITIES.md @@ -1,7 +1,21 @@ # ⚠️ List of fixed vulnerabilities +## Potential vulnerabilities with PHP+ImageMagick +> Mitigated: 2018-10-25 (GMT) + +The sample [PHP upload handler](server/php/UploadHandler.php) before [v9.25.1](https://github.com/blueimp/jQuery-File-Upload/releases/tag/v9.25.1) did not validate file signatures before invoking [ImageMagick](https://www.imagemagick.org/) (via [Imagick](http://php.net/manual/en/book.imagick.php)). +Verifying those [magic bytes](https://en.wikipedia.org/wiki/List_of_file_signatures) mitigates potential vulnerabilities when handling input files other than `GIF/JPEG/PNG`. + +Please also configure ImageMagick to only enable the coders required for `GIF/JPEG/PNG` processing, e.g. with the sample [ImageMagick config](SECURITY.md#imagemagick-config). + +**Further information:** +* Commit containing the mitigation: [fe44d34](https://github.com/blueimp/jQuery-File-Upload/commit/fe44d34be43be32c6b8d507932f318dababb25dd) +* [ImageTragick](https://imagetragick.com/) +* [CERT Vulnerability Note VU#332928](https://www.kb.cert.org/vuls/id/332928) +* [ImageMagick CVE entries](https://cve.mitre.org/cgi-bin/cvekey.cgi?keyword=imagemagick) + ## Remote code execution vulnerability in the PHP component -> Fixed: 2018-10-23 +> Fixed: 2018-10-23 (GMT) The sample [PHP upload handler](server/php/UploadHandler.php) before [v9.24.1](https://github.com/blueimp/jQuery-File-Upload/releases/tag/v9.24.1) allowed to upload all file types by default. This opens up a remote code execution vulnerability, unless the server is configured to not execute (PHP) files in the upload directory (`server/php/files`). @@ -33,7 +47,7 @@ The provided [.htaccess](server/php/files/.htaccess) file includes instructions * [OWASP - Unrestricted File Upload](https://www.owasp.org/index.php/Unrestricted_File_Upload) ## Open redirect vulnerability in the GAE components -> Fixed: 2015-06-12 +> Fixed: 2015-06-12 (GMT) The sample Google App Engine upload handlers before v[9.10.1](https://github.com/blueimp/jQuery-File-Upload/releases/tag/9.10.1) accepted any URL as redirect target, making it possible to use the Webserver's domain for phishing attacks. @@ -42,7 +56,7 @@ The sample Google App Engine upload handlers before v[9.10.1](https://github.com * [OWASP - Unvalidated Redirects and Forwards Cheat Sheet](https://www.owasp.org/index.php/Unvalidated_Redirects_and_Forwards_Cheat_Sheet) ## Cross-site scripting vulnerability in the Iframe Transport -> Fixed: 2012-08-09 +> Fixed: 2012-08-09 (GMT) The [redirect page](cors/result.html) for the [Iframe Transport](js/jquery.iframe-transport.js) before commit [4175032](https://github.com/blueimp/jQuery-File-Upload/commit/41750323a464e848856dc4c5c940663498beb74a) (*fixed in all tagged releases*) allowed executing arbitrary JavaScript in the context of the Webserver. From 3750d3a10c40814e57edfb77d04857e8f3389c59 Mon Sep 17 00:00:00 2001 From: Sebastian Tschan Date: Fri, 26 Oct 2018 01:21:47 +0200 Subject: [PATCH 021/195] 9.25.1 --- bower.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bower.json b/bower.json index 9e31381a8..34594a32f 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "blueimp-file-upload", - "version": "9.25.0", + "version": "9.25.1", "title": "jQuery File Upload", "description": "File Upload widget with multiple file selection, drag&drop support, progress bar, validation and preview images.", "keywords": [ diff --git a/package.json b/package.json index 6f5bfef40..4b33a0362 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "blueimp-file-upload", - "version": "9.25.0", + "version": "9.25.1", "title": "jQuery File Upload", "description": "File Upload widget with multiple file selection, drag&drop support, progress bar, validation and preview images, audio and video for jQuery. Supports cross-domain, chunked and resumable file uploads. Works with any server-side platform (Google App Engine, PHP, Python, Ruby on Rails, Java, etc.) that supports standard HTML form file uploads.", "keywords": [ From a356654bef180821578b8cf971ca5d5c636670f3 Mon Sep 17 00:00:00 2001 From: Sebastian Tschan Date: Fri, 26 Oct 2018 01:25:32 +0200 Subject: [PATCH 022/195] Fix link anchor. --- README.md | 2 +- SECURITY.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index d2f104d5c..d9e16ed18 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ Supports cross-domain, chunked and resumable file uploads and client-side image ## ⚠️ Security Notice Security related releases: -* [v9.25.1](https://github.com/blueimp/jQuery-File-Upload/releases/tag/v9.25.1) Mitigates some [Potential vulnerabilities with PHP+ImageMagick](VULNERABILITIES.md#potential-vulnerabilities-with-php+imagemagick). +* [v9.25.1](https://github.com/blueimp/jQuery-File-Upload/releases/tag/v9.25.1) Mitigates some [Potential vulnerabilities with PHP+ImageMagick](VULNERABILITIES.md#potential-vulnerabilities-with-php-imagemagick). * [v9.24.1](https://github.com/blueimp/jQuery-File-Upload/releases/tag/v9.24.1) Fixes a [Remote code execution vulnerability in the PHP component](VULNERABILITIES.md#remote-code-execution-vulnerability-in-the-php-component). * v[9.10.1](https://github.com/blueimp/jQuery-File-Upload/releases/tag/9.10.1) Fixes an [Open redirect vulnerability in the GAE components](VULNERABILITIES.md#open-redirect-vulnerability-in-the-gae-components). * Commit [4175032](https://github.com/blueimp/jQuery-File-Upload/commit/41750323a464e848856dc4c5c940663498beb74a) (*fixed in all tagged releases*) Fixes a [Cross-site scripting vulnerability in the Iframe Transport](VULNERABILITIES.md#cross-site-scripting-vulnerability-in-the-iframe-transport). diff --git a/SECURITY.md b/SECURITY.md index db58f7dd7..86ffc163b 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -113,7 +113,7 @@ location ^~ /path/to/project/server/php/files { ``` ## Secure image processing configurations -The following configuration mitigates [potential image processing vulnerabilities with ImageMagick](VULNERABILITIES.md#potential-vulnerabilities-with-php+imagemagick) by limiting the attack vectors to a small subset of image types (`GIF/JPEG/PNG`). +The following configuration mitigates [potential image processing vulnerabilities with ImageMagick](VULNERABILITIES.md#potential-vulnerabilities-with-php-imagemagick) by limiting the attack vectors to a small subset of image types (`GIF/JPEG/PNG`). Please also consider using alternative, safer image processing libraries like [libvips](https://github.com/libvips/libvips) or [imageflow](https://github.com/imazen/imageflow). From 92921ef9f3cc67645aef275afd7eabde9f76dd90 Mon Sep 17 00:00:00 2001 From: edent Date: Wed, 31 Oct 2018 10:45:02 +0000 Subject: [PATCH 023/195] Add SRI to external JavaScript --- angularjs.html | 12 ++++++------ basic-plus.html | 8 ++++---- basic.html | 4 ++-- cors/postmessage.html | 2 +- index.html | 12 ++++++------ jquery-ui.html | 12 ++++++------ test/index.html | 10 +++++----- 7 files changed, 30 insertions(+), 30 deletions(-) diff --git a/angularjs.html b/angularjs.html index 2051bbf79..54ee0a10f 100644 --- a/angularjs.html +++ b/angularjs.html @@ -177,18 +177,18 @@

    - - + + - + - + - + - + diff --git a/basic-plus.html b/basic-plus.html index acee24843..acf715cc3 100644 --- a/basic-plus.html +++ b/basic-plus.html @@ -96,15 +96,15 @@

    Demo Notes

    - + - + - + - + diff --git a/basic.html b/basic.html index 232a24624..d67e8e919 100644 --- a/basic.html +++ b/basic.html @@ -96,7 +96,7 @@

    Demo Notes

    - + @@ -104,7 +104,7 @@

    Demo Notes

    - + + - + - + - + - + - + - + diff --git a/jquery-ui.html b/jquery-ui.html index 842dd4ca7..0bdaa3f59 100644 --- a/jquery-ui.html +++ b/jquery-ui.html @@ -201,16 +201,16 @@

    {% } %} - - + + - + - + - + - + diff --git a/test/index.html b/test/index.html index 0b5cf57b7..73eca84f8 100644 --- a/test/index.html +++ b/test/index.html @@ -145,11 +145,11 @@

    {% } %} - + - - - + + + - + From fa9ddd2a4c0e686f659ffd7476691303012ea8ee Mon Sep 17 00:00:00 2001 From: Sebastian Tschan Date: Thu, 1 Nov 2018 23:09:53 +0100 Subject: [PATCH 024/195] Add Subresource Integrity checksums to external CSS. --- angularjs.html | 4 ++-- basic-plus.html | 2 +- basic.html | 2 +- index.html | 4 ++-- jquery-ui.html | 2 +- test/index.html | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/angularjs.html b/angularjs.html index 54ee0a10f..f571bd187 100644 --- a/angularjs.html +++ b/angularjs.html @@ -22,11 +22,11 @@ - + - + diff --git a/basic-plus.html b/basic-plus.html index acf715cc3..e63aab41b 100644 --- a/basic-plus.html +++ b/basic-plus.html @@ -20,7 +20,7 @@ - + diff --git a/basic.html b/basic.html index d67e8e919..a9ef6273e 100644 --- a/basic.html +++ b/basic.html @@ -20,7 +20,7 @@ - + diff --git a/index.html b/index.html index cf449d60e..f0f396550 100644 --- a/index.html +++ b/index.html @@ -22,11 +22,11 @@ - + - + diff --git a/jquery-ui.html b/jquery-ui.html index 0bdaa3f59..bc17318a8 100644 --- a/jquery-ui.html +++ b/jquery-ui.html @@ -22,7 +22,7 @@ - + diff --git a/test/index.html b/test/index.html index 73eca84f8..fe5f44a34 100644 --- a/test/index.html +++ b/test/index.html @@ -20,7 +20,7 @@ jQuery File Upload Plugin Test - +

    jQuery File Upload Plugin Test

    From 10a66db5f3bf5ea69ea3d7751e02ad37c841dd62 Mon Sep 17 00:00:00 2001 From: Sebastian Tschan Date: Thu, 1 Nov 2018 23:10:05 +0100 Subject: [PATCH 025/195] 9.26.0 --- bower.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bower.json b/bower.json index 34594a32f..4569ae78c 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "blueimp-file-upload", - "version": "9.25.1", + "version": "9.26.0", "title": "jQuery File Upload", "description": "File Upload widget with multiple file selection, drag&drop support, progress bar, validation and preview images.", "keywords": [ diff --git a/package.json b/package.json index 4b33a0362..b76544548 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "blueimp-file-upload", - "version": "9.25.1", + "version": "9.26.0", "title": "jQuery File Upload", "description": "File Upload widget with multiple file selection, drag&drop support, progress bar, validation and preview images, audio and video for jQuery. Supports cross-domain, chunked and resumable file uploads. Works with any server-side platform (Google App Engine, PHP, Python, Ruby on Rails, Java, etc.) that supports standard HTML form file uploads.", "keywords": [ From 7a4bf4824b23bd3a23f5a8ebf35d471252d198b5 Mon Sep 17 00:00:00 2001 From: Silicon Forks Date: Tue, 6 Nov 2018 19:09:01 -0400 Subject: [PATCH 026/195] Remove "protected" visibility modifier from const This restores compatibility with PHP 5.6 and PHP 7.0. --- server/php/UploadHandler.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/server/php/UploadHandler.php b/server/php/UploadHandler.php index e44004395..492ba56cc 100755 --- a/server/php/UploadHandler.php +++ b/server/php/UploadHandler.php @@ -38,9 +38,9 @@ class UploadHandler 'image_resize' => 'Failed to resize image' ); - protected const IMAGETYPE_GIF = 1; - protected const IMAGETYPE_JPEG = 2; - protected const IMAGETYPE_PNG = 3; + const IMAGETYPE_GIF = 1; + const IMAGETYPE_JPEG = 2; + const IMAGETYPE_PNG = 3; protected $image_objects = array(); From ff55388c021057778c026f31b8184815d547c862 Mon Sep 17 00:00:00 2001 From: Sebastian Tschan Date: Wed, 7 Nov 2018 11:41:14 +0100 Subject: [PATCH 027/195] Catch image scaling exceptions. --- server/php/UploadHandler.php | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/server/php/UploadHandler.php b/server/php/UploadHandler.php index 492ba56cc..12ff5ec30 100755 --- a/server/php/UploadHandler.php +++ b/server/php/UploadHandler.php @@ -1047,13 +1047,18 @@ protected function get_image_size($file_path) { } protected function create_scaled_image($file_name, $version, $options) { - if ($this->options['image_library'] === 2) { - return $this->imagemagick_create_scaled_image($file_name, $version, $options); - } - if ($this->options['image_library'] && extension_loaded('imagick')) { - return $this->imagick_create_scaled_image($file_name, $version, $options); + try { + if ($this->options['image_library'] === 2) { + return $this->imagemagick_create_scaled_image($file_name, $version, $options); + } + if ($this->options['image_library'] && extension_loaded('imagick')) { + return $this->imagick_create_scaled_image($file_name, $version, $options); + } + return $this->gd_create_scaled_image($file_name, $version, $options); + } catch (\Exception $e) { + error_log($e->getMessage()); + return false; } - return $this->gd_create_scaled_image($file_name, $version, $options); } protected function destroy_image_object($file_path) { From 1da893f232434e5bcbb32f81f6d23a5b622b239e Mon Sep 17 00:00:00 2001 From: Sebastian Tschan Date: Wed, 7 Nov 2018 12:04:49 +0100 Subject: [PATCH 028/195] Use all 4 bytes to validate GIF headers. --- server/php/UploadHandler.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/php/UploadHandler.php b/server/php/UploadHandler.php index 12ff5ec30..2b03b8406 100755 --- a/server/php/UploadHandler.php +++ b/server/php/UploadHandler.php @@ -1071,8 +1071,8 @@ protected function imagetype($file_path) { $fp = fopen($file_path, 'r'); $data = fread($fp, 4); fclose($fp); - // GIF: 47 49 46 - if (substr($data, 0, 3) === 'GIF') { + // GIF: 47 49 46 38 + if ($data === 'GIF8') { return self::IMAGETYPE_GIF; } // JPG: FF D8 From fac6b5f5a72ede558ff60960f2c6c2943235bef7 Mon Sep 17 00:00:00 2001 From: Sebastian Tschan Date: Wed, 7 Nov 2018 12:18:33 +0100 Subject: [PATCH 029/195] Use the first 3 bytes to validate JPEG headers. --- server/php/UploadHandler.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/php/UploadHandler.php b/server/php/UploadHandler.php index 2b03b8406..459375f06 100755 --- a/server/php/UploadHandler.php +++ b/server/php/UploadHandler.php @@ -1075,8 +1075,8 @@ protected function imagetype($file_path) { if ($data === 'GIF8') { return self::IMAGETYPE_GIF; } - // JPG: FF D8 - if (bin2hex(substr($data, 0, 2)) === 'ffd8') { + // JPG: FF D8 FF + if (bin2hex(substr($data, 0, 3)) === 'ffd8ff') { return self::IMAGETYPE_JPEG; } // PNG: 89 50 4E 47 From b96fd5a53dfdb7081db1635934581697f8a8c97d Mon Sep 17 00:00:00 2001 From: Sebastian Tschan Date: Wed, 7 Nov 2018 12:20:14 +0100 Subject: [PATCH 030/195] Also validate image file names. --- server/php/UploadHandler.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/server/php/UploadHandler.php b/server/php/UploadHandler.php index 459375f06..5215e4c0f 100755 --- a/server/php/UploadHandler.php +++ b/server/php/UploadHandler.php @@ -1087,6 +1087,9 @@ protected function imagetype($file_path) { } 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); } From 44f0f4c4d688031dc793ae0c705217ea7e54f82a Mon Sep 17 00:00:00 2001 From: Sebastian Tschan Date: Wed, 7 Nov 2018 12:32:50 +0100 Subject: [PATCH 031/195] 9.27.0 --- bower.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bower.json b/bower.json index 4569ae78c..599dfc7ec 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "blueimp-file-upload", - "version": "9.26.0", + "version": "9.27.0", "title": "jQuery File Upload", "description": "File Upload widget with multiple file selection, drag&drop support, progress bar, validation and preview images.", "keywords": [ diff --git a/package.json b/package.json index b76544548..ee13d126a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "blueimp-file-upload", - "version": "9.26.0", + "version": "9.27.0", "title": "jQuery File Upload", "description": "File Upload widget with multiple file selection, drag&drop support, progress bar, validation and preview images, audio and video for jQuery. Supports cross-domain, chunked and resumable file uploads. Works with any server-side platform (Google App Engine, PHP, Python, Ruby on Rails, Java, etc.) that supports standard HTML form file uploads.", "keywords": [ From 23b3bb36f30d41819b43c023ed4e78284a388323 Mon Sep 17 00:00:00 2001 From: Sebastian Tschan Date: Mon, 12 Nov 2018 18:45:02 +0100 Subject: [PATCH 032/195] Remove SRI from non-versioned resources. --- angularjs.html | 8 ++++---- basic-plus.html | 4 ++-- index.html | 10 +++++----- jquery-ui.html | 8 ++++---- test/index.html | 6 +++--- 5 files changed, 18 insertions(+), 18 deletions(-) diff --git a/angularjs.html b/angularjs.html index f571bd187..e8b05e77f 100644 --- a/angularjs.html +++ b/angularjs.html @@ -26,7 +26,7 @@ - + @@ -182,13 +182,13 @@

    - + - + - + diff --git a/basic-plus.html b/basic-plus.html index e63aab41b..6d53acdc1 100644 --- a/basic-plus.html +++ b/basic-plus.html @@ -100,9 +100,9 @@

    Demo Notes

    - + - + diff --git a/index.html b/index.html index f0f396550..37e08a7cb 100644 --- a/index.html +++ b/index.html @@ -26,7 +26,7 @@ - + @@ -220,15 +220,15 @@

    - + - + - + - + diff --git a/jquery-ui.html b/jquery-ui.html index bc17318a8..e44d41e89 100644 --- a/jquery-ui.html +++ b/jquery-ui.html @@ -204,13 +204,13 @@

    - + - + - + - + diff --git a/test/index.html b/test/index.html index fe5f44a34..b8c585df5 100644 --- a/test/index.html +++ b/test/index.html @@ -147,9 +147,9 @@

    - - - + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/basic-plus.html b/basic-plus.html index 59019a3eb..93a917b14 100644 --- a/basic-plus.html +++ b/basic-plus.html @@ -1,4 +1,4 @@ - + - - - - -jQuery File Upload Demo - Basic Plus version - - - - - - - - - - -