diff options
Diffstat (limited to '')
-rw-r--r-- | src/args.rs | 4 | ||||
-rw-r--r-- | src/config.rs | 4 | ||||
-rw-r--r-- | src/file_upload.rs | 13 | ||||
-rw-r--r-- | src/renderer.rs | 9 |
4 files changed, 29 insertions, 1 deletions
diff --git a/src/args.rs b/src/args.rs index a8718bd..4edf455 100644 --- a/src/args.rs +++ b/src/args.rs @@ -111,6 +111,10 @@ pub struct CliArgs { #[clap(short = 'u', long = "upload-files")] pub file_upload: bool, + /// Restrict upload directories + #[clap(long = "restrict-upload-dir")] + pub restrict_upload_dir: Vec<String>, + /// Enable creating directories #[clap(short = 'U', long = "mkdir", requires = "file-upload")] pub mkdir_enabled: bool, diff --git a/src/config.rs b/src/config.rs index 5bcbd62..380cf5a 100644 --- a/src/config.rs +++ b/src/config.rs @@ -87,6 +87,9 @@ pub struct MiniserveConfig { /// Enable file upload pub file_upload: bool, + /// Restrict file upload dirs + pub restrict_upload_dir: Vec<String>, + /// HTML accept attribute value pub uploadable_media_type: Option<String>, @@ -248,6 +251,7 @@ impl MiniserveConfig { show_qrcode: args.qrcode, mkdir_enabled: args.mkdir_enabled, file_upload: args.file_upload, + restrict_upload_dir: args.restrict_upload_dir, uploadable_media_type, tar_enabled: args.enable_tar, tar_gz_enabled: args.enable_tar_gz, diff --git a/src/file_upload.rs b/src/file_upload.rs index 6643c68..747d0de 100644 --- a/src/file_upload.rs +++ b/src/file_upload.rs @@ -171,6 +171,19 @@ pub async fn upload_file( ContextualError::IoError("Failed to resolve path served by miniserve".to_string(), e) })?; + + // Disallow paths outside of restricted directories + // TODO: Probably not the most rust-ic style... + if !conf.restrict_upload_dir.is_empty() { + let upl_path = upload_path.clone().into_os_string().into_string().unwrap(); + + if !(conf.restrict_upload_dir.contains(&upl_path)){ + // not good + return Err(ContextualError::InvalidPathError("Not allowed to upload to this path".to_string())); + } + } + + // Disallow the target path to go outside of the served directory // The target directory shouldn't be canonicalized when it gets passed to // handle_multipart so that it can check for symlinks if needed diff --git a/src/renderer.rs b/src/renderer.rs index c8958fe..8bee00f 100644 --- a/src/renderer.rs +++ b/src/renderer.rs @@ -38,8 +38,15 @@ pub fn page( let upload_action = build_upload_action(&upload_route, encoded_dir, sort_method, sort_order); let mkdir_action = build_mkdir_action(&upload_route, encoded_dir); + let upload_allowed = conf.restrict_upload_dir.contains(&encoded_dir[1..].to_string()); let title_path = breadcrumbs_to_path_string(breadcrumbs); + let title_path = breadcrumbs + .iter() + .map(|el| el.name.clone()) + .collect::<Vec<_>>() + .join("/"); + html! { (DOCTYPE) html { @@ -120,7 +127,7 @@ pub fn page( } } div.toolbar_box_group { - @if conf.file_upload { + @if conf.file_upload && upload_allowed { div.toolbar_box { form id="file_submit" action=(upload_action) method="POST" enctype="multipart/form-data" { p { "Select a file to upload or drag it anywhere into the window" } |