Hello, > > Could the community share their thoughts on introducing a directive to > > cap the number of HTTP request headers? While we currently have the > > ability to limit client HTTP request buffer size, having more specific > > control over the number of headers could be advantageous. > > I personally tend to think that buffer size limit is enough for > [free]nginx itself. On the other hand, an additional limit on the > number of request headers might be beneficial to protect backend > servers, and might worth adding.
thanks! a possible patch is attached. max
diff --git a/ports/netflix/nginx/files/nginx/src/http/ngx_http_core_module.c b/ports/netflix/nginx/files/nginx/src/http/ngx_http_core_module.c index e26705475e46..b12951fd2a09 100644 --- a/ports/netflix/nginx/files/nginx/src/http/ngx_http_core_module.c +++ b/ports/netflix/nginx/files/nginx/src/http/ngx_http_core_module.c @@ -287,6 +287,13 @@ static ngx_command_t ngx_http_core_commands[] = { offsetof(ngx_http_core_srv_conf_t, underscores_in_headers), NULL }, + { ngx_string("max_request_headers"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1, + ngx_conf_set_num_slot, + NGX_HTTP_SRV_CONF_OFFSET, + offsetof(ngx_http_core_srv_conf_t, max_request_headers), + NULL }, + { ngx_string("location"), NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_BLOCK|NGX_CONF_TAKE12, ngx_http_core_location, @@ -3508,6 +3515,7 @@ ngx_http_core_create_srv_conf(ngx_conf_t *cf) cscf->ignore_invalid_headers = NGX_CONF_UNSET; cscf->merge_slashes = NGX_CONF_UNSET; cscf->underscores_in_headers = NGX_CONF_UNSET; + cscf->max_request_headers = NGX_CONF_UNSET_UINT; cscf->file_name = cf->conf_file->file.name.data; cscf->line = cf->conf_file->line; @@ -3554,6 +3562,9 @@ ngx_http_core_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child) ngx_conf_merge_value(conf->underscores_in_headers, prev->underscores_in_headers, 0); + ngx_conf_merge_value(conf->max_request_headers, + prev->max_request_headers, 128); + if (conf->server_names.nelts == 0) { /* the array has 4 empty preallocated elements, so push cannot fail */ sn = ngx_array_push(&conf->server_names); diff --git a/ports/netflix/nginx/files/nginx/src/http/ngx_http_core_module.h b/ports/netflix/nginx/files/nginx/src/http/ngx_http_core_module.h index 3ed9d1632eec..1a5853fc7dc1 100644 --- a/ports/netflix/nginx/files/nginx/src/http/ngx_http_core_module.h +++ b/ports/netflix/nginx/files/nginx/src/http/ngx_http_core_module.h @@ -212,6 +212,7 @@ typedef struct { ngx_flag_t ignore_invalid_headers; ngx_flag_t merge_slashes; ngx_flag_t underscores_in_headers; + ngx_uint_t max_request_headers; /* max number of request headers */ unsigned listen:1; #if (NGX_PCRE) diff --git a/ports/netflix/nginx/files/nginx/src/http/ngx_http_request.c b/ports/netflix/nginx/files/nginx/src/http/ngx_http_request.c index 2ed0d99c168b..1ff03b215880 100644 --- a/ports/netflix/nginx/files/nginx/src/http/ngx_http_request.c +++ b/ports/netflix/nginx/files/nginx/src/http/ngx_http_request.c @@ -1728,6 +1728,7 @@ ngx_http_process_request_headers(ngx_event_t *rev) ngx_http_request_t *r; ngx_http_core_srv_conf_t *cscf; ngx_http_core_main_conf_t *cmcf; + ngx_list_part_t *part; c = rev->data; r = c->data; @@ -1816,6 +1817,25 @@ ngx_http_process_request_headers(ngx_event_t *rev) continue; } + /* apply request header limit */ + + for (rv = 0, part = &r->headers_in.headers.part; + part != NULL; + part = part->next) { + rv += part->nelts; + } + + if (rv >= cscf->max_request_headers) { + ngx_log_error(NGX_LOG_INFO, c->log, 0, + "client sent too many request headers, have %i, limit is %ui", + rv, cscf->max_request_headers); + + r->lingering_close = 1; + ngx_http_finalize_request(r, NGX_HTTP_REQUEST_ENTITY_TOO_LARGE); + + break; + } + /* a header line has been parsed successfully */ h = ngx_list_push(&r->headers_in.headers);
-- nginx-devel mailing list nginx-devel@freenginx.org https://freenginx.org/mailman/listinfo/nginx-devel