4 ms·
First of all, thanks for for getting this out there. The Length Hiding piece protects all content, but only really slows the attack (as you mention!). The pro
by jwilliams 13y ago
First of all, thanks for for getting this out there.
The Length Hiding piece protects all content, but only really slows the attack (as you mention!).
The problem is this implementation breaks Rails' Conditional GET (Actually Rack's) -- which returns 304 Not Modified if the content is the same. Now that the content varies, normal usage will get a 200 and the full response every time.
It depends on the Application, but in most cases this will be a reasonable increase in overall bandwidth (for normal use, not the attack). Probably more of an increase than you'd encounter by turning off gzip - which completely defeats the attack rather than just making it more difficult, as Length Hiding does.
The workaround is to use ETags (See: http://api.rubyonrails.org/classes/ActionController/ConditionalGet.html http://api.rubyonrails.org/classes/ActionController/Conditio...), which will use the tag rather than the content to determine 304s. I'd suggest this should be recommended if you're using Length Hiding.
Edit: Actually another workaround might be to put your Middleware after the relevant middleware Rack::ConditionalGet, Rack::ETag. Right now it's at the top of the Middleware chain.
- bradleybuda 13y agoGreat idea; I was worried about breaking ETags but I think that would work. I'll test it and update the gem appropriately.
- jwilliams 13y agoActually, it's a harder workaround than I was suggesting. When the ETag isn't explictly set, the full body of the middleware chain is generated every single time, irrespective of the Conditional Get. You want the ETag generated without the Length Hiding, which isn't the way Rack::ETag works. It digests the whole content - it's implementation calls upstream first, so it effectively ensures it's always at the end of the middleware chain. You'd need to extend/replace/otherwise hook into Rack::ETag, which is a bit more surgical.
- lnanek2 13y agoWonder how easy it would be to turn off gzip on just potential attacks. It takes a lot of requests to execute the attack after all. So an example where each user only got their response gzipped the first time for any URL would be safe. But then the site would slow down for them later. So you'd have to pick some sort of reset metric that prevented efficient attacks, but still gave users compressed data most of the time. Another piece of low hanging fruit would be to change the session cookie every request. It isn't a big deal for most servers to update the session ID and send a cookie down each request. Meanwhile it would hurt attacks going after the session ID by methods like this that need a lot of requests with the same value a lot.