@@ -635,7 +635,6 @@ impl ChunkedState {
635635 }
636636}
637637
638- // TODO: disallow Transfer-Encoding, Content-Length, Trailer, etc in trailers ??
639638fn 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