Nginx have announced a fix to an information disclosure vulnerability arising from an integer overflow when multiple ranges are requested (via the HTTP Range header)
When using nginx with standard modules this allows an attacker to
obtain a cache file header if a response was returned from cache.
In some configurations a cache file header may contain IP address
of the backend server or other sensitive information.
The issue affects a wide range of versions
- nginx 0.5.6 - 1.13.2.
The issue is fixed in nginx 1.13.3, 1.12.1.
There's a known mitigation - limiting the number of ranges permitted in a request to 1 (which suggests it should be possible to exploit with just 2 ranges)
max_ranges 1;
Activity
2017-07-13 08:41:10
Need to look at the module to see how size is calculated initially, but from the patch, it looks as though exploitation is just a case of requesting ranges so that the total number of bytes requested (i.e. the total of the deltas between each start and end) is sufficiently high to overflow the integer, so that Nginx winds up ignoring the usual offset when reading the cachefile (so it no longer excludes the cache file header)
2017-07-13 09:16:44
It's size is controlled by a macro - _FILE_OFFSET_BITS based upon the platform, but should be 64 bits (8 bytes) on Linux ( https://github.com/nginx/nginx/blob/master/src/os/unix/ngx_linux_config.h#L16 )
So, with a quick calculation, it looks like we have to request an inordinate amount of data in order to trigger the issues
It's possible I've made some wrong assumptions about the patch (should really find time to read the module), but that might also be why it's been present for so long without detection.
That said, NGX_MAX_OFF_T_VALUE on Linux (by the looks of it, on all *nix) gets calculated and set at configure time. On a 64 bit Ubuntu test box, I get the value
Which is still a butt-load of data
2017-07-13 09:38:12
What I don't know is whether it de-duplicates the requested ranges, so will have to test
Seems not, so you could potentially request the entire range repeatedly to try and trigger this issue
2017-07-13 09:47:37
It seems it also doesn't work if you omit the end range:
results in a 200 with the content length being one instance of the file, so end bytes must be defined.
Will come back to this some more later, given the high number of bytes needed to trigger an integer overflow and limits on the length of HTTP request headers will probably need to set up a system with a pretty sizeable cache partition (and a large test file)
2017-07-13 09:47:56
2017-07-13 09:47:56
2017-07-13 10:02:20
2019-07-16 16:03:56
Given the time that's passed, there's probably not much value in finishing off anyway
2019-07-16 16:03:56
2019-07-16 16:03:56
2019-07-16 16:03:56
2019-07-16 16:04:00