diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/config.rs | 28 | ||||
-rw-r--r-- | src/file_op.rs | 20 |
2 files changed, 27 insertions, 21 deletions
diff --git a/src/config.rs b/src/config.rs index d52b231..50b7343 100644 --- a/src/config.rs +++ b/src/config.rs @@ -234,6 +234,21 @@ impl MiniserveConfig { }) }); + let allowed_upload_dir = args + .allowed_upload_dir + .as_ref() + .map(|v| { + v.iter() + .map(|p| { + sanitize_path(p, false) + .map(|p| p.display().to_string().replace("\\", "/")) + .ok_or(anyhow!("Illegal path {p:?}: upward traversal not allowed")) + }) + .collect() + }) + .transpose()? + .unwrap_or_default(); + Ok(MiniserveConfig { verbose: args.verbose, path: args.path.unwrap_or_else(|| PathBuf::from(".")), @@ -254,18 +269,7 @@ impl MiniserveConfig { show_qrcode: args.qrcode, mkdir_enabled: args.mkdir_enabled, file_upload: args.allowed_upload_dir.is_some(), - allowed_upload_dir: args - .allowed_upload_dir - .unwrap_or_default() - .iter() - .map(|x| { - sanitize_path(x, false) - .unwrap() - .to_str() - .unwrap() - .replace('\\', "/") - }) - .collect(), + allowed_upload_dir, uploadable_media_type, tar_enabled: args.enable_tar, tar_gz_enabled: args.enable_tar_gz, diff --git a/src/file_op.rs b/src/file_op.rs index 901c1d6..329ee8c 100644 --- a/src/file_op.rs +++ b/src/file_op.rs @@ -9,8 +9,10 @@ use actix_web::{http::header, web, HttpRequest, HttpResponse}; use futures::TryStreamExt; use serde::Deserialize; -use crate::file_utils::contains_symlink; -use crate::{errors::ContextualError, file_utils::sanitize_path}; +use crate::{ + config::MiniserveConfig, errors::ContextualError, file_utils::contains_symlink, + file_utils::sanitize_path, +}; /// Saves file data from a multipart form field (`field`) to `file_path`, optionally overwriting /// existing file. @@ -171,17 +173,11 @@ pub struct FileOpQueryParameters { /// invalid. /// This method returns future. pub async fn upload_file( + conf: web::Data<MiniserveConfig>, req: HttpRequest, query: web::Query<FileOpQueryParameters>, payload: web::Payload, ) -> Result<HttpResponse, ContextualError> { - let conf = req.app_data::<crate::MiniserveConfig>().unwrap(); - let return_path = if let Some(header) = req.headers().get(header::REFERER) { - header.to_str().unwrap_or("/").to_owned() - } else { - "/".to_string() - }; - let upload_path = sanitize_path(&query.path, conf.show_hidden).ok_or_else(|| { ContextualError::InvalidPathError("Invalid value for 'path' parameter".to_string()) })?; @@ -227,6 +223,12 @@ pub async fn upload_file( .try_collect::<Vec<u64>>() .await?; + let return_path = req + .headers() + .get(header::REFERER) + .and_then(|h| h.to_str().ok()) + .unwrap_or("/"); + Ok(HttpResponse::SeeOther() .append_header((header::LOCATION, return_path)) .finish()) |