diff options
author | Sven-Hendrik Haase <svenstaro@gmail.com> | 2022-05-18 05:08:22 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-05-18 05:08:22 +0000 |
commit | bb4afb2d10582d7b5d27e3e01d2f316ab3d31ffc (patch) | |
tree | 02519193e2ab5e52ef24fbb530e08c188b502b66 /src | |
parent | Merge pull request #801 from svenstaro/run-clippy-only-on-nightly (diff) | |
parent | Fix security issue with --no-symlinks (diff) | |
download | miniserve-bb4afb2d10582d7b5d27e3e01d2f316ab3d31ffc.tar.gz miniserve-bb4afb2d10582d7b5d27e3e01d2f316ab3d31ffc.zip |
Merge pull request #802 from svenstaro/fix-symlink-following
Fix security issue with --no-symlinks
Diffstat (limited to 'src')
-rw-r--r-- | src/args.rs | 4 | ||||
-rw-r--r-- | src/main.rs | 19 |
2 files changed, 21 insertions, 2 deletions
diff --git a/src/args.rs b/src/args.rs index 7667bee..757fd22 100644 --- a/src/args.rs +++ b/src/args.rs @@ -75,7 +75,7 @@ pub struct CliArgs { #[clap(long = "random-route", conflicts_with("route-prefix"))] pub random_route: bool, - /// Do not follow symbolic links + /// Hide symlinks in listing and prevent them from being followed #[clap(short = 'P', long = "no-symlinks")] pub no_symlinks: bool, @@ -160,7 +160,7 @@ pub struct CliArgs { )] pub header: Vec<HeaderMap>, - /// Show symlink info + /// Visualize symlinks in directory listing #[clap(short = 'l', long = "show-symlink-info")] pub show_symlink_info: bool, diff --git a/src/main.rs b/src/main.rs index de10d7d..9d3f9ac 100644 --- a/src/main.rs +++ b/src/main.rs @@ -304,6 +304,8 @@ fn configure_header(conf: &MiniserveConfig) -> middleware::DefaultHeaders { } /// Configures the Actix application +/// +/// This is where we configure the app to serve an index file, the file listing, or a single file. fn configure_app(app: &mut web::ServiceConfig, conf: &MiniserveConfig) { let files_service = || { let files = actix_files::Files::new("", &conf.path); @@ -332,11 +334,28 @@ fn configure_app(app: &mut web::ServiceConfig, conf: &MiniserveConfig) { true => files.use_hidden_files(), false => files, }; + + let base_path = conf.path.clone(); + let symlinks_may_be_followed = !conf.no_symlinks; files .show_files_listing() .files_listing_renderer(listing::directory_listing) .prefer_utf8(true) .redirect_to_slash_directory() + .path_filter(move |path, _| { + // Only allow symlinks to be followed in case conf.no_symlinks is false. + let path_is_symlink = base_path + .join(path) + .symlink_metadata() + .map(|m| m.file_type().is_symlink()) + .unwrap_or(false); + + if path_is_symlink { + symlinks_may_be_followed + } else { + true + } + }) }; if !conf.path.is_file() { |