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 ae76c64300
commit 279ae488a4

View File

@ -1097,6 +1097,7 @@ ngx_int_t
ngx_http_v23_fixup_header(ngx_http_request_t *r, ngx_str_t *name,
ngx_str_t *value)
{
int bad;
u_char ch;
ngx_str_t tmp;
ngx_uint_t i;
@ -1154,6 +1155,37 @@ ngx_http_v23_fixup_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");
X("proxy-connection");
X("proxy-authorization");
X("proxy-authenticate");
#undef X
case 10:
bad = memcmp(name->data, "connection", 10) == 0
|| memcmp(name->data, "keep-alive", 10) == 0;
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;
}
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;
}
tmp = *value;
if (tmp.data[0] > 0x20 && tmp.data[tmp.len - 1] > 0x20) {