fix(http1): reject content-lengths that have a plus sign prefix

The HTTP/1 content-length parser would accept lengths that were prefixed
with a plus sign (for example, `+1234`). The specification restricts the
content-length header to only allow DIGITs, making such a content-length
illegal. Since some HTTP implementations protect against that, and
others mis-interpret the length when the plus sign is present, this
fixes hyper to always reject such content lengths.

See GHSA-f3pg-qwvg-p99c
This commit is contained in:
Sean McArthur
2021-07-01 12:36:41 -07:00
parent 1068b994df
commit 1fb719e0b6
3 changed files with 87 additions and 6 deletions

View File

@@ -405,6 +405,44 @@ fn get_chunked_response_with_ka() {
read_until(&mut req, |buf| buf.ends_with(quux)).expect("reading 2");
}
#[test]
fn post_with_content_length_body() {
let server = serve();
let mut req = connect(server.addr());
req.write_all(
b"\
POST / HTTP/1.1\r\n\
Content-Length: 5\r\n\
\r\n\
hello\
",
)
.unwrap();
req.read(&mut [0; 256]).unwrap();
assert_eq!(server.body(), b"hello");
}
#[test]
fn post_with_invalid_prefix_content_length() {
let server = serve();
let mut req = connect(server.addr());
req.write_all(
b"\
POST / HTTP/1.1\r\n\
Content-Length: +5\r\n\
\r\n\
hello\
",
)
.unwrap();
let mut buf = [0; 256];
let _n = req.read(&mut buf).unwrap();
let expected = "HTTP/1.1 400 Bad Request\r\n";
assert_eq!(s(&buf[..expected.len()]), expected);
}
#[test]
fn post_with_chunked_body() {
let server = serve();