diff --git a/server_manager/src/core/validate.rs b/server_manager/src/core/validate.rs index 7fe9504..9c4898e 100644 --- a/server_manager/src/core/validate.rs +++ b/server_manager/src/core/validate.rs @@ -142,7 +142,9 @@ pub fn validate_ip(ip_str: &str) -> Result { /// Validates that a path does not contain directory traversal sequences (`..`). pub fn validate_safe_path>(path: P) -> Result

{ let p = path.as_ref(); - for comp in p.components() { + let normalized = p.to_string_lossy().replace('\\', "/"); + let norm_path = Path::new(&normalized); + for comp in norm_path.components() { if comp == Component::ParentDir { bail!( "Validation error: path traversal forbidden in '{}'", diff --git a/server_manager/tests/contract_input_validation.rs b/server_manager/tests/contract_input_validation.rs index 998458d..7b9da2d 100644 --- a/server_manager/tests/contract_input_validation.rs +++ b/server_manager/tests/contract_input_validation.rs @@ -114,3 +114,10 @@ fn test_validate_safe_path() { assert!(validate_safe_path(Path::new("/opt/server_manager/../../etc/shadow")).is_err()); assert!(validate_safe_path(Path::new("a/b/../../../etc/passwd")).is_err()); } + +#[test] +fn test_validate_safe_path_extended_traversal() { + assert!(validate_safe_path(Path::new("..\\secret")).is_err()); + assert!(validate_safe_path(Path::new("..")).is_err()); + assert!(validate_safe_path(Path::new(".")).is_ok()); +}