httpd-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Plüm, Rüdiger, VF-Group" <ruediger.pl...@vodafone.com>
Subject RE: mod_deflate DoS using HEAD
Date Tue, 14 Jul 2009 15:47:16 GMT
 

> -----Original Message-----
> From: William A. Rowe, Jr. 
> Sent: Montag, 13. Juli 2009 23:58
> To: dev@httpd.apache.org
> Subject: Re: mod_deflate DoS using HEAD
> 
> Nick Kew wrote:
> > Eric Covener wrote:
> > 
> >>          /* For a 304 response, only change the headers */
> >> -        if (r->status == HTTP_NOT_MODIFIED) {
> >> +        if (r->status == HTTP_NOT_MODIFIED || r->header_only) {
> > 
> > Technically speaking, screws up the protocol.
> > 
> > IMHO it would be acceptable provided:
> >   (a) it's an option for the admin, rather than enforced
> >   (b) it's documented
> >   (c) the headers are correct: either Content-Encoding is
> >       unset (uncompressed response) or Content-Length is
> >       unset.  Probably the former.
> 
> Agreed.  It's not a DoS.  If the admin wants to conserve CPU
> resources, they must either;
> 
>  * cache the deflated pages (avoid user-agent header if there
>    are multiples, which reminds me we need a module to unset the
>    accept deflate trigger on non-compliant browsers running
>    very-first in the quick_handler.)
> 
>  * create gzip'ed content, navigate the choice of content through
>    multiviews.
> 
>  * do not do server-side deflation (it is expensive).
> 

All very true. But how about the following patch. It should do no
harm and should solve the issue in at least some cases (I think
in most cases):

Index: modules/filters/mod_deflate.c
===================================================================
--- modules/filters/mod_deflate.c       (revision 793927)
+++ modules/filters/mod_deflate.c       (working copy)
@@ -629,6 +629,19 @@
         apr_bucket *b;
         apr_size_t len;

+        /*
+         * Optimization: If we are a HEAD request and bytes_sent is not zero
+         * it means that we have passed the content-length filter once and
+         * have more data to sent. This means that the content-length filter
+         * could not determine our content-length for the response to the
+         * HEAD request anyway (the associated GET request would deliver the
+         * body in chunked encoding) and we can stop compressing.
+         */
+        if (r->header_only && r->bytes_sent) {
+            ap_remove_output_filter(f);
+            return ap_pass_brigade(f->next, bb);
+        }
+
         e = APR_BRIGADE_FIRST(bb);

         if (APR_BUCKET_IS_EOS(e)) {

Regards

Rüdiger


Mime
View raw message