mirror of
https://github.com/nginx/nginx.git
synced 2025-08-01 02:56:15 +08:00
HTTP/3: client pseudo-headers restrictions.
- :method, :path and :scheme are expected exactly once and not empty - :method and :scheme character validation is added - :authority cannot appear more than once
This commit is contained in:
parent
9e489d208f
commit
4e312daa7e
@ -300,6 +300,7 @@ static ngx_int_t
|
|||||||
ngx_http_v3_process_pseudo_header(ngx_http_request_t *r, ngx_str_t *name,
|
ngx_http_v3_process_pseudo_header(ngx_http_request_t *r, ngx_str_t *name,
|
||||||
ngx_str_t *value)
|
ngx_str_t *value)
|
||||||
{
|
{
|
||||||
|
u_char ch, c;
|
||||||
ngx_uint_t i;
|
ngx_uint_t i;
|
||||||
|
|
||||||
if (r->request_line.len) {
|
if (r->request_line.len) {
|
||||||
@ -310,6 +311,18 @@ ngx_http_v3_process_pseudo_header(ngx_http_request_t *r, ngx_str_t *name,
|
|||||||
|
|
||||||
if (name->len == 7 && ngx_strncmp(name->data, ":method", 7) == 0) {
|
if (name->len == 7 && ngx_strncmp(name->data, ":method", 7) == 0) {
|
||||||
|
|
||||||
|
if (r->method_name.len) {
|
||||||
|
ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
|
||||||
|
"client sent duplicate \":method\" header");
|
||||||
|
goto failed;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value->len == 0) {
|
||||||
|
ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
|
||||||
|
"client sent empty \":method\" header");
|
||||||
|
goto failed;
|
||||||
|
}
|
||||||
|
|
||||||
r->method_name = *value;
|
r->method_name = *value;
|
||||||
|
|
||||||
for (i = 0; i < sizeof(ngx_http_v3_methods)
|
for (i = 0; i < sizeof(ngx_http_v3_methods)
|
||||||
@ -325,6 +338,16 @@ ngx_http_v3_process_pseudo_header(ngx_http_request_t *r, ngx_str_t *name,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < value->len; i++) {
|
||||||
|
ch = value->data[i];
|
||||||
|
|
||||||
|
if ((ch < 'A' || ch > 'Z') && ch != '_' && ch != '-') {
|
||||||
|
ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
|
||||||
|
"client sent invalid method: \"%V\"", value);
|
||||||
|
goto failed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||||
"http3 method \"%V\" %ui", value, r->method);
|
"http3 method \"%V\" %ui", value, r->method);
|
||||||
return NGX_OK;
|
return NGX_OK;
|
||||||
@ -332,6 +355,18 @@ ngx_http_v3_process_pseudo_header(ngx_http_request_t *r, ngx_str_t *name,
|
|||||||
|
|
||||||
if (name->len == 5 && ngx_strncmp(name->data, ":path", 5) == 0) {
|
if (name->len == 5 && ngx_strncmp(name->data, ":path", 5) == 0) {
|
||||||
|
|
||||||
|
if (r->uri_start) {
|
||||||
|
ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
|
||||||
|
"client sent duplicate \":path\" header");
|
||||||
|
goto failed;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value->len == 0) {
|
||||||
|
ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
|
||||||
|
"client sent empty \":path\" header");
|
||||||
|
goto failed;
|
||||||
|
}
|
||||||
|
|
||||||
r->uri_start = value->data;
|
r->uri_start = value->data;
|
||||||
r->uri_end = value->data + value->len;
|
r->uri_end = value->data + value->len;
|
||||||
|
|
||||||
@ -349,6 +384,39 @@ ngx_http_v3_process_pseudo_header(ngx_http_request_t *r, ngx_str_t *name,
|
|||||||
|
|
||||||
if (name->len == 7 && ngx_strncmp(name->data, ":scheme", 7) == 0) {
|
if (name->len == 7 && ngx_strncmp(name->data, ":scheme", 7) == 0) {
|
||||||
|
|
||||||
|
if (r->schema.len) {
|
||||||
|
ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
|
||||||
|
"client sent duplicate \":scheme\" header");
|
||||||
|
goto failed;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value->len == 0) {
|
||||||
|
ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
|
||||||
|
"client sent empty \":scheme\" header");
|
||||||
|
goto failed;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < value->len; i++) {
|
||||||
|
ch = value->data[i];
|
||||||
|
|
||||||
|
c = (u_char) (ch | 0x20);
|
||||||
|
if (c >= 'a' && c <= 'z') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (((ch >= '0' && ch <= '9')
|
||||||
|
|| ch == '+' || ch == '-' || ch == '.')
|
||||||
|
&& i > 0)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
|
||||||
|
"client sent invalid \":scheme\" header: \"%V\"",
|
||||||
|
value);
|
||||||
|
goto failed;
|
||||||
|
}
|
||||||
|
|
||||||
r->schema = *value;
|
r->schema = *value;
|
||||||
|
|
||||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||||
@ -358,6 +426,12 @@ ngx_http_v3_process_pseudo_header(ngx_http_request_t *r, ngx_str_t *name,
|
|||||||
|
|
||||||
if (name->len == 10 && ngx_strncmp(name->data, ":authority", 10) == 0) {
|
if (name->len == 10 && ngx_strncmp(name->data, ":authority", 10) == 0) {
|
||||||
|
|
||||||
|
if (r->host_start) {
|
||||||
|
ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
|
||||||
|
"client sent duplicate \":authority\" header");
|
||||||
|
goto failed;
|
||||||
|
}
|
||||||
|
|
||||||
r->host_start = value->data;
|
r->host_start = value->data;
|
||||||
r->host_end = value->data + value->len;
|
r->host_end = value->data + value->len;
|
||||||
|
|
||||||
@ -388,6 +462,24 @@ ngx_http_v3_init_pseudo_headers(ngx_http_request_t *r)
|
|||||||
return NGX_OK;
|
return NGX_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (r->method_name.len == 0) {
|
||||||
|
ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
|
||||||
|
"client sent no \":method\" header");
|
||||||
|
goto failed;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (r->schema.len == 0) {
|
||||||
|
ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
|
||||||
|
"client sent no \":scheme\" header");
|
||||||
|
goto failed;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (r->uri_start == NULL) {
|
||||||
|
ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
|
||||||
|
"client sent no \":path\" header");
|
||||||
|
goto failed;
|
||||||
|
}
|
||||||
|
|
||||||
len = r->method_name.len + 1
|
len = r->method_name.len + 1
|
||||||
+ (r->uri_end - r->uri_start) + 1
|
+ (r->uri_end - r->uri_start) + 1
|
||||||
+ sizeof("HTTP/3.0") - 1;
|
+ sizeof("HTTP/3.0") - 1;
|
||||||
|
Loading…
Reference in New Issue
Block a user