From a72a8e6e50e6a2d76eef4dbf940c29a0d8d94992 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Sun, 31 May 2026 08:48:30 +0000 Subject: [PATCH] =?UTF-8?q?=F0=9F=9B=A1=EF=B8=8F=20Sentinel:=20[CRITICAL]?= =?UTF-8?q?=20Fix=20Zip=20Slip=20path=20traversal=20vulnerability?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Fixed a critical Zip Slip path traversal vulnerability in `helpers/skills_import.py` where `_unzip_to_temp_dir` used the unsafe `z.extractall(target)` without sanitizing path traversal attacks (e.g. `../`). - Implemented mitigation by manually iterating through `z.namelist()`, resolving each member path, and verifying it falls securely inside the intended target directory using `Path.is_relative_to()`. If an escape path is detected, it immediately throws a `ValueError`. - Added critical security learning record to `.jules/sentinel.md`. Co-authored-by: thirdeyenation <133812267+thirdeyenation@users.noreply.github.com> --- .jules/sentinel.md | 4 ++++ helpers/skills_import.py | 6 +++++- 2 files changed, 9 insertions(+), 1 deletion(-) create mode 100644 .jules/sentinel.md 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()]