-
-
Notifications
You must be signed in to change notification settings - Fork 302
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
Added option restrict-upload-dir #858
Conversation
Cool, before I do a proper review, could you add a test to check that other directories are now indeed forbidden? |
Sure, let me have a look into testing in Rust :) |
You can take a look at the other tests concerning the upload. It should be somewhat straight forward. Just remember: If you messed up and the test doesn't pick it up, this is a security issue so we need to be really careful here. :) |
@svenstaro thanks for the suggestion. Fixed an issue (running tests is actually helpful :)) and added a test similar to existing one |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good stuff! This will probably require a few rounds of reviews until we get there but i think for your first foray into Rust this is already looking pretty good.
Reworked the solution to use PathBuf and with this also fixed subdirectories not working. Edit: improved (hopefully) the style a bit using iter().any(). @svenstaro I'd appreciate some feedback (esp. on improving the style). Thanks again! :) |
I'd be happy to merge as-is. Please update the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Found a few tiny things but once we have that, we're good to go. Great job so far!
src/args.rs
Outdated
/// Allowed upload directories (together with -u) | ||
/// | ||
/// If this is set, uploads are only allowed into the provided directories. | ||
#[clap(long, requires = "file-upload", value_hint = ValueHint::FilePath)] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you like, you can choose a short letter for this as well as it'd be annoying to write it out many times otherwise.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd go for 'A' (as in allowed...), but I am wondering if we might just want to re-purpose -u
...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You mean something like -u
alone would allow for uploading everywhere and then -u /tmp/lol
would allow uploading only to that dir? If that's what you're thinking, I appreciate the conciseness but I can't help but wonder whether that wouldn't make -u
pretty hard to parse (is it even still possible?) and somewhat confusing to users perhaps. Thoughts?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
-A
is a fine choice, I think.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You mean something like
-u
alone would allow for uploading everywhere and then-u /tmp/lol
would allow uploading only to that dir? If that's what you're thinking, I appreciate the conciseness but I can't help but wonder whether that wouldn't make-u
pretty hard to parse (is it even still possible?) and somewhat confusing to users perhaps. Thoughts?
Exactly, that was my thinking (after seeing so many command line shorts already taken ;)). Not sure about the parsing, though, I'd give it a try...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does it parse this correctly? -u --some-other-flag
? Would it try to parse the stuff behind -u
as a PathBuf
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just tried -u --verbose
and it worked as expected (i.e. verbose output and allowed_upload_dir == Some([])
(i.e. it would allow uploads everywhere)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've just committed a version that uses -u
to define allowed directories. @svenstaro, please check it out and let me know what you think (I am also fine to use the previous version with -A
as a shortcut).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like the -u
with min_values
. Makes more sense. Might want to try how it does in windows shell. It should work in bash because we've to use ./-path
when a file starts with -
(e.g. touch ./-h
) otherwise it'll be parsed as cli argument.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unfortunately, I cannot try on Windows.
Directories starting with -
would also need the ./
prefix, which doesn't work with my implementation (yet) - will have a look.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey, I think we're almost there now. Only some tiny stuff now. I'd like to put this into the next miniserve release, too! Do you have some time to finish it up soon so we can land it with the release?
src/args.rs
Outdated
/// Allowed upload directories (together with -u) | ||
/// | ||
/// If this is set, uploads are only allowed into the provided directories. | ||
#[clap(long, requires = "file-upload", value_hint = ValueHint::FilePath)] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
-A
is a fine choice, I think.
Except for the decision for using -u or -A (and some cleanup in case we go with -u), it should be ready. |
Please run |
Fixed formatting and also sanitized paths so that specification of `-u ./some_dir' also works. |
There's a small lint to fix there. |
Looks like CICD on Windows fails, might have to do with the tests that include a dash in the directory name. Unfortunately, I don't have a windows machine to test on... |
I also don't have a Windows machine to build miniserve to test, but I made a colleague try to make a directory named "-h" and it was a success (I tried both with "New Folder" button and I don't know if it's a good idea, but we might be able to use |
I'd be fine if we don't run that test on Windows. |
As CI has test cases 3+4 failing, I am not sure it's related to the dot. Rather, it could be related to sub-directories (and possibly different path separator for Windows). I've pushed another commit that tries to fix the paths for windows, let's see if it passes CI. Suggestions welcome (struggling a bit as a noob without access to the target platform). |
tests/upload_files.rs
Outdated
fn uploading_files_to_allowed_dir_works( | ||
#[case] server: TestServer, | ||
#[case] upload_dirs: Vec<&str>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does it work if you take these as Path
or OsPath
? That might be a better way that just works in Windows as well.
It seems like there's a conflict with the recent QR stuff merge. Could you rebase? |
ec83ba7
to
753eed8
Compare
Co-authored-by: Sven-Hendrik Haase <svenstaro@gmail.com>
Co-authored-by: Sven-Hendrik Haase <svenstaro@gmail.com>
Co-authored-by: Sven-Hendrik Haase <svenstaro@gmail.com>
753eed8
to
d34b411
Compare
Rebase done, still need to fix the failing test for windows platform. |
tests/upload_files.rs
Outdated
#[case(server(&["-u", "someDir"]), vec!["someDir".to_string()])] | ||
#[case(server(&["-u", "./-someDir"]), vec!["./-someDir".to_string()])] | ||
#[case(server(&["-u", if cfg!(windows) {r"someDir\some_sub_dir"} else {"someDir/some_sub_dir"}]), | ||
vec!["someDir/some_sub_dir".to_string()])] | ||
#[case(server(&["-u", if cfg!(windows) {r"someDir\some_sub_dir"} else {"someDir/some_sub_dir"}, | ||
"-u", if cfg!(windows) {r"someDir\some_other_dir"} else {"someDir/some_other_dir"}]), | ||
vec!["someDir/some_sub_dir".to_string(), "someDir/some_other_dir".to_string()])] | ||
fn uploading_files_to_allowed_dir_works( | ||
#[case] server: TestServer, | ||
#[case] upload_dirs: Vec<String>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I still don't really understand why you can't use a std::path::Path
here as it will take care of the conversion for you on the operating systems. Wouldn't that be more convenient?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I was thinking the same, but thought I'd stick first with they way other tests (see e.g. l. 179) handled it. Since that didn't work in this case (CI still failing), I will try the approach with std::path::Path
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should probably change other tests as well. :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since it still doesn't work, I'd also be ok with you simply disabling the failing test cases on Windows.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yup, and kind of hard to make progress without access to a windows machine. Not sure I'll find time to setup something (e.g. on Azure/CodeSpaces)...
@svenstaro, I don't know how I would disable a test-case for a specific platform. Could you give me a pointer?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also noticed, that the feature doesn't work on windows with subdirectories (likely due to \
vs /
) - found out by running miniserve.exe from publish_release action on an old windows laptop. Pushed a fix, waiting for Action workflow to verify.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like I found a solution - latest commit passes CI on all platforms.
I assume the warning (the following packages contain code that will be rejected by a future version of Rust: winapi v0.2.8) has nothing to do with my PR.
From my perspective, the PR should be ready to merge now - please let me know if I overlooked something.
Re the 500 errors, I might have a stab at that if time permits.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, the error handling was easier to fix than I thought - fixed it (also for the case when overwrite_files
is not set, i.e. DuplicateFileError
).
At last! Outstanding work getting it to this state. It took a while but I hope you appreciate that for security stuff we need to go the extra mile. :) |
Thanks a lot for your guidance (and patience), I leaned a lot and it was fun! |
To fix #842