From c6b5517c95f033da108bf4a9b7bc12abc6c16849 Mon Sep 17 00:00:00 2001 From: Harry Barber Date: Thu, 8 Sep 2022 14:14:49 +0000 Subject: [PATCH 1/2] Add unsanitary_path test --- .../src/routing/request_spec.rs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/rust-runtime/aws-smithy-http-server/src/routing/request_spec.rs b/rust-runtime/aws-smithy-http-server/src/routing/request_spec.rs index b30be54191..b28fc7b51f 100644 --- a/rust-runtime/aws-smithy-http-server/src/routing/request_spec.rs +++ b/rust-runtime/aws-smithy-http-server/src/routing/request_spec.rs @@ -469,4 +469,22 @@ mod tests { assert_eq!(Match::Yes, label_spec.matches(&req(method, uri, None))); } } + + #[test] + fn unsanitary_path() { + let spec = RequestSpec::from_parts( + Method::GET, + vec![ + PathSegment::Literal(String::from("ReDosLiteral")), + PathSegment::Label, + PathSegment::Literal(String::from("(a+)+")), + ], + Vec::new(), + ); + + assert_eq!( + Match::Yes, + spec.matches(&req(&Method::GET, "/ReDosLiteral/abc/(a+)+", None)) + ); + } } From d65f138d82031d8b07955a1fc7049343cce40997 Mon Sep 17 00:00:00 2001 From: Harry Barber Date: Thu, 8 Sep 2022 14:15:35 +0000 Subject: [PATCH 2/2] Escape literals --- .../aws-smithy-http-server/src/routing/request_spec.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/rust-runtime/aws-smithy-http-server/src/routing/request_spec.rs b/rust-runtime/aws-smithy-http-server/src/routing/request_spec.rs index b28fc7b51f..5e50305886 100644 --- a/rust-runtime/aws-smithy-http-server/src/routing/request_spec.rs +++ b/rust-runtime/aws-smithy-http-server/src/routing/request_spec.rs @@ -3,6 +3,8 @@ * SPDX-License-Identifier: Apache-2.0 */ +use std::borrow::Cow; + use http::Request; use regex::Regex; @@ -104,13 +106,13 @@ impl From<&PathSpec> for Regex { .0 .iter() .map(|segment_spec| match segment_spec { - PathSegment::Literal(literal) => literal, + PathSegment::Literal(literal) => Cow::Owned(regex::escape(literal)), // TODO(https://github.com/awslabs/smithy/issues/975) URL spec says it should be ASCII but this regex accepts UTF-8: // `*` instead of `+` because the empty string `""` can be bound to a label. - PathSegment::Label => "[^/]*", - PathSegment::Greedy => ".*", + PathSegment::Label => Cow::Borrowed("[^/]*"), + PathSegment::Greedy => Cow::Borrowed(".*"), }) - .fold(String::new(), |a, b| a + sep + b) + .fold(String::new(), |a, b| a + sep + &b) }; Regex::new(&format!("^{}$", re)).expect("invalid `Regex` from `PathSpec`; please file a bug report under https://github.com/awslabs/smithy-rs/issues")