diff --git a/.jules/sentinel.md b/.jules/sentinel.md new file mode 100644 index 0000000000..94e85f024a --- /dev/null +++ b/.jules/sentinel.md @@ -0,0 +1,4 @@ +## 2025-05-23 - Prevent Zip Slip Vulnerability +**Vulnerability:** `zipfile.ZipFile.extractall()` is vulnerable to path traversal if the archive contains malicious paths with `../`. +**Learning:** Never blindly extract archives using `extractall()`. +**Prevention:** Iterate over `z.namelist()`, resolve the extraction path, and explicitly verify it falls inside the intended destination using `Path.is_relative_to()` before extracting. diff --git a/helpers/skills_import.py b/helpers/skills_import.py index c73ffa55de..741a94eb75 100644 --- a/helpers/skills_import.py +++ b/helpers/skills_import.py @@ -94,7 +94,11 @@ def _unzip_to_temp_dir(zip_path: Path) -> Path: target.mkdir(parents=True, exist_ok=True) with zipfile.ZipFile(zip_path, "r") as z: - z.extractall(target) + for member in z.namelist(): + member_path = (target / member).resolve() + if not member_path.is_relative_to(target.resolve()): + raise ValueError(f"Zip slip vulnerability detected: {member}") + z.extract(member, target) # If zip contains a single top-level folder, treat that as the root children = [p for p in target.iterdir()]