From 3d44bf1cca7d302dedaf299a9fc1b7844f6ebd90 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 16 Jun 2026 10:19:24 +0000 Subject: [PATCH 1/2] Initial plan From 869e21c2a482b1c5c323b5d20b48ff25cc97fc1a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 16 Jun 2026 10:24:14 +0000 Subject: [PATCH 2/2] Fix ZipSlip path traversal vulnerability in ArtifactTool zip extraction Replace unsafe `ZipFile.extractall()` with member-by-member extraction that validates each entry's resolved path stays within the target directory using `infolist()` for complete coverage including directories. Co-authored-by: ayushhgarg-work <259261949+ayushhgarg-work@users.noreply.github.com> --- sdk/ml/azure-ai-ml/azure/ai/ml/_utils/_artifact_utils.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/sdk/ml/azure-ai-ml/azure/ai/ml/_utils/_artifact_utils.py b/sdk/ml/azure-ai-ml/azure/ai/ml/_utils/_artifact_utils.py index 9b00040ef19c..c193cdd27386 100644 --- a/sdk/ml/azure-ai-ml/azure/ai/ml/_utils/_artifact_utils.py +++ b/sdk/ml/azure-ai-ml/azure/ai/ml/_utils/_artifact_utils.py @@ -204,7 +204,14 @@ def _redirect_artifacts_tool_path(self, organization: Optional[str]): artifacts_tool_uri = response.json()["uri"] response = requests_pipeline.get(artifacts_tool_uri) # pylint: disable=too-many-function-args with zipfile.ZipFile(BytesIO(response.content)) as zip_file: - zip_file.extractall(artifacts_tool_path) + artifacts_tool_resolved = Path(artifacts_tool_path).resolve() + for member_info in zip_file.infolist(): + member_resolved = (artifacts_tool_resolved / member_info.filename).resolve() + if not member_resolved.is_relative_to(artifacts_tool_resolved): + raise RuntimeError( + f"Unsafe path in zip archive: '{member_info.filename}' resolves outside the target directory." + ) + zip_file.extract(member_info, artifacts_tool_path) os.environ["AZURE_DEVOPS_EXT_ARTIFACTTOOL_OVERRIDE_PATH"] = str(artifacts_tool_path.resolve()) self._artifacts_tool_path = artifacts_tool_path else: