Security – Applying header range fix to apache 2.0.59 issue CVE-2011-3192

apache-2.2http-headersSecurity

I've been trying to apply the suggested fix to apache for CVE-2011-3192 which was to add to httpd.conf

# Drop the Range header when more than 5 ranges. 
# CVE-2011-3192 
SetEnvIf Range (,.*?){5,} bad-range=1 
RequestHeader unset Range env=bad-range

However, in Apache 2.0.59, configtest says

Syntax error on line .... 
header unset takes two arguments

We still require the use of the range header so to unset the whole range portion is not really an option. Any thoughts on getting this to work?

Best Answer

Bad news! mod_headers in 2.0.59 doesn't seem to play nice with environment variables in its validation code.

It parses like this:

RequestHeader {action} {inhdr} {value} {envclause}

For unset, 2.0.59 validates like this, scrapping a directive if it has a third argument (value) after the directive name:

if (new->action == hdr_unset) {
    if (value)
        return "header unset takes two arguments";
}

So, RequestHeader unset Range works, and RequestHeader unset Range bytes=0-1000 breaks as intended.. but RequestHeader unset Range env=bad-range also breaks.

Someone figured that out somewhere along the line, and current versions do this, instead - putting the arguments where they belong:

if (new->action == hdr_unset) {
    if (value) {
        if (envclause) {
            return "header unset takes two arguments";
        }
        envclause = value;
        value = NULL;
    }
}

So, it's still parsing the envclause into the value position, but since unset doesn't take a value, it rearranges accordingly. So, now, RequestHeader unset Range env=bad-range works, but RequestHeader unset Range bytes=0-1000 env=bad-range still throws a validation error.. and RequestHeader unset Range bytes=0-1000 probably just blows up at runtime.


To fix, there's no shortage of bad options - patching then recompiling mod_headers to work correctly is one option, or just flat-out upgrading Apache. But, it might be worth a shot to empty the header with set (no validation bugs), instead of using unset:

RequestHeader set Range "badrange" env=bad-range

On the Apache 2.2 I checked on, junk data in the "Range" field will simply be ignored; in essence, an effective unset.