-
Notifications
You must be signed in to change notification settings - Fork 168
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ServeDir/File: Fix build_and_validate_path to prevent hacker from accessing arbitrary files #204
Conversation
Thanks for finding this! |
Have to do some investigation to figure out if not allowing I don't have access to a windows machine but are you able test if other frameworks do the same as tower-http? Warp, tide, and actix-web would be cool to look at. This validation code was originally copied from warp. |
I can confirm this issue on Warp and Tower. This is seems only exploitable on Windows and the server must have a current working directory that is different from the target disk's, though it still allows the user to access arbitrary paths from the working directory. The core of this issue boils down to I enabled logging for the warp example to see what files the program tried to access, and found that it tried to access Instead of just rejecting // Only accept current dir `.` and relative paths `a`, `a/b`.
let is_valid = path.components().all(|comp| matches!(comp, Component::Normal(_) | Component::CurDir)); I also believe that this check ensures that |
I've opened seanmonstar/warp#937 in warp to let them know about it since this seems important and I saw no other issues like it. |
I think Tide is ok. They have a check on the requested file paths to ensure that the requested file's path is prefixed by the served dir's path, which I think prevents this issue. |
I believe actix is also not affected by this. They seem to disallow path segments to end with |
@adumbidiot Thank you that detailed explanation! I've pushed some changes to this branch that uses @c5soft I do return 404 if the path contains a "prefix component" but according to the docs that only appears on windows. Do you want to verify that my changes actually fixes the problem? |
@davidpdrsn I am test "prefix component" with following code:
and i access file with http://127.0.0.1/aaa/bbb/c:/windows/win.ini
it means "c:" treats as Component::Normal not Component::Prefix in Windows 10 64bit OS. |
Hm that's weird. Then I don't understand the docs in std 🤔 I guess we need to guard on the component ending in |
Looking at the path doc's source code, it seems the prefix component is only returned if it is the first element, which is why let comp = Path::new(comp);
if !comp
.components()
.all(|c| matches!(c, std::path::Component::Normal(_)))
{
return None;
}
full_path.push(comp); I can't seem to reproduce the issue after that change. Also, why is |
@adumbidiot That makes sense! I've pushed a change that also checks each component individually. |
That commit seems to fix the issue |
@c5soft @adumbidiot Thanks for your help in reporting and fixing this! The patch is shipped in version 0.2.1, I've filed a RUSTSEC about it (rustsec/advisory-db#1159), and yanked the affected versions from crates.io. |
It looks like the RUSTSEC advisory accidentally got marked as 2021 instead of 2022. :-( |
Motivation
Current version 0.2.0 release has a high risk hidden danger that allowed a hacker to access arbitrary files in server.
When axum+tower-http-ServeDir static web server started with Windows 10 at driver D:\any-folder, a hacker can access any files at driver C:, for example:
http://127.0.0.1/anypath/c:/windows/win.ini will get some lines of text and
http://127.0.0.1/anypath/c:/windows/web/screen/img101.png will get a image
Solution
Fix build_and_validate_path function to exclude colon charactor #204