The Apache .htaccess vulnerability
There’s an article about a security problem getting a bit of attention lately,
Apache Access Vulnerability Could Affect Thousands of
Applications.
Sounds really scary. Here’s a better article about it, Zero-day in popular jQuery plugin actively
exploited for at least three
years.
Looking at those titles you might think that the problem is either with a
jQuery plugin, or Apache’s .htaccess
files. It’s neither. The real
situation is more complicated. You might think that if you’re not using this
plugin on your website, you’d be safe. You’d be wrong. You might think that
patching the plugin, or the Apache web server, would solve the problem. You’d
be wrong about that, too. The real problem is still there, waiting to bite
you in the tail. If you don’t have a website, or don’t allow file uploads,
you can stop reading now unless you’re curious. If you do, stick around
(or jump to the last section if all you want is the fix).
The problem being reported
You may have noticed that the two titles up there are highlighting different
aspects of the problem. There’s that “popular jQuery plugin”,
blueimp/jQuery-File-Upload.
People building websites use it to allow their users to upload files (e.g.,
cat pictures). It’s really popular – 7800 forks on GitHub, 29,000 stars;
probably tens or hundreds of thousands of sites using it. And then there’s
the Apache web server. Apache is even more
popular – it runs some 45% of the
web. Since there
are presently just short of two
billion websites
(although all but a couple of hundred million are currently active). And more
specifically and specifically htaccess
files, which are used
to override certain server configuration options (including security options,
which is almost as scary as it sounds, but doesn’t have to be).
The specific problem is this: jQuery-File-Upload lets visitors to a web site upload their cat pictures. These get put in a directory somewhere in the server’s file system. If you’re running a website and have any sense, you’ll put that directory someplace where it can’t be seen from the web, but of course that means that your visitors can’t see the cat pictures they’ve uploaded, without you or your software doing some work, and that could be tricky.
If you have a directory that’s part of your website that you want to be
invisble from the web, or visible safely (we’ll get into that a little later),
there are two ways to set that up. If you have access to Apache’s
configuration files, you do it there. Unfortunately that requires root
access, and most of us are using shared servers and our hosting sites don’t
allow that, because it would be a huge security hole if they did. The other
way of configuring your site is to put a file called .htaccess
somewhere on
your site, and it will apply configuration overrides to that directory and
everything below it. That’s a little dicey, because it’s possible to get that
wrong, especially if you’re not an experienced system administrator, but if
you’re operating a shared hosting service like the one I use, you have to give
your users some way of setting parameters, and .htaccess
is the only game
in town.
Finally there’s the fact that, some ten years ago, Apache changed the
defaults on their server so that .htaccess
files are disabled, so the
administrator has to specifically re-enable them. What does that mean?
Well, if you are allowing users to upload files, and if you put the upload
directory where it can be seen from the web (meaning that people can
download from it), and if you were counting on a .htaccess
file to
protect that directory, and if you upgraded Apache any time in the last
ten years, and if you or your system administrator didn’t re-enable
.htaccess
files, and if you thought that your .htaccess
file was
still protecting you, then you have a problem. That’s a lot of “if”s, but
there are an awful lot of websites.
Here’s how this situation can be exploited, as reported by a security researcher at Akamai named Larry Cashdollar, in an article titled Having The Security Rug Pulled Out From Under You.
If you can upload files to a website, all you have to do is:
$ echo '<?php $cmd=$_GET['cmd']; system($cmd);?>' > shell.php
$ curl -F "files=@shell.php" http://example.com/jQuery-File-Upload-9.22.0/server/php/index.php
It’s not hard. The first line there creates a one-line file with some PHP
code in it. The second line uploads it. Now you have a file called
shell.php
on the server. You can send a request for that file with a query
string attached to it, and PHP will helpfully pass that string to the
system
, which runs it. Boom.
The problem with the reporting
Here are a couple of passages quoted from the ZDNet article:
The developer’s investigation identified the true source of the vulnerability not in the plugin’s code, but in a change made in the Apache Web Server project dating back to 2010, which indirectly affected the plugin’s expected behavior on Apache servers.
…
Starting with [version2.3.9], the Apache HTTPD server got an option that would allow server owners to ignore custom security settings made to individual folders via .htaccess files. This setting was made for security reasons, was enabled by default.
Actually, what happened was that the server disabled .htaccess
files by
default, and it was done for performance reasons – having to read
.htaccess
files with every request is a big performance hit. Here’s what
the Apache documentation says about it:
.htaccess
files should be used in a case where the content providers need to make configuration changes to the server on a per-directory basis, but do not have root access on the server system. In the event that the server administrator is not willing to make frequent configuration changes, it might be desirable to permit individual users to make these changes in .htaccess files for themselves. This is particularly true, for example, in cases where ISPs are hosting multiple user sites on a single machine, and want their users to be able to alter their configuration. [emphasis mine]
The DARKReading Article adds,
A security vulnerability is born, Cashdollar said, when a developer looks at very old documentation and uses .htaccess for authentication instead of one of the methods now suggested by the Apache Foundation.
Well, no. The documentation is still current, and it’s very clearly marked
as something you shouldn’t use unless you have to. And most of the people who
have vulnerable websites aren’t developers, don’t have any choice about
whether to use .htaccess
, and aren’t reading the docs. They’re just doing
cut-and-paste from the quick-start documents that their web host provides.
What’s the real problem?
There are a couple of things that the articles I’ve refererred to didn’t mention, or just glossed over.
The first is that uploading files is a problem, and it’s been a problem
since long before there was a World Wide Web! I first ran into this while
running an FTP server. There are all sorts of ways file uploads can be
abused. Somebody can bring down your server by uploading junk and filling
your disk. They can upload malware. It has nothing at all to do with
jQuery-File-Upload
; this has been a problem since day 1.
The solution, if you must allow uploads, is to upload them to someplace safely
outside of your website, and process them immediately – either with your
server-side code, or a cron
job. This is just as much common sense as not
using any form data until it’s been validated and sanitized. Some
languages, like Perl, give you some help with this. This is true on the
client side too, if you have JavaScript. Validate your inputs! I ran into
that one last week, you may remember.
The second problem is PHP. Actually, the problem is putting executable files in your website instead of someplace like a CGI script directory, or a web server. But PHP is the biggest offender. It was designed to make it so easy to build a website that anyone could do it. And everyone did.
PHP was designed to be simple. It wasn’t designed to be safe. (It has a lot of other problems, too, but that’s the big one.) See Why PHP Sucks and PHP: a fractal of bad design, for example.
The biggest problem with PHP is that it works by mixing executable executable code with the documents you’re serving to the user. Sure, it’s convenient. It’s also bad design – it’s a series of disasters waiting to happen, and this is only the most recent one.
What should you do?
- Obviously, if you have access to your server’s configuration, you should
disable
.htaccess
and do everything at the server level. That’s not always possible. - If you aren’t using PHP on your website, disable it.
- At the very least, disable PHP in your upload directory!
- If you want to let users upload files, put them someplace outside your document root and keep them there until you or your software can review them for safety. (When I was running an FTP server, I had separate ‘incoming’ and ‘outgoing’ directories.)
You may find Disable PHP in a directory with Apache .htaccess - Electric
Toolbox
helpful: just put these three lines into an .htaccess
file, either at the
top level of your site, or down in any directories where it’s not needed
(which includes not only your upload directory but also image directories and
other assets, just to be sure).
RemoveHandler .php .phtml .php3
RemoveType .php .phtml .php3
php_flag engine off
While you’re at it, make it so that the web server – and anyone else who isn’t you – can’t write into your website files:
cd your_server's_document_root
chmod -R go-w .
Have fun, be safe out there, and don’t use PHP.