Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Author of jQuery File Upload here.

The vulnerability is a combination of Apache v.2.3.9's default setting to not read .htaccess files and my mistake of relying on .htaccess to enforce security of the sample PHP upload component.

To give you some context on how this could happen:

- As the project name implies, this started as a client-side jQuery plugin, with a dummy PHP script to echo out the uploaded file

- Over time, I added a couple of sample server-side upload components, including two for Google App Engine (Python + Golang) - which I used for the demo - and one for PHP, which I never used myself in production

- I used the PHP component for local tests with various possible file uploads, including very large files and chunked uploads, which required enabling all file types for upload. My thinking was that allowing all file types for upload is not critical as long as the handling of those files is properly configured.

- Prior to adding the .htaccess file, I mistakenly assumed developers would configure their Apache server themselves so that no PHP scripts would be executed in the uploads folder. It was only added in this commit: https://github.com/blueimp/jQuery-File-Upload/commit/13931c7...

- The Apache servers I tested with always had support for .htaccess enabled, so I never bothered to check that the default Apache configuration since version 2.3.9 actually disabled it

- The original .htaccess configuration didn't even prevent script execution in all Apache configurations and had to be fixed, see: https://github.com/blueimp/jQuery-File-Upload/pull/3381

Looking back, there are a couple of things that I should have done differently:

- Move out the server-side components into separate repositories

- Inform users better about file upload security - see https://github.com/blueimp/jQuery-File-Upload/wiki/Security

- Never assume people actually read information about security

- Never rely on .htaccess for security configurations in Apache

- Make sure that published code is secure in all default configurations

- Never allow all file types for upload by default, even if it is secure in your configuration

- Recommend users to not upload files in the same root as their executable web application

- Always follow security best practices, even if it makes setup for users more difficult

I wanted to make it really simple for users to install a generic and secure file upload service with a great user interface. Unfortunately, security best practices and ease-of-use are often at odds to each other.

Bonus info:

The client-side component had a cross-site scripting vulnerability in the Iframe Transport HTML site back in 2012: https://github.com/blueimp/jQuery-File-Upload/commit/4175032...

The App Engine components had an open redirect vulnerability back in 2015: https://github.com/blueimp/jQuery-File-Upload/commit/f74d2a8...



I really don't blame the author here, sure there was an issue with the sample code - but come on it was sample code. If someone is implementing user uploads they should really do the due diligence and understand what the sample code does.

To be honest I'm not really that surprised that the vulnerability stayed hidden for so long; many PHP users are hobbyists or come from a more traditional "webmaster" background. This is not to say that there aren't good PHP programmers, just that there is a large group of novices.


Not a good way to look at it. Sample code is equivalent to production code. It will be copied, verbatim, if it appears to work. Once it has the appearance of working, it isn’t looked at again. It doesn’t matter if you think people should be doing this or not. The only thing that matters is they will.


Exactly this.

For most developers there doesn't seem to be a differentiation between example code on a blog post and actual producation code.


It wasn't exactly hidden seeing as how there was a YouTube video titled 'Exploit jQuery File Upload Vulnerability' available since 2015. I don't blame the author (given the timing of the Apache change it probably would have been easy for him to overlook[1]) and it is surprising that this took years for anyone to make him aware of the issue since the exploit wasn't exactly unknown. Apparently there's some groundbreaking work left to be done in infosec searching on combinations of various library / application names and 'exploit'...

[1] I assume that like most of the rest of us he was lagging behind the latest and greatest Apache release a bit. So when he was writing/testing this, it probably wouldn't have been an issue.


Unfortunately, I never tested it with an Apache configuration that had .htaccess support disabled and so it simply did not occur to me that the default was "off".

I think the bigger issue was that the PHP sample code allowed all file types by default - this would not only affect Apache, but any Webserver that had broad rules to execute PHP scripts found in a directory.

Originally I didn't see this as an issue as I trusted developers to securely configure their server to make sure no uploaded files would be executed, which is why the .htaccess security settings were only added later in this commit: https://github.com/blueimp/jQuery-File-Upload/commit/13931c7...

But neither was the documentation informing developers clearly enough about the security implications, nor should I have relied on people actually reading security notices.


Fair enough... but I still don't blame you ;-)


Hehe, thanks! :)


I'm not going to throw stones either. But I would encourage developers to make their sample code robust. Especially as

> many PHP users are hobbyists or come from a more traditional "webmaster" background

I seem to remember a somewhat related problem with WordPress. The issue there was made worse by the fact the sample code was part of the default install and so available to anyone who knew the URL.

Edit: A quick search shows I was thinking of an XSS attack. It was due to some bad example code in the default theme folder, which is by default publicly accessible even if not used.

https://arstechnica.com/information-technology/2015/05/activ...


I agree, the sample code should have been secure by default (with all web server configurations) because it's guaranteed that someone will use it as is without checking their own server configuration.

And inexperienced webmasters were definitely part of the target group, since I wanted to make is as accessible as possible, including for those users on shared hosting webspace without access to the Apache configuration files.


The simplicity of the sample code is a strong factor in deciding what library to use for a task.

If the 'hello world' example is hundreds of lines, then I imagine the effort of using this library to be a few days at least.

If the 'hello world' example is just 3 lines, then I can probably integrate this library into my service in 10 minutes.

Making the sample code more robust (handling errors, checking for legacy configs, etc.), makes it longer, which in turn puts off people like me.


Thanks for your comment.

I do think that I share at least part of the blame. Enabling all file types by default was not necessary and would have prevented this issue.

Especially since there are so many inexperienced developers using PHP, the defaults should have been secure in every perceivable Webserver configuration.


Understanding what the code does is not how people generally write software. They slap components together, copy&paste examples and randomly move code lines around until it seems to work good enough. So your examples better be correct :)


> The Apache servers I tested with always had support for .htaccess enabled

For what it's worth, you'll find lots of people disable support for .htaccess for performance reasons.

It's probably less of an issue these days, but if you support .htaccess files, apache reads the .htaccess file for the current directory, and those for every parent directory, and it happens on every single access.

So for example someone accessing http://foo.bar.com/thing/goes/here would cause the webserver to check for and read /thing/goes/.htaccess, /thing/.htaccess and /.htaccess. If you imagine you've done the sensible thing and got your content nicely split out, you can probably see how that can hurt performance. *nix OSs will be smart and cache the content etc. but you're still wasting time on every access making sys calls.

If you put the access rules in the apache config file, everything is set-up at initialisation time and it never has to make further checks.


Agreed - in addition to performance issues, there are also security issues if .htaccess support is enabled - because they can override security settings.

Originally the PHP example code didn't have a .htaccess file - I trusted developers that they would configure file uploads securely by themselves, e.g. via Apache configuration files.

The reason I added it was to support developers on shared hosting plans without access to the Apache configuration - something which was very common back then.


Don't beat yourself up. Your response shown here is insightful and reasonable. Well done!


Thanks a lot!


"Zero-day in popular jQuery plugin" is a bit misleading for the title then. More like "Zero-day in copy pasted code in PHP if apache incorrectly configured".


I think the title is substantially misleading in that it suggests the bug is in the plugin itself. Maybe "Zero-day in PHP server sample code provided with popular jQuery plugin"?


That’s not really true, given that the default Apache confit is vulnerable.


That's exactly what a security post-mortem should look like.

- What went wrong

- Why did it go wrong

- What can be done to ensure this doesn't happen again

Everyone makes mistakes once in a while, the key is learning from them.

Well done!


Thanks a lot!

By now I've also updated the project page with

- Security-related releases on top of the main page: https://github.com/blueimp/jQuery-File-Upload#%EF%B8%8F-secu...

- Security guidelines linked in various places on how to securely set up file uploads: https://github.com/blueimp/jQuery-File-Upload/blob/master/SE...

- A list of the fixed vulnerabilities with instructions on how to fix it for the recent critical one: https://github.com/blueimp/jQuery-File-Upload/blob/master/VU...


> Never allow all file types for upload by default, even if it is secure in your configuration

The general form - never use default-allow - should be used in most situations where set of possible inputs cannot be exhaustively enumerated. In most situations, you cannot enumerate badness[1]. Instead of trying to define valid input by specifying it's inverse, it's far simpler (and safer) to use default-deny and specify valid input directly.

[1] http://www.ranum.com/security/computer_security/editorials/d...


Also known as "use a whitelist instead of a blacklist".


Although I agree with you in a general sense, in this case there was no blacklist mistakenly used.

If the server is configured to serve uploaded files securely, it is feasible to allow all file types for upload (e.g. think of Amazon S3 or Google Cloud Storage).

However since there is no way to ensure that the server security settings to securely handle uploaded files are applied, limiting file uploads with a whitelist minimizes the attack vector sufficiently.



Since this is about vulnerabilities in a third-party dependency (ImageMagick/Ghostscript), the recommendation in the blog post to use the GD library instead (what the image_library 0 setting does) is not very sound, as libgd also had a number of vulnerabilities in the past, albeit less than ImageMagick: https://cve.mitre.org/cgi-bin/cvekey.cgi?keyword=Libgd

A better recommendation is to securely configure ImageMagick, or even better: to use a safer image processing library (e.g libvips or imageflow).

I’ve added some mitigating code and recommendations on how to securely configure ImageMagick to jQuery File Upload, please have a look here: https://github.com/blueimp/jQuery-File-Upload/blob/master/VU... https://github.com/blueimp/jQuery-File-Upload/blob/master/SE...


Thank you for coming that clear.


Thanks for your comment.

I think in situations like this it's important to take responsibility and provide as much transparency as possible.


Relying on apache version specific defaults is always the wrong approach.

But everything else can be avoided with a whitelist of acceptable types by default.


are other web servers vulnerable ? for example, wildfly jboss server,??


If the upload directory is securely configured, no.

Please refer to the vulnerability documentation here to see if you are affected: https://github.com/blueimp/jQuery-File-Upload/blob/master/VU...


There is no blame on you. There is no way you can provide a configuration that will be secure on every server.

My recommendation: add a big warning message that there is at least one known security hole and many unknown ones in the server code and it is up to the just to secure their server properly.

Then fix the demo code but leave the warning there.

It's always up to the developers to check the system they build for security problems. They could use the best frameworks in the world and copy thoro reviewed example code. The end result might still have huge security problems.


Thanks!

I already got a helpful pull request for the main README.me that I've updated by now with

- Security-related releases on top of the main page: https://github.com/blueimp/jQuery-File-Upload#%EF%B8%8F-secu...

- Security guidelines linked in various places on how to securely set up file uploads: https://github.com/blueimp/jQuery-File-Upload/blob/master/SE...

- A list of the fixed vulnerabilities with instructions on how to fix it for the recent critical one: https://github.com/blueimp/jQuery-File-Upload/blob/master/VU...

The demo code was fixed as soon as I could confirm the report from Larry Cashdollar.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: