HTTP: Reject hop-by-hop headers in HTTP/2 and HTTP/3 requests

RFC9113 and RFC9114 both require requests with connection-specific
headers to be treated as malformed, with the exception of "te: trailers".
Reject requests containing them.
This commit is contained in:
Demi Marie Obenour 2025-03-13 01:36:49 -04:00
parent c68c7adcdb
commit bccf2b1f3b

View File

@ -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