View Issue Details

IDProjectCategoryView StatusLast Update
0009634libmicrohttpdotherpublic2025-03-18 14:08
Reporterkenballus Assigned To 
PrioritynormalSeverityminorReproducibilityalways
Status newResolutionopen 
Summary0009634: Insufficient request header validation
DescriptionRFC 9110 specifies that only the following bytes are allowed within header names:
> tchar = "!" / "#" / "$" / "%" / "&" / "'" / "*"
        / "+" / "-" / "." / "^" / "_" / "`" / "|" / "~"
        / DIGIT / ALPHA

libmicrohttpd does not enforce this rule. Instead, it accepts *any byte whatsoever* in header names, except SP (0x20), HTAB, (0x09), LF (0x0a), CR (0x0d), ':' (0x3a), and NUL (0x00).

I suggest that libmicrohttpd comply with the RFC by responding 400 to invalid requests. This is what most other web servers do, because accepting forbidden bytes opens the door to misinterpretations between origin and gateway servers.
Steps To Reproduce1. Start a libmicrohttpd server that echoes request header names, like this one: https://github.com/narfindustries/http-garden/blob/main/images/libmicrohttpd/garden_server.c

2. Send it a request with a header containing every invalid header name byte except 0x20, 0x09, 0x0a, 0x0d, 0x3a, and 0x00:
```
printf 'GET / HTTP/1.1\r\nHost: whatever\r\n\x01\x02\x03\x04\x05\x06\x07\x08\x0b\x0c\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"(),/;<=>?@[\\]{}\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff: some-value\r\n\r\n' \
  | timeout 1 ncat localhost 80 \
  | grep "headers" \
  | jq '.["headers"][1][0]' \
  | xargs echo \
  | base64 -d \
  | xxd
```

3. Observe that the invalid bytes made it into the request's header name unchanged:
```
00000000: 0102 0304 0506 0708 0b0c 0e0f 1011 1213 ................
00000010: 1415 1617 1819 1a1b 1c1d 1e1f 2228 292c ............"(),
00000020: 2f3b 3c3d 3e3f 405b 5c5d 7b7d 7f80 8182 /;<=>?@[\]{}....
00000030: 8384 8586 8788 898a 8b8c 8d8e 8f90 9192 ................
00000040: 9394 9596 9798 999a 9b9c 9d9e 9fa0 a1a2 ................
00000050: a3a4 a5a6 a7a8 a9aa abac adae afb0 b1b2 ................
00000060: b3b4 b5b6 b7b8 b9ba bbbc bdbe bfc0 c1c2 ................
00000070: c3c4 c5c6 c7c8 c9ca cbcc cdce cfd0 d1d2 ................
00000080: d3d4 d5d6 d7d8 d9da dbdc ddde dfe0 e1e2 ................
00000090: e3e4 e5e6 e7e8 e9ea ebec edee eff0 f1f2 ................
000000a0: f3f4 f5f6 f7f8 f9fa fbfc fdfe ff .............
```
Additional InformationThis behavior is reproducible on a fresh build of the https://git.gnunet.org/libmicrohttpd.git master branch at commit 5e40455beae130dd0dd239a7a2447b88496c3be8.
TagsNo tags attached.

Activities

There are no notes attached to this issue.

Issue History

Date Modified Username Field Change
2025-03-18 14:08 kenballus New Issue