bun icon indicating copy to clipboard operation
bun copied to clipboard

Bun.serve not answers when HTTP header name contains underscore

Open krutoo opened this issue 1 year ago • 8 comments

What version of Bun is running?

0.6.13

What platform is your computer?

Darwin 22.1.0 arm64 arm

What steps can reproduce the bug?

  1. create index.ts with content:
Bun.serve({
  port: 1234,
  fetch() {
    return new Response('Hello, world!');
  },
});
  1. bun run index.ts
  2. Make http request (for example via Postman) with header foo-bar_baz: 1.2.3

What is the expected behavior?

postman get an answer Hello, world!

What do you see instead?

Postman cannot receive response - it freezes on stage "Sending request..."

When i remove this custom header it works perfectly

Additional information

According to this resource: https://www.rfc-editor.org/rfc/rfc9110.html#fields.registry

header names should contains only

- alphanumeric characters
- "."
- "-"

Maybe it is reason why Bun.serve() not anwsers on requests with headers with underscore

krutoo avatar Jul 09 '23 09:07 krutoo

@uNetworkingAB but I didn't claim anything =)

krutoo avatar Jul 13 '23 17:07 krutoo

If we were to add support for this in uWebSockets, I think it'd mean changing these lines:

  • https://github.com/Jarred-Sumner/uWebSockets/blob/master/src/HttpParser.h#L256-L264
  • https://github.com/Jarred-Sumner/uWebSockets/blob/master/src/HttpParser.h#L233-L240

cc @kwhitley

Jarred-Sumner avatar Aug 10 '23 23:08 Jarred-Sumner

I'm not concerned about it accepting the header or not, but about it hanging if you pass such a header. That is a potential Denial Of Service vector.

If the header isn't valid the server should maybe emit a 409 return code instead of hanging. Alternatively it could just close the connection, but a 409 would at least give consumers an indication something is wrong.

That said, most implementations don't validate incoming headers and just pass them on to the application to decide about. Be lenient in what you accept and all that.

nickpalmer avatar Aug 11 '23 08:08 nickpalmer

I'm not concerned about it accepting the header or not, but about it hanging if you pass such a header. That is a potential Denial Of Service vector.

If the header isn't valid the server should maybe emit a 409 return code instead of hanging. Alternatively it could just close the connection, but a 409 would at least give consumers an indication something is wrong.

That said, most implementations don't validate incoming headers and just pass them on to the application to decide about. Be lenient in what you accept and all that.

It treats it the same as other forms of invalid input. It keeps the connection open until a timeout elapses, doesn’t send more data and halts parsing. This is cheap so it’s not likely to be a DoS vector

Jarred-Sumner avatar Aug 11 '23 16:08 Jarred-Sumner

It treats it the same as other forms of invalid input. It keeps the connection open until a timeout elapses, doesn’t send more data and halts parsing. This is cheap so it’s not likely to be a DoS vector

How do other http servers handle something like this? I know nginx, for instance, just ignores those headers... but I would assume in the case of a bad/malformed request, that an error response (e.g. 400?) would be appropriate, rather than a live/stalled connection with no feedback.

kwhitley avatar Aug 11 '23 17:08 kwhitley

@Jarred-Sumner the issue is really important for user-facing services. Right now a website created with Bun doesn't pass LinkedIn Inspector due to headers formatted like X-LI-R2-W-IC-2-com.linkedin.container.dsc: 1

dszymon avatar Jan 17 '24 09:01 dszymon

https://github.com/uNetworking/uWebSockets/releases/tag/v20.60.0

uNetworkingAB avatar Feb 09 '24 21:02 uNetworkingAB

That said, most implementations don't validate incoming headers and just pass them on to the application to decide about. Be lenient in what you accept and all that.

This literally is request smuggling and allows to bypass proxies. That's why the validation must be strict.

I'm not concerned about it accepting the header or not, but about it hanging if you pass such a header. That is a potential Denial Of Service vector.

It's not a DOS vector since the entire HTTP standard is based on accepting anything until you reach CRLFCRLF so the very same behavior of waiting until timeout can be seen for regular use. You get the same exact behavior if you just send the letter "H" and wait until timeout. This is the case for all HTTP servers in existence 😉

uNetworkingAB avatar Feb 09 '24 21:02 uNetworkingAB