yesodweb / wai

Haskell Web Application Interface
MIT License
834 stars 263 forks source link

"is http2" detection doesn't seem quite correct #989

Closed mitchellwrosen closed 6 months ago

mitchellwrosen commented 6 months ago

https://github.com/yesodweb/wai/blob/2a7399f5229f6a8ea675a20cf0cf8f69ba8b9f72/warp/Network/Wai/Handler/Warp/Run.hs#L390

Here we seem to determine whether this is an HTTP/2 request by reading some bytes off the wire, and if they are PRI, it is.

But there's no guarantee we read 4 bytes, of course. We could read PR, determine this isn't an HTTP/2 request, go down the HTTP/1 code path and proceed to read the remaining I!

kazu-yamamoto commented 6 months ago

Right. But a question is whether or not we should rescue this corner case.

mitchellwrosen commented 6 months ago

Why is that a question?

kazu-yamamoto commented 6 months ago

Clients to send a few bytes at the beginning seem malicious. Should we treat them kindly?

davean commented 6 months ago

This sounds like an argument for ossification https://en.wikipedia.org/wiki/Protocol_ossification over correctness. Why shouldn't it be able to handle a semantically correct connection if the server chooses to?

On Tue, May 7, 2024 at 7:29 PM Kazu Yamamoto @.***> wrote:

Clients to send a few bytes at the beginning seem malicious. Should we treat them kindly?

— Reply to this email directly, view it on GitHub https://github.com/yesodweb/wai/issues/989#issuecomment-2099470932, or unsubscribe https://github.com/notifications/unsubscribe-auth/AABZLS7V2ZZFVPWO2RLE6VLZBFPUTAVCNFSM6AAAAABHI5Z2ZSVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDAOJZGQ3TAOJTGI . You are receiving this because you are subscribed to this thread.Message ID: @.***>

mitchellwrosen commented 6 months ago

@kazu-yamamoto For sure; it's clearly a corner case. Nonetheless, it's exactly the kind of thing I would expect to be handled correctly in a web server!

Regarding this,

Clients to send a few bytes at the beginning seem malicious.

My understanding is that even if an honest client sends a legitimately-sized "packet" of bytes, the server can nonetheless read an arbitrary number of them at each call to read().