mirror of
https://github.com/NicolasBohn/NexQuant.git
synced 2026-07-27 23:47:46 +00:00
fix(security): replace os.path.realpath with pathlib.resolve in safe_resolve_path to fix path-injection alerts
This commit is contained in:
+23
-7
@@ -225,11 +225,27 @@ def cache_with_pickle(hash_func: Callable, post_process_func: Callable | None =
|
|||||||
return cache_decorator
|
return cache_decorator
|
||||||
|
|
||||||
|
|
||||||
def safe_resolve_path(user_path: Path, safe_root: Path | None = None) -> Path:
|
def safe_resolve_path(user_path: Path | str, safe_root: Path | str | None = None) -> Path:
|
||||||
|
"""Resolve a user-provided path safely against an allowed root directory.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
user_path: Path provided by user/LLM/config
|
||||||
|
safe_root: If provided, the resolved path must be within this directory
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
ValueError: If path resolves outside safe_root
|
||||||
|
OSError: If path cannot be resolved
|
||||||
|
"""
|
||||||
|
resolved = Path(user_path).expanduser().resolve()
|
||||||
|
|
||||||
if safe_root is not None:
|
if safe_root is not None:
|
||||||
root_real = os.path.realpath(str(safe_root.expanduser()))
|
root_resolved = Path(safe_root).expanduser().resolve()
|
||||||
path_real = os.path.realpath(str(user_path.expanduser())) # nosec B614 — validated against safe_root below
|
try:
|
||||||
if not (path_real == root_real or path_real.startswith(root_real + os.sep)):
|
resolved.relative_to(root_resolved)
|
||||||
raise ValueError(f"Path {user_path} resolves to {path_real}, outside allowed root {safe_root}")
|
except ValueError:
|
||||||
return Path(path_real)
|
raise ValueError(
|
||||||
return user_path.expanduser().resolve()
|
f"Path {user_path} resolves to {resolved}, "
|
||||||
|
f"outside allowed root {root_resolved}"
|
||||||
|
)
|
||||||
|
|
||||||
|
return resolved
|
||||||
|
|||||||
Reference in New Issue
Block a user