valyala/fasthttp

FastHTTP doesn't adequately validate HTTP methods

kenballus opened this issue · 0 comments

Description

RFCs 9110 and 9112 specify that only the following characters are permitted within HTTP methods:

"!" / "#" / "$" / "%" / "&" / "'" / "*"
/ "+" / "-" / "." / "^" / "_" / "`" / "|" / "~"
/ DIGIT / ALPHA

FastHTTP doesn't enforce this rule. In particular, the following disallowed characters are erroneously permitted in HTTP methods:

  • \x00-\x09, inclusive
  • \x0b-\x1f, inclusive
  • ", (, ), ,, /, :, ;, <, ., =, >, ?, @, [, \, ], {, }
  • \x7f-\xff, inclusive

To reproduce

You can observe this for yourself by sending the following request to a FastHTTP server that echos each received request's method, such as this one.

  1. Start the aforementioned server.
  2. Run the following command, which contains a very invalid method, and extract the echoed method from the response:
printf '\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\x0b\x0c\r\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 / HTTP/1.1\r\nHost: whatever\r\n\r\n' \
    | timeout 1 nc localhost 80
HTTP/1.1 200 OK
Server: fasthttp
Date: Mon, 08 Jul 2024 17:43:37 GMT
Content-Type: text/plain; charset=utf-8
Content-Length: 369

{"headers":[["SG9zdA==","d2hhdGV2ZXI="],["Q29udGVudC1MZW5ndGg=","MA=="]],"body":"","method":"AAECAwQFBgcICQsMDQ4PEBESExQVFhcYGRobHB0eHyIoKSwvOjs8PT4/QFtcXXt9f4CBgoOEhYaHiImKi4yNjo+QkZKTlJWWl5iZmpucnZ6foKGio6SlpqeoqaqrrK2ur7CxsrO0tba3uLm6u7y9vr/AwcLDxMXGx8jJysvMzc7P0NHS09TV1tfY2drb3N3e3+Dh4uPk5ebn6Onq6+zt7u/w8fLz9PX29/j5+vv8/f7/","version":"SFRUUC8xLjE=","uri":"Lw=="}
  1. Observe that the invalid method was not rejected:
printf 'AAECAwQFBgcICQsMDQ4PEBESExQVFhcYGRobHB0eHyIoKSwvOjs8PT4/QFtcXXt9f4CBgoOEhYaHiImKi4yNjo+QkZKTlJWWl5iZmpucnZ6foKGio6SlpqeoqaqrrK2ur7CxsrO0tba3uLm6u7y9vr/AwcLDxMXGx8jJysvMzc7P0NHS09TV1tfY2drb3N3e3+Dh4uPk5ebn6Onq6+zt7u/w8fLz9PX29/j5+vv8/f7/' \
    | base64 -d \
    | xxd
00000000: 0001 0203 0405 0607 0809 0b0c 0d0e 0f10  ................
00000010: 1112 1314 1516 1718 191a 1b1c 1d1e 1f22  ..............."
00000020: 2829 2c2f 3a3b 3c3d 3e3f 405b 5c5d 7b7d  (),/:;<=>?@[\]{}
00000030: 7f80 8182 8384 8586 8788 898a 8b8c 8d8e  ................
00000040: 8f90 9192 9394 9596 9798 999a 9b9c 9d9e  ................
00000050: 9fa0 a1a2 a3a4 a5a6 a7a8 a9aa abac adae  ................
00000060: afb0 b1b2 b3b4 b5b6 b7b8 b9ba bbbc bdbe  ................
00000070: bfc0 c1c2 c3c4 c5c6 c7c8 c9ca cbcc cdce  ................
00000080: cfd0 d1d2 d3d4 d5d6 d7d8 d9da dbdc ddde  ................
00000090: dfe0 e1e2 e3e4 e5e6 e7e8 e9ea ebec edee  ................
000000a0: eff0 f1f2 f3f4 f5f6 f7f8 f9fa fbfc fdfe  ................
000000b0: ff                                       .                                     .

What other servers do

Nearly all other HTTP implementations reject the above request.
These include AIOHTTP, Apache httpd, Deno, Go net/http, Gunicorn, H2O, Hyper, Hypercorn, Jetty, Libevent, Libsoup, Lighttpd, Mongoose, Netty, Nginx, Node.js, LiteSpeed, Passenger, Puma, Tomcat, Twisted, OpenWrt uhttpd, Uvicorn, Waitress, WEBrick, OpenBSD httpd, Apache Traffic Server, nghttpx, Pingora, Pound, Squid, Varnish, Akamai GHost, Google Classic Application Load Balacner, Envoy, and OpenBSD relayd.