Skip to content

Commit e16c78c

Browse files
committed
Reject path-traversal entries in test fixture ZIP extraction
Copilot review on #426 flagged that extract_addon_from_zip() trusted the zip entry path after only checking the addons/godot_ai/ prefix; a member like addons/godot_ai/../../outside would let target_addon/rel escape the fixture directory. The runtime installer's _is_safe_zip_addon_file() in update_reload_runner.gd already rejects absolute paths and "." / ".." segments; mirror that guard in the Python test helper. Live-verified: a synthetic zip with an addons/godot_ai/../../escape.txt member now raises ValueError with a clear message; clean zips still extract normally. 903 pytest tests pass. https://claude.ai/code/session_01VgXf3Lqv2ypt36g6EqpRYg
1 parent 0e1ae91 commit e16c78c

1 file changed

Lines changed: 5 additions & 0 deletions

File tree

tests/integration/_self_update_fixture.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,11 @@ def extract_addon_from_zip(zip_path: Path, target_addon: Path) -> None:
279279
if not info.filename.startswith("addons/godot_ai/") or info.is_dir():
280280
continue
281281
rel = Path(info.filename).relative_to("addons/godot_ai")
282+
if rel.is_absolute() or any(part in ("", ".", "..") for part in rel.parts):
283+
raise ValueError(
284+
f"Refusing unsafe zip entry {info.filename!r}: relative path "
285+
f"{rel!s} contains absolute or traversal segments"
286+
)
282287
out = target_addon / rel
283288
out.parent.mkdir(parents=True, exist_ok=True)
284289
out.write_bytes(zf.read(info.filename))

0 commit comments

Comments
 (0)