Mercurial > hg > nginx-quic
comparison src/http/ngx_http_file_cache.c @ 6243:4821fc788c12
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.
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Fri, 11 Sep 2015 17:03:56 +0300 |
parents | d698c300b9ff |
children | 9fd738b85fad |
comparison
equal
deleted
inserted
replaced
6242:0e3a45ec2a3a | 6243:4821fc788c12 |
---|---|
519 | 519 |
520 | 520 |
521 static ngx_int_t | 521 static ngx_int_t |
522 ngx_http_file_cache_read(ngx_http_request_t *r, ngx_http_cache_t *c) | 522 ngx_http_file_cache_read(ngx_http_request_t *r, ngx_http_cache_t *c) |
523 { | 523 { |
524 u_char *p; | |
524 time_t now; | 525 time_t now; |
525 ssize_t n; | 526 ssize_t n; |
527 ngx_str_t *key; | |
526 ngx_int_t rc; | 528 ngx_int_t rc; |
529 ngx_uint_t i; | |
527 ngx_http_file_cache_t *cache; | 530 ngx_http_file_cache_t *cache; |
528 ngx_http_file_cache_header_t *h; | 531 ngx_http_file_cache_header_t *h; |
529 | 532 |
530 n = ngx_http_file_cache_aio_read(r, c); | 533 n = ngx_http_file_cache_aio_read(r, c); |
531 | 534 |
545 ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, | 548 ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, |
546 "cache file \"%s\" version mismatch", c->file.name.data); | 549 "cache file \"%s\" version mismatch", c->file.name.data); |
547 return NGX_DECLINED; | 550 return NGX_DECLINED; |
548 } | 551 } |
549 | 552 |
550 if (h->crc32 != c->crc32) { | 553 if (h->crc32 != c->crc32 || h->header_start != c->header_start) { |
551 ngx_log_error(NGX_LOG_CRIT, r->connection->log, 0, | 554 ngx_log_error(NGX_LOG_CRIT, r->connection->log, 0, |
552 "cache file \"%s\" has md5 collision", c->file.name.data); | 555 "cache file \"%s\" has md5 collision", c->file.name.data); |
553 return NGX_DECLINED; | 556 return NGX_DECLINED; |
557 } | |
558 | |
559 p = c->buf->pos + sizeof(ngx_http_file_cache_header_t) | |
560 + sizeof(ngx_http_file_cache_key); | |
561 | |
562 key = c->keys.elts; | |
563 for (i = 0; i < c->keys.nelts; i++) { | |
564 if (ngx_memcmp(p, key[i].data, key[i].len) != 0) { | |
565 ngx_log_error(NGX_LOG_CRIT, r->connection->log, 0, | |
566 "cache file \"%s\" has md5 collision", | |
567 c->file.name.data); | |
568 return NGX_DECLINED; | |
569 } | |
570 | |
571 p += key[i].len; | |
554 } | 572 } |
555 | 573 |
556 if ((size_t) h->body_start > c->body_start) { | 574 if ((size_t) h->body_start > c->body_start) { |
557 ngx_log_error(NGX_LOG_CRIT, r->connection->log, 0, | 575 ngx_log_error(NGX_LOG_CRIT, r->connection->log, 0, |
558 "cache file \"%s\" has too long header", | 576 "cache file \"%s\" has too long header", |
581 | 599 |
582 c->valid_sec = h->valid_sec; | 600 c->valid_sec = h->valid_sec; |
583 c->last_modified = h->last_modified; | 601 c->last_modified = h->last_modified; |
584 c->date = h->date; | 602 c->date = h->date; |
585 c->valid_msec = h->valid_msec; | 603 c->valid_msec = h->valid_msec; |
586 c->header_start = h->header_start; | |
587 c->body_start = h->body_start; | 604 c->body_start = h->body_start; |
588 c->etag.len = h->etag_len; | 605 c->etag.len = h->etag_len; |
589 c->etag.data = h->etag; | 606 c->etag.data = h->etag; |
590 | 607 |
591 r->cached = 1; | 608 r->cached = 1; |