The first thing you have to do is go read the whitepaper (or watch the movie) we just put together on some research I did into bypassing authentication and authorization mechanisms with HTTP verb tampering.

It’s only been out for about 2 hours and we’ve already got a few thousand hits. Pretty cool! Ok, assuming you’re up to speed, let’s talk about some of aspects of it we couldn’t fit into the paper.

How I Found It

I was teaching J2EE developers how to write secure code on the road down south, and in my breaks and lunch I was looking at Tomcat 6.x source code for, um, for fun. After finding a handful of other vulnerabilities, I saw this snippet:

protected void doHead(HttpServletRequest req, HttpServletResponse resp)
 throws ServletException, IOException
 {
 NoBodyResponse response = new NoBodyResponse(resp);
 doGet(req, response);
 response.setContentLength();
 }

There’s half of the whole thing in a nutshell. HEAD is a silent backdoor to GET in all the web servers. The fact that you can specify JEFF/BBQ/VAJAJAY as your verb and get forwarded to GET handlers in some situations is the second half, and that hilarity we only discovered after the fact.

Blackbox Testing

When I was bouncing the concept off JG the first thing he tried to figure out was how one could detect a bypassable VBAAC mechanism from a blackbox perspective. He said timing, which is right. Send in a GET request, a HEAD request and a JEFF request and compare the timing results. It’s almost certain that if the attack worked with the HEAD or JEFF request, then it would take longer to complete those requests when compared to the GET (which is ostensibly protected). I think this is right, but there might be an easier, less noisy way.

If you make a request for a protected resource, you probably get a default or slightly customized 403 error page delivered by the web or application server. The chances are the response will be standard and have standard header values. However, the HEAD request, if it is successful, will return the real header values of the identical GET request. If that GET was sensitive, it’s headers are probably going to be different regarding content-type, caching, etc.

Stupidity

This is a stupid, stupid, stupid vulnerability to find in 2008. It’s almost criminally negligent for the vendors to put out mechanisms that are so prone to misuse – and it’s negligent that it took us this long to find it! But who knows, maybe the “bad guys” have known for a while.

Credits

  • Jeff Williams, who should have his name on the paper as much as mine at this point, but refuses credit.
  • Jim Manico for setting up some testing environments in a hurry.
  • Jeremiah Grossman, who, for having as recognizable a name as any in security, is always happy to hear ideas from other people.
  • Arian Evans, who has been flirting with this subject for a few years and is totally an 8.5+ on Hot or Not.
  • pdp, who after talking with him in Belgium said that he did something similar to bypass some security in one of his various router hacking sessions (prior art).
  • Everyone else I’ve been talking to and trying to get feedback from over the last few weeks – thanks for keeping it under wraps, although, as you can see from the comments of my last post, the information did make it outside my circle of trust. But for the security community, keeping something a secret for a few weeks is quite an accomplishment!