I attended the Messaging, Malware and Mobile Anti-Abuse Working Group (m3aawg.org) meeting in Brooklyn, NY. I expected better weather to wander around the city while enjoying the conference and the neighborhood's wide selection of food. I had been so confident of clear skies that I did not bring a rain jacket. It rained most of the week. This left me somewhat stranded in my hotel room with free Wifi service and both my research laptop and my work laptop. I decided to start looking at Node.js and its accompanying packages available from https://www.npmjs.com.
There are thousands of user-contributed packages available for download and inclusion in your own software development project. I searched the Node.js npm site for common package names and functions like, file, backup, download, and upload. The last search term turned up a software project by Blueimp called jQuery file upload. Its description seemed interesting enough to download and investigate:
"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."
I started looking through the package's source and found myself peering at two PHP files under the directory server/php. The files are named upload.php and UploadHandler.php. The upload.php file calls the main file UploadHandler.php where all of the file upload code resides. I also saw that all files were uploaded to the files/ directory in the web server's root path. I wrote a quick command line test with curl and a simple PHP shell file confirmed that I could upload a web shell and run commands on the server.
$ curl -F "email@example.com" http://example.com/jQuery-File-Upload-9.22.0/server/php/index.php
Where shell.php is:
<?php $cmd=$_GET['cmd']; system($cmd);?>
A browser connection to the test web server with cmd=id returned the user id of the web server's running process. I suspected this vulnerability hadn't gone unnoticed and a quick Google search confirmed that other projects that used this code or possibly code derived from it were vulnerable. There are a few Youtube videos demonstrating the attack for similar software packages.
I notified the jQuery File Upload author and began documenting what I had found for the CVE numbering process. The author responded shortly the next day a bit confused and asking for detail as he was unable to reproduce the vulnerability in his test environment.
After comparing our test configurations over email we soon realized that the Apache maintainers disabled support for .htaccess since Apache version 2.3.9. It appears they've done this to improve performance as the server doesn't have to check for this file everytime it accesses a directory. Moreover, the change was made to prevent users from overriding security features that were configured on the server.
So Apache had good reasons to disable .htaccess, but their changes left some developers and their projects open to attack, especially if they relied on .htaccess as a security function.
In the case of Blueimp, in order to address these changes and correct the file upload vulnerability in CVE-2018-9206, the developer made changes to his code that only allows file uploads to be of a content-type image.
The problem is larger than a single project
There is something else to note, because of the changes to Apache, some 7,800 other projects could be vulnerable to the file upload issue.
The majority of these code forks carry the original vulnerability over into their code. In some cases, the vulnerability persists even after the project author changed the original Blueimp code to suit their own project, with each project exploitable by a slight variation of my proof of concept example.
This means that if any of these projects are used in production they are vulnerable to file upload and code execution vulnerability. Opening the application up to data exfiltration, malware infection, defacement, an entire assortment of nastiness.
Unfortunately, there is no way to accurately determine how many of the projects forked from jQuery File Upload are being properly maintained and applying changes as they happen in the master project. Also, there is no way to determine where the forked projects are being used in production environments if they're being used in such a way. Moreover, older versions of the project were also vulnerable to the file upload issue, going back to 2010.
The internet relies on many security controls every day in order to keep our systems, data, and transactions safe and secure. If one of these controls suddenly doesn't exist it may put security at risk unknowingly to the users and software developers relying on them.
For software developers reviewing changes to the systems and libraries you rely on during the development of your project is a great idea as well. In the article above a security control was removed by Apache it not only removed a security control for Blueimp's Jquery file upload software project but most of all of the forked code branches off of it. The vulnerability impacted many projects that depend on it from stand-alone web applications to WordPress plugins and other CMSs.