File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -66,7 +66,20 @@ fn ensure_directory_exists(file_path: &Path) -> Result<(), std::io::Error> {
6666fn get_storage_file_path ( filename : & str ) -> PathBuf {
6767 let config = get_local_config ( ) ;
6868 let storage_path = Path :: new ( & config. storage_path ) ;
69- storage_path. join ( filename)
69+ // Strip leading slashes to ensure the path is always relative to storage root
70+ let safe_name = filename. trim_start_matches ( '/' ) ;
71+ let full = storage_path. join ( safe_name) ;
72+ // Defense-in-depth: verify resolved path stays within storage root
73+ let canonical_storage = storage_path. canonicalize ( ) . unwrap_or_else ( |_| storage_path. to_path_buf ( ) ) ;
74+ // Use the parent directory for canonicalization since the file may not exist yet
75+ let parent = full. parent ( ) . unwrap_or ( & full) ;
76+ let canonical_parent = parent. canonicalize ( ) . unwrap_or_else ( |_| parent. to_path_buf ( ) ) ;
77+ if !canonical_parent. starts_with ( & canonical_storage) {
78+ // Fall back to storage root to prevent escape
79+ storage_path. join ( Path :: new ( safe_name) . file_name ( ) . unwrap_or_default ( ) )
80+ } else {
81+ full
82+ }
7083}
7184
7285/// Get metadata file path for storing headers
Original file line number Diff line number Diff line change @@ -693,6 +693,8 @@ async fn ax_post_file(
693693 } else {
694694 format ! ( "{}/{}" , path, file0_filename)
695695 } ;
696+ // Normalize: strip leading slashes so the path is always relative
697+ let full_path = full_path. trim_start_matches ( '/' ) . to_string ( ) ;
696698
697699 // validate path for traversal
698700 match validate_path ( & full_path) {
@@ -828,6 +830,8 @@ async fn ax_post_file(
828830 } else {
829831 format ! ( "{}/{}" , path, file0_filename)
830832 } ;
833+ // Normalize: strip leading slashes so the path is always relative
834+ let full_path = full_path. trim_start_matches ( '/' ) . to_string ( ) ;
831835
832836 match validate_path ( & full_path) {
833837 Ok ( _) => ( ) ,
You can’t perform that action at this time.
0 commit comments