Skip to content

Commit bee33c7

Browse files
committed
fix(http1): reject forbidden trailer fields
1 parent d32b294 commit bee33c7

1 file changed

Lines changed: 19 additions & 1 deletion

File tree

src/proto/h1/decode.rs

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -635,7 +635,6 @@ impl ChunkedState {
635635
}
636636
}
637637

638-
// TODO: disallow Transfer-Encoding, Content-Length, Trailer, etc in trailers ??
639638
fn decode_trailers(buf: &mut BytesMut, count: usize) -> Result<HeaderMap, io::Error> {
640639
let mut trailers = HeaderMap::new();
641640
let mut headers = vec![httparse::EMPTY_HEADER; count];
@@ -654,6 +653,16 @@ fn decode_trailers(buf: &mut BytesMut, count: usize) -> Result<HeaderMap, io::Er
654653
}
655654
};
656655

656+
if name == http::header::CONTENT_LENGTH
657+
|| name == http::header::TRANSFER_ENCODING
658+
|| name == http::header::TRAILER
659+
{
660+
return Err(io::Error::new(
661+
io::ErrorKind::InvalidInput,
662+
format!("Forbidden trailer field: {:?}", &header),
663+
));
664+
}
665+
657666
let value = match HeaderValue::from_bytes(header.value) {
658667
Ok(value) => value,
659668
Err(_) => {
@@ -1164,6 +1173,15 @@ mod tests {
11641173
assert_eq!(values, ["first", "second"]);
11651174
}
11661175

1176+
#[test]
1177+
fn test_decode_trailers_rejects_forbidden_fields() {
1178+
for name in ["Content-Length", "Transfer-Encoding", "Trailer"] {
1179+
let mut buf = BytesMut::from(format!("{name}: value\r\n\r\n").as_bytes());
1180+
let err = decode_trailers(&mut buf, 1).expect_err("forbidden trailer field");
1181+
assert_eq!(err.kind(), io::ErrorKind::InvalidInput);
1182+
}
1183+
}
1184+
11671185
#[tokio::test]
11681186
async fn test_trailer_max_headers_enforced() {
11691187
let h1_max_headers = 10;

0 commit comments

Comments
 (0)