diff options
author | Maxim Dounin <mdounin@mdounin.ru> | 2015-09-11 17:03:56 +0300 |
---|---|---|
committer | Maxim Dounin <mdounin@mdounin.ru> | 2015-09-11 17:03:56 +0300 |
commit | ce05841eefe0e6c5d18ae9b0fb8f9fbd7e99afdd (patch) | |
tree | 90806d4643b0a7e570ed2b67b497b766b10034c0 /src | |
parent | 51f714c85d1554ee2a1ccfe94b416e3cab6a63ad (diff) | |
download | nginx-ce05841eefe0e6c5d18ae9b0fb8f9fbd7e99afdd.tar.gz nginx-ce05841eefe0e6c5d18ae9b0fb8f9fbd7e99afdd.zip |
Cache: check the whole cache key in addition to hashes.
This prevents a potential attack that discloses cached data if an attacker
will be able to craft a hash collision between some cache key the attacker
is allowed to access and another cache key with protected data.
See http://mailman.nginx.org/pipermail/nginx-devel/2015-September/007288.html.
Thanks to Gena Makhomed and Sergey Brester.
Diffstat (limited to 'src')
-rw-r--r-- | src/http/ngx_http_file_cache.c | 21 |
1 files changed, 19 insertions, 2 deletions
diff --git a/src/http/ngx_http_file_cache.c b/src/http/ngx_http_file_cache.c index fc1476133..66339182f 100644 --- a/src/http/ngx_http_file_cache.c +++ b/src/http/ngx_http_file_cache.c @@ -521,9 +521,12 @@ wakeup: static ngx_int_t ngx_http_file_cache_read(ngx_http_request_t *r, ngx_http_cache_t *c) { + u_char *p; time_t now; ssize_t n; + ngx_str_t *key; ngx_int_t rc; + ngx_uint_t i; ngx_http_file_cache_t *cache; ngx_http_file_cache_header_t *h; @@ -547,12 +550,27 @@ ngx_http_file_cache_read(ngx_http_request_t *r, ngx_http_cache_t *c) return NGX_DECLINED; } - if (h->crc32 != c->crc32) { + if (h->crc32 != c->crc32 || h->header_start != c->header_start) { ngx_log_error(NGX_LOG_CRIT, r->connection->log, 0, "cache file \"%s\" has md5 collision", c->file.name.data); return NGX_DECLINED; } + p = c->buf->pos + sizeof(ngx_http_file_cache_header_t) + + sizeof(ngx_http_file_cache_key); + + key = c->keys.elts; + for (i = 0; i < c->keys.nelts; i++) { + if (ngx_memcmp(p, key[i].data, key[i].len) != 0) { + ngx_log_error(NGX_LOG_CRIT, r->connection->log, 0, + "cache file \"%s\" has md5 collision", + c->file.name.data); + return NGX_DECLINED; + } + + p += key[i].len; + } + if ((size_t) h->body_start > c->body_start) { ngx_log_error(NGX_LOG_CRIT, r->connection->log, 0, "cache file \"%s\" has too long header", @@ -583,7 +601,6 @@ ngx_http_file_cache_read(ngx_http_request_t *r, ngx_http_cache_t *c) c->last_modified = h->last_modified; c->date = h->date; c->valid_msec = h->valid_msec; - c->header_start = h->header_start; c->body_start = h->body_start; c->etag.len = h->etag_len; c->etag.data = h->etag; |