The directive limits the number of request headers accepted from clients.
While the total amount of headers is believed to be sufficiently limited
by the existing buffer size limits (client_header_buffer_size and
large_client_header_buffers), the additional limit on the number of headers
might be beneficial to better protect backend servers.
Requested by Maksim Yevmenkin.
Signed-off-by: Elijah Zupancic <e.zupancic@f5.com>
Origin: <https://freenginx.org/hg/nginx/rev/
199dc0d6b05be814b5c811876c20af58cd361fea>
offsetof(ngx_http_core_srv_conf_t, large_client_header_buffers),
NULL },
+ { ngx_string("max_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_headers),
+ NULL },
+
{ ngx_string("ignore_invalid_headers"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
ngx_conf_set_flag_slot,
cscf->request_pool_size = NGX_CONF_UNSET_SIZE;
cscf->client_header_timeout = NGX_CONF_UNSET_MSEC;
cscf->client_header_buffer_size = NGX_CONF_UNSET_SIZE;
+ cscf->max_headers = NGX_CONF_UNSET_UINT;
cscf->ignore_invalid_headers = NGX_CONF_UNSET;
cscf->merge_slashes = NGX_CONF_UNSET;
cscf->underscores_in_headers = NGX_CONF_UNSET;
return NGX_CONF_ERROR;
}
+ ngx_conf_merge_uint_value(conf->max_headers, prev->max_headers, 1000);
+
ngx_conf_merge_value(conf->ignore_invalid_headers,
prev->ignore_invalid_headers, 1);
ngx_msec_t client_header_timeout;
+ ngx_uint_t max_headers;
+
ngx_flag_t ignore_invalid_headers;
ngx_flag_t merge_slashes;
ngx_flag_t underscores_in_headers;
/* a header line has been parsed successfully */
+ if (r->headers_in.count++ >= cscf->max_headers) {
+ r->lingering_close = 1;
+ ngx_log_error(NGX_LOG_INFO, c->log, 0,
+ "client sent too many header lines");
+ ngx_http_finalize_request(r,
+ NGX_HTTP_REQUEST_HEADER_TOO_LARGE);
+ break;
+ }
+
h = ngx_list_push(&r->headers_in.headers);
if (h == NULL) {
ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
typedef struct {
ngx_list_t headers;
+ ngx_uint_t count;
ngx_table_elt_t *host;
ngx_table_elt_t *connection;
}
} else {
+ cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
+
+ if (r->headers_in.count++ >= cscf->max_headers) {
+ ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
+ "client sent too many header lines");
+ ngx_http_finalize_request(r, NGX_HTTP_REQUEST_HEADER_TOO_LARGE);
+ goto error;
+ }
+
h = ngx_list_push(&r->headers_in.headers);
if (h == NULL) {
return ngx_http_v2_connection_error(h2c,
}
} else {
+ cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
+
+ if (r->headers_in.count++ >= cscf->max_headers) {
+ ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
+ "client sent too many header lines");
+ ngx_http_finalize_request(r, NGX_HTTP_REQUEST_HEADER_TOO_LARGE);
+ return NGX_ERROR;
+ }
+
h = ngx_list_push(&r->headers_in.headers);
if (h == NULL) {
ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);