aboutsummaryrefslogtreecommitdiff
path: root/src/http/v3/ngx_http_v3_request.c
diff options
context:
space:
mode:
authorRoman Arutyunyan <arut@nginx.com>2020-05-19 15:34:00 +0300
committerRoman Arutyunyan <arut@nginx.com>2020-05-19 15:34:00 +0300
commitd25937c2b596013874fcb049f10b28270ee49e29 (patch)
tree023bebd18eb7da6995d93c650f97bfcea9976683 /src/http/v3/ngx_http_v3_request.c
parent6abb50658fcdf6ab92a4bc9042cd7dd9bb413850 (diff)
downloadnginx-d25937c2b596013874fcb049f10b28270ee49e29.tar.gz
nginx-d25937c2b596013874fcb049f10b28270ee49e29.zip
HTTP/3: restricted symbols in header names.
As per HTTP/3 draft 27, a request or response containing uppercase header field names MUST be treated as malformed. Also, existing rules applied when parsing HTTP/1 header names are also applied to HTTP/3 header names: - null character is not allowed - underscore character may or may not be treated as invalid depending on the value of "underscores_in_headers" - all non-alphanumeric characters with the exception of '-' are treated as invalid Also, the r->locase_header field is now filled while parsing an HTTP/3 header. Error logging for invalid headers is fixed as well.
Diffstat (limited to 'src/http/v3/ngx_http_v3_request.c')
-rw-r--r--src/http/v3/ngx_http_v3_request.c49
1 files changed, 46 insertions, 3 deletions
diff --git a/src/http/v3/ngx_http_v3_request.c b/src/http/v3/ngx_http_v3_request.c
index 2bb627489..59b8ce5b8 100644
--- a/src/http/v3/ngx_http_v3_request.c
+++ b/src/http/v3/ngx_http_v3_request.c
@@ -116,16 +116,23 @@ failed:
ngx_int_t
-ngx_http_v3_parse_header(ngx_http_request_t *r, ngx_buf_t *b)
+ngx_http_v3_parse_header(ngx_http_request_t *r, ngx_buf_t *b,
+ ngx_uint_t allow_underscores)
{
+ u_char ch;
ngx_int_t rc;
ngx_str_t *name, *value;
+ ngx_uint_t hash, i, n;
ngx_connection_t *c;
ngx_http_v3_parse_headers_t *st;
c = r->connection;
st = r->h3_parse;
+ if (st->header_rep.state == 0) {
+ r->invalid_header = 0;
+ }
+
if (st->state == 0) {
if (r->header_name_start == NULL) {
name = &st->header_rep.header.name;
@@ -164,9 +171,45 @@ done:
r->header_name_end = name->data + name->len;
r->header_start = value->data;
r->header_end = value->data + value->len;
- r->header_hash = ngx_hash_key(name->data, name->len);
- /* XXX r->lowcase_index = i; */
+ hash = 0;
+ i = 0;
+
+ for (n = 0; n < name->len; n++) {
+ ch = name->data[n];
+
+ if (ch >= 'A' && ch <= 'Z') {
+ /*
+ * A request or response containing uppercase
+ * header field names MUST be treated as malformed
+ */
+ return NGX_HTTP_PARSE_INVALID_HEADER;
+ }
+
+ if (ch == '\0') {
+ return NGX_HTTP_PARSE_INVALID_HEADER;
+ }
+
+ if (ch == '_' && !allow_underscores) {
+ r->invalid_header = 1;
+ continue;
+ }
+
+ if ((ch < 'a' || ch > 'z')
+ && (ch < '0' || ch > '9')
+ && ch != '-' && ch != '_')
+ {
+ r->invalid_header = 1;
+ continue;
+ }
+
+ hash = ngx_hash(hash, ch);
+ r->lowcase_header[i++] = ch;
+ i &= (NGX_HTTP_LC_HEADER_LEN - 1);
+ }
+
+ r->header_hash = hash;
+ r->lowcase_index = i;
return NGX_OK;
}