fix bug where URIs could traverse server filesystem

This commit is contained in:
Thomas Harmon 2021-03-09 11:14:34 -05:00
parent 5b4105e1e6
commit e6fcea67f4
2 changed files with 18 additions and 5 deletions

View File

@ -1,6 +1,8 @@
# 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

View File

@ -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<Self, UriSegmentError> {
let mut buf = PathBuf::new();
for segment in path.split('/') {
if segment == ".." {
buf.pop();
} else if !hidden_files && segment.starts_with('.') {
if !hidden_files && segment.starts_with('.') {
return Err(UriSegmentError::BadStart('.'));
} else if segment.starts_with('*') {
return Err(UriSegmentError::BadStart('*'));
@ -41,6 +41,8 @@ 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)
}
@ -99,8 +101,12 @@ mod tests {
PathBuf::from_iter(vec!["seg1", "seg2"])
);
assert_eq!(
PathBufWrap::from_str("/seg1/../seg2/").unwrap().0,
PathBuf::from_iter(vec!["seg2"])
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('.'))
);
}
@ -115,5 +121,10 @@ 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('.'))
);
}
}