diff --git a/src/http/ngx_http_parse.c b/src/http/ngx_http_parse.c index 2b083660c..286bec23a 100644 --- a/src/http/ngx_http_parse.c +++ b/src/http/ngx_http_parse.c @@ -1098,6 +1098,7 @@ ngx_int_t ngx_http_v23_validate_header(ngx_http_request_t *r, ngx_str_t *name, ngx_str_t *value) { + int bad; u_char ch; ngx_uint_t i; ngx_http_core_srv_conf_t *cscf; @@ -1162,6 +1163,46 @@ ngx_http_v23_validate_header(ngx_http_request_t *r, ngx_str_t *name, } } + bad = 0; + switch (name->len) { +#define X(s) \ + case sizeof("" s) - 1: \ + bad = memcmp(name->data, s, sizeof(s) - 1) == 0; \ + break; + X("upgrade"); + X("transfer-encoding"); +#undef X + case 10: + switch (name->data[0]) { + case 'c': + bad = memcmp(name->data + 1, "onnection", 9) == 0; + break; + case 'k': + bad = memcmp(name->data + 1, "eep-alive", 9) == 0; + break; + default: + break; + } + break; + case 2: + /* te: trailiers is allowed, all other te values forbidden */ + bad = name->data[0] == 't' && name->data[1] == 'e' + && !(value->len == 8 && memcmp(value->data, "trailers", 8) == 0); + break; + } + + /* Proxy-* headers are not allowed */ + if (name->len >= 6 && memcmp(name->data, "proxy-", 6) == 0) { + bad = 1; + } + + if (bad) { + ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, + "client sent forbidden hop-by-hop header \"%V\" with " + "value: \"%V\"", name, value); + + return NGX_ERROR; + } return NGX_OK; } #endif