[Zope] unprotected VHM usage may facilitate cache poisoning

Jamie Heilman jamie@audible.transient.net
Mon, 3 Feb 2003 02:22:29 -0800


With Virtual Host Monsters being all the rage these days, I'd like to
point out something that I have yet to see addressed in any of the
tutorials.

Letting anonymous clients send tainted requests to a VHM enabled site
is not a good idea, and should be guarded against.  A tainted request
in this case is one whose URI contains the substrings
"/VirtualHostBase/", "/VirtualHostRoot/", or "/_vh_".  For unprotected
sites using VHMs, letting an anonymous client send URIs containing
those substrings will result in the returned document rendered in the
context of an appropriately mangled traversal request name stack.
Usually if that mangling results in a bunch of broken URLs in the
document its no big deal.[1]  It is a big deal though, if you're using
a cache, and that request results in a cache miss--then that broken
document gets stored as the response for subsequent requests.  Oops.

I've verified this can be a problem when using RAM Caches, I haven't
tried external caches, depending on how they key the content it may
or may not be a problem.

Now, this isn't so much a problem with the VHM product, but rather
with sloppy configuration practices.  Which, as it happens, pretty
much every tutorial I've read demonstrates, with a uniformity
otherwise rare to the HOW-TO library.  As virtual host monsters may be
used in a variety of ways, there's no one-size-fits-all approach to
protecting your site.  If you use Apache with mod_proxy's directives,
for example, you can probably use any number of techniques ranging
from LocationMatch directives to perhaps even abusing mod_alias.  If
you use Apache with mod_rewrite (+ mod_proxy for the [P] flag), then
you can simply use RewriteCond patterns to ignore tainted URIs,
letting them fall through to their fate, or you could even catch them
and send 'em packing with a [F] flag or similar.  An example[2] of the
former is:

RewriteEngine on
RewriteCond %{REQUEST_URI} !/VirtualHostBase/
RewriteCond %{REQUEST_URI} !/VirtualHostRoot/
RewriteCond %{REQUEST_URI} !/_vh_
RewriteRule pattern substitution [P]

If you use VHM mappings and ZServer's HTTP service on a raw wire, then
you've probably already thrown out any notion of security, and this is
the least of your worries.  Fixing other front-end proxy server
configurations (squid, etc.) is left as an exercise for the reader.

I believe the 3 'magic' strings I've outlined here are the only ones
which are used by the VHM product, and as such, are the only ones
which need immediate attention for rectifying this particular problem.
If somebody wants to double-check my interpretation of the VHM code
I'd gladly welcome the peer review.

My knowledge of exactly what is used as key in a RAM Cache is hazy at
the moment - but it *may* be possible in some circumstances to exploit
acquisition to poison a RAM Cache as well.  I made a few half-hearted
attempts at doing this, but I wasn't successful; something to think
about though.  If anyone has evidence of why this can or can't work
I'd like to hear about it, if for no other reason than to set my mind
at ease.

-- 
Jamie Heilman                   http://audible.transient.net/~jamie/
"You came all this way, without saying squat, and now you're trying
 to tell me a '56 Chevy can beat a '47 Buick in a dead quarter mile?
 I liked you better when you weren't saying squat kid."	-Buddy

[1] Its no big deal with one huge proviso, that the resulting mangled
URLs in the document returned are properly escaped for the context in
which they appear so as to prevent cross-site scripting attacks and
such.  From my perusal of the VHM source, I'd say no escaping is done
to path elements prefixed by "_vh_".  Nevertheless, this is probably
fine, as I'm guessing all escaping is left until later in the
processing phase when the context of presentation is less of an
unknown.  Anyway, I think we're in the clear there, but if you're
sufficiently paranoid (good for you!) and you have some spare time you
may wanna investigate this further.

[2] I hate giving examples of how to configure Apache, because people
will inevitably blindly follow your advice without ever taking the
time to RTFM and learn what the hell they are doing.  I'll make an
exception for (what I've perceived to be) the most common mode of
usage though, in this case.