Welcome! Log In Create A New Profile

Advanced

nginx security advisory (CVE-2017-7529)

Posted by Maxim Dounin 
Maxim Dounin
nginx security advisory (CVE-2017-7529)
July 11, 2017 05:50PM
Hello!

A security issue was identified in nginx range filter. A specially
crafted request might result in an integer overflow and incorrect
processing of ranges, potentially resulting in sensitive information
leak (CVE-2017-7529).

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.

Besides, with 3rd party modules it is potentially possible that
the issue may lead to a denial of service or a disclosure of
a worker process memory. No such modules are currently known though.

The issue affects nginx 0.5.6 - 1.13.2.
The issue is fixed in nginx 1.13.3, 1.12.1.

For older versions, the following configuration can be used
as a temporary workaround:

max_ranges 1;

Patch for the issue can be found here:

http://nginx.org/download/patch.2017.ranges.txt


--
Maxim Dounin
http://nginx.org/
_______________________________________________
nginx mailing list
nginx@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx
c0nw0nk
Re: nginx security advisory (CVE-2017-7529)
July 11, 2017 11:50PM
Couldn't you use

max_ranges 0;

To disable byte range support completely.

Also won't setting the value of ranges to max_ranges 1; break pseudo
streaming in HTML5 video apps etc. ?

Posted at Nginx Forum: https://forum.nginx.org/read.php?2,275424,275437#msg-275437

_______________________________________________
nginx mailing list
nginx@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx
darylwang
Re: nginx security advisory (CVE-2017-7529)
July 12, 2017 01:00AM
Is there any available proof of concept or other test for this exploit? I'm
applying the patch to our systems and would like some way to check that the
fix is effective.

Posted at Nginx Forum: https://forum.nginx.org/read.php?2,275424,275439#msg-275439

_______________________________________________
nginx mailing list
nginx@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx
Maxim Dounin
Re: nginx security advisory (CVE-2017-7529)
July 12, 2017 02:10PM
Hello!

On Tue, Jul 11, 2017 at 05:45:15PM -0400, c0nw0nk wrote:

> Couldn't you use
>
> max_ranges 0;
>
> To disable byte range support completely.

Disabling ranges completely will mitigate the issue as well. But
as the issue only affects requests with multiple ranges, it is not
needed, "max_ranges 1;" is enough.

> Also won't setting the value of ranges to max_ranges 1; break pseudo
> streaming in HTML5 video apps etc. ?

No, pseudo streaming generally uses requests with a single range,
and these are allowed with "max_ranges 1;". Requests with
multiple ranges are very rare in practice (AFAIK, they are used
by Adobe Acrobat and MS Office, but I've never heard of anything
more popular than that).

--
Maxim Dounin
http://nginx.org/
_______________________________________________
nginx mailing list
nginx@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx
martinzhou
Re: nginx security advisory (CVE-2017-7529)
July 13, 2017 03:50AM
Maxim Dounin Wrote:
-------------------------------------------------------
> Hello!
>
> On Tue, Jul 11, 2017 at 05:45:15PM -0400, c0nw0nk wrote:
>
> > Couldn't you use
> >
> > max_ranges 0;
> >
> > To disable byte range support completely.
>
> Disabling ranges completely will mitigate the issue as well. But
> as the issue only affects requests with multiple ranges, it is not
> needed, "max_ranges 1;" is enough.
>
> > Also won't setting the value of ranges to max_ranges 1; break pseudo
> > streaming in HTML5 video apps etc. ?
>
> No, pseudo streaming generally uses requests with a single range,
> and these are allowed with "max_ranges 1;". Requests with
> multiple ranges are very rare in practice (AFAIK, they are used
> by Adobe Acrobat and MS Office, but I've never heard of anything
> more popular than that).
>
> --
> Maxim Dounin
> http://nginx.org/
> _______________________________________________
> nginx mailing list
> nginx@nginx.org
> http://mailman.nginx.org/mailman/listinfo/nginx


I found that in some cases (when the browser is requesting for a mp3 file),
the HTTP header will be formed as "Range: bytes=1-100, 200-100". I'm
wondering if we set "max_ranges 0;" or "max_ranges 1;" in the config, it
will cause the failure of loading such files.

Also, I'm wondering if I've already set a comparatively "big" number after
the "max_ranges", for example, "max_ranges 100;", do I still need to adjust
the number to a low value (e.g. "1" or "2")?

Posted at Nginx Forum: https://forum.nginx.org/read.php?2,275424,275462#msg-275462

_______________________________________________
nginx mailing list
nginx@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx
Maxim Dounin
Re: nginx security advisory (CVE-2017-7529)
July 13, 2017 04:20PM
Hello!

On Wed, Jul 12, 2017 at 09:42:04PM -0400, martinzhou wrote:

> Maxim Dounin Wrote:
> -------------------------------------------------------
> > Hello!
> >
> > On Tue, Jul 11, 2017 at 05:45:15PM -0400, c0nw0nk wrote:
> >
> > > Couldn't you use
> > >
> > > max_ranges 0;
> > >
> > > To disable byte range support completely.
> >
> > Disabling ranges completely will mitigate the issue as well. But
> > as the issue only affects requests with multiple ranges, it is not
> > needed, "max_ranges 1;" is enough.
> >
> > > Also won't setting the value of ranges to max_ranges 1; break pseudo
> > > streaming in HTML5 video apps etc. ?
> >
> > No, pseudo streaming generally uses requests with a single range,
> > and these are allowed with "max_ranges 1;". Requests with
> > multiple ranges are very rare in practice (AFAIK, they are used
> > by Adobe Acrobat and MS Office, but I've never heard of anything
> > more popular than that).
>
> I found that in some cases (when the browser is requesting for a mp3 file),
> the HTTP header will be formed as "Range: bytes=1-100, 200-100". I'm

AFAIK, no general-purpose browsers do this, at least no popular
ones. Some music players may do so though.

> wondering if we set "max_ranges 0;" or "max_ranges 1;" in the config, it
> will cause the failure of loading such files.

Full response with code 200 will be returned to the client. This
is valid response as per RFC, and all HTTP-complaint clients are
expected to understand it and handle it properly. Also, this is
what happens regularly when a server does not support range
requests, so is highly unlikely to break any clients.

I wouldn't recommend using "max_range 0;" though, as it will
disable single-range requests as well, and this means that
download resumption and seeking won't work.

> Also, I'm wondering if I've already set a comparatively "big" number after
> the "max_ranges", for example, "max_ranges 100;", do I still need to adjust
> the number to a low value (e.g. "1" or "2")?

For the workaround to work, multi-range requests need to be
disabled. That is, you should use "max_ranges 1;".

--
Maxim Dounin
http://nginx.org/
_______________________________________________
nginx mailing list
nginx@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx
Shuxin Yang
Re: nginx security advisory (CVE-2017-7529)
July 21, 2017 07:40AM
HI, There:

I try to exploit this bug in an attempt to do something nasty :-).
However, the more I dig into it, the more I get confused.

As far as I know, one necessary conditional to trigger the problem
is that range-filter kicks in, and range-filter is called if and *ONLY*
if (FIXME):

1) Nginx serves static file.

2) Nginx serves as a reverse-proxy *with* cache capability, and the
resource being accessed is *cache-able*. In this case, the proxy will
fetch the entire file from origin, cache it, then send the ranges down
to downstream via range-filter. (If content is not cache-able, range
range in reverse proxy will not be enabled, instead, the range request
is directly forwarded to upstream. Also, in proxy without cache, rang
filter will not be invoked)

Questions:

======

a). Does this bug have any negative impact to 1)?

b). Where exactly does buffer overflow take place? How does this
patch resolve the problem. As far as I can understand, the patch only
check if total size of the ranges exceeds 4G (assuming 32-bit system for
simplicity). The start/end pointer of each range is guaranteed in the
range of "[0, content-length]" regardless the patched condition.

c) Could following statement have overflow problem as well when the
start/end point is very close 4G?

850 if (ngx_buf_in_memory(buf)) {
851 b->pos = buf->pos + (size_t) range.start;
852 b->last = buf->pos + (size_t) range.end;
853 }

d) the patch guarantees the total size of ranges is smaller than 4G
(again, assume 32bit system). But what if it ends up very close to 4G,
making the "len" variable in function variable
ngx_http_range_multipart_header() overflow. The "len" is to calculate
the content-length the resulting response, it is the total size of
multi-part overhead plus ranges.

Is there any simple example to reproduce the problem?

Thanks a lot!

Shuxin

On 07/11/2017 08:47 AM, Maxim Dounin wrote:
> Hello!
>
> A security issue was identified in nginx range filter. A specially
> crafted request might result in an integer overflow and incorrect
> processing of ranges, potentially resulting in sensitive information
> leak (CVE-2017-7529).
>
> 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.
>
> Besides, with 3rd party modules it is potentially possible that
> the issue may lead to a denial of service or a disclosure of
> a worker process memory. No such modules are currently known though.
>
> The issue affects nginx 0.5.6 - 1.13.2.
> The issue is fixed in nginx 1.13.3, 1.12.1.
>
> For older versions, the following configuration can be used
> as a temporary workaround:
>
> max_ranges 1;
>
> Patch for the issue can be found here:
>
> http://nginx.org/download/patch.2017.ranges.txt
>
>

_______________________________________________
nginx mailing list
nginx@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx
Maxim Dounin
Re: nginx security advisory (CVE-2017-7529)
August 09, 2017 05:20PM
Hello!

On Thu, Jul 20, 2017 at 10:32:15PM -0700, Shuxin Yang wrote:

> I try to exploit this bug in an attempt to do something nasty :-).
> However, the more I dig into it, the more I get confused.

No comments on this, sorry. We generally avoid providing
exploitation details to minimize impact on not-yet-updated
systems.

[...]

> d) the patch guarantees the total size of ranges is smaller than 4G
> (again, assume 32bit system). But what if it ends up very close to 4G,
> making the "len" variable in function variable
> ngx_http_range_multipart_header() overflow. The "len" is to calculate
> the content-length the resulting response, it is the total size of
> multi-part overhead plus ranges.

This looks like a separate bug, which can result in incorrect
Content-Length being returned if a file larger than 4G is
requested using multiple ranges on a 32-bit system. Thanks for
reporting this.

The following patch should fix this:

# HG changeset patch
# User Maxim Dounin <[email protected]>
# Date 1502291117 -10800
# Wed Aug 09 18:05:17 2017 +0300
# Node ID fc89eec543ee3e41b74347ffa0c59554188dc3f5
# Parent 2f48ab272052d9b2ca00f8192c589b872ee3bc86
Range filter: changed type for total length to off_t.

Total length of a response with multiple ranges can be larger than a size_t
variable can hold, so type changed to off_t. Previously, an incorrect
Content-Length was returned when requesting more than 4G of ranges from
a large enough file on a 32-bit system.

Reported by Shuxin Yang,
http://mailman.nginx.org/pipermail/nginx/2017-July/054384.html.

diff --git a/src/http/modules/ngx_http_range_filter_module.c b/src/http/modules/ngx_http_range_filter_module.c
--- a/src/http/modules/ngx_http_range_filter_module.c
+++ b/src/http/modules/ngx_http_range_filter_module.c
@@ -463,7 +463,7 @@ static ngx_int_t
ngx_http_range_multipart_header(ngx_http_request_t *r,
ngx_http_range_filter_ctx_t *ctx)
{
- size_t len;
+ off_t len;
ngx_uint_t i;
ngx_http_range_t *range;
ngx_atomic_uint_t boundary;
@@ -569,7 +569,7 @@ ngx_http_range_multipart_header(ngx_http
- range.content_range.data;

len += ctx->boundary_header.len + range.content_range.len
- + (size_t) (range.end - range.start);
+ + (range.end - range.start);
}

r->headers_out.content_length_n = len;

--
Maxim Dounin
http://nginx.org/
_______________________________________________
nginx mailing list
nginx@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx
Sorry, only registered users may post in this forum.

Click here to login