From 090ee08b03266491944b136f9fcd96bfaf2015b4 Mon Sep 17 00:00:00 2001 From: Sean McArthur Date: Tue, 20 Jul 2021 17:11:15 -0700 Subject: [PATCH] refactor(http1): reject newlines in chunked extensions We don't really care what bytes are in chunked extensions. We ignore them until we find a CRLF. However, some other HTTP implementations may only look for a LF, and forget that chunked requires the CR as well. To save them from themselves, this makes hyper reject any chunked extensions that include an LF byte. This isn't a *bug*. No one ever cares what's in the extensions. This is meant as a way to help implementations that don't decoded chunked encoding correctly. This shouldn't affect really anyone in the real world. --- src/proto/h1/decode.rs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/proto/h1/decode.rs b/src/proto/h1/decode.rs index 5d1c1c3c..1e6027d9 100644 --- a/src/proto/h1/decode.rs +++ b/src/proto/h1/decode.rs @@ -268,8 +268,18 @@ impl ChunkedState { rdr: &mut R, ) -> Poll> { trace!("read_extension"); + // We don't care about extensions really at all. Just ignore them. + // They "end" at the next CRLF. + // + // However, some implementations may not check for the CR, so to save + // them from themselves, we reject extensions containing plain LF as + // well. match byte!(rdr, cx) { b'\r' => Poll::Ready(Ok(ChunkedState::SizeLf)), + b'\n' => Poll::Ready(Err(io::Error::new( + io::ErrorKind::InvalidData, + "invalid chunk extension contains newline", + ))), _ => Poll::Ready(Ok(ChunkedState::Extension)), // no supported extensions } } @@ -537,6 +547,7 @@ mod tests { read_err("1 invalid extension\r\n", InvalidInput).await; read_err("1 A\r\n", InvalidInput).await; read_err("1;no CRLF", UnexpectedEof).await; + read_err("1;reject\nnewlines\r\n", InvalidData).await; // Overflow read_err("f0000000000000003\r\n", InvalidData).await; }