From 5a25515dba7f322d0789d60a50dca05f59b23d28 Mon Sep 17 00:00:00 2001 From: Prathamesh Jadhav <55660103+lollinng@users.noreply.github.com> Date: Fri, 5 Jun 2026 20:49:48 +0530 Subject: [PATCH] Fix path traversal in download_external_data containment guard The guard computed path = data_dir / item.local_data_path and rejected it only if data_dir not in path.parents. pathlib does not normalize "..", so "../evil.bin" yields "/data/../evil.bin" which still has data_dir in .parents and passes -- yet the download paths below call .resolve() and write to "/evil.bin", outside data_dir. Resolve before the containment check. Co-authored-by: Claude Opus 4.8 (1M context) --- truss/util/download.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/truss/util/download.py b/truss/util/download.py index 2e8cb2468..8c6655ad5 100644 --- a/truss/util/download.py +++ b/truss/util/download.py @@ -20,9 +20,11 @@ def download_external_data(external_data: Optional[ExternalData], data_dir: Path b10cp_path = _b10cp_path() # ensure parent directories exist + data_dir_resolved = data_dir.resolve() for item in external_data.items: - path = data_dir / item.local_data_path - if data_dir not in path.parents: + # resolve before the containment check so ".." cannot escape data_dir + path = (data_dir / item.local_data_path).resolve() + if path != data_dir_resolved and data_dir_resolved not in path.parents: raise ValueError( "Local data path of external data cannot point to outside data directory" )