Untainting in Apache HTTPD

Back in the early days of the web, before there was ever an Apache web server, the first widely-used language for web applications was Perl.  And the Perl community took a lead in raising awareness of security issues and promoting Good Practice, notably with their treatment of tainted data and untainting.

Not everyone has followed Perl’s lead.  Applications in, for example, PHP or C, must either re-invent the security of Perl’s untainting or do without.  Or they can delegate it to mod_security, at the expense of introducing a big third-party module and quite a lot more complexity.

So, what if you could do it within Apache itself?  Well, of course, you can, up to a point.  For example, to untaint your application’s cookie:

RewriteEngine On
RewriteCond %{HTTP_COOKIE} !cookie-match-pattern
RewriteRule .* - [E=MyCookie:substitution-string]
RequestHeader set Cookie %{MyCookie}e
.

Phew!  What a hideous hack!  Actually it’s untested: I don’t even know if it’ll work, but you get the point.  Complexity is the enemy of security, and this is already horribly complex before we even start to wrestle with the match pattern and substitution.

In fact it’s worse than that.  A client can send multiple Cookie headers (or any other header).  An attacker could do that to circumvent our protection: in outline, send a ‘good’ cookie to get through our rule, together with a malicious one to attack the application.  Oops!  Well, the directives we just used weren’t designed for security: we should’ve used mod_security instead!

Providing a small, simple untainting capability has long been on my wishlist, and now at last I’ve got around to writing a first draft mod_taint, simplifying the above to:

Untaint HTTP_COOKIE cookie-match-pattern substitution-string
.

with the added bonus of folding any multiple headers into a single line, to close off the multiple-header attack we identified.  In addition to request headers, it can check all aspects of the request line, including form data (though it cannot yet parse it).

The idea is that a simple and effective untainting directive could encourage the levels of usage seen in Perl/CGI, when the community rallied behind the idea of taint-checking every web-facing script.

Actually the mod_taint default is a little different: instead of fixing an unacceptable input, it will check that the request matches an acceptable pattern, and reject the request with HTTP error status 400 (Bad Request) if it encounters an unacceptable request field.  A server admin may also set an alternative error status.

Untaint RequestField match-pattern [error-status]
.

There are of course also things mod_taint won’t do.  It won’t do anything with POST data, nor will it alert you to intrusion attempts (beyond logging them).  That’s where you definitely want mod_security!

Question: do people think this feature should be in the core distribution?  Should I drop it in to trunk, so it’ll be standard in Apache HTTPD 2.4?

Posted on August 6, 2010, in apache, security. Bookmark the permalink. Leave a comment.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: