diff --git a/actix-files/CHANGES.md b/actix-files/CHANGES.md index 439bf59ad..6e2a241ac 100644 --- a/actix-files/CHANGES.md +++ b/actix-files/CHANGES.md @@ -1,8 +1,6 @@ # Changes ## Unreleased - 2021-xx-xx -* Fix `PathBufWrap::parse_path` to error if the `path` has `".."`. This is to - prevent directory traversal attacks. ## 0.6.0-beta.2 - 2021-02-10 diff --git a/actix-files/src/path_buf.rs b/actix-files/src/path_buf.rs index e6463f68c..dd8e5b503 100644 --- a/actix-files/src/path_buf.rs +++ b/actix-files/src/path_buf.rs @@ -21,13 +21,13 @@ impl FromStr for PathBufWrap { impl PathBufWrap { /// Parse a path, giving the choice of allowing hidden files to be considered valid segments. - /// If the path contains `".."`, an error will be returned to prevent someone being able - /// to traverse the filesystem. pub fn parse_path(path: &str, hidden_files: bool) -> Result { let mut buf = PathBuf::new(); for segment in path.split('/') { - if !hidden_files && segment.starts_with('.') { + if segment == ".." { + buf.pop(); + } else if !hidden_files && segment.starts_with('.') { return Err(UriSegmentError::BadStart('.')); } else if segment.starts_with('*') { return Err(UriSegmentError::BadStart('*')); @@ -41,8 +41,6 @@ impl PathBufWrap { continue; } else if cfg!(windows) && segment.contains('\\') { return Err(UriSegmentError::BadChar('\\')); - } else if segment.contains("..") { - return Err(UriSegmentError::BadStart('.')); } else { buf.push(segment) } @@ -101,12 +99,8 @@ mod tests { PathBuf::from_iter(vec!["seg1", "seg2"]) ); assert_eq!( - PathBufWrap::from_str("/seg1/../seg2/").map(|t| t.0), - Err(UriSegmentError::BadStart('.')) - ); - assert_eq!( - PathBufWrap::from_str("/seg1/..%5c/..%5c/seg2/test.txt").map(|t| t.0), - Err(UriSegmentError::BadStart('.')) + PathBufWrap::from_str("/seg1/../seg2/").unwrap().0, + PathBuf::from_iter(vec!["seg2"]) ); } @@ -121,10 +115,5 @@ mod tests { PathBufWrap::parse_path("/test/.tt", true).unwrap().0, PathBuf::from_iter(vec!["test", ".tt"]) ); - - assert_eq!( - PathBufWrap::parse_path("/seg1/..%5c/..%5c/seg2/test.txt", true).map(|t| t.0), - Err(UriSegmentError::BadStart('.')) - ); } }