From 8db72d9526d9cb51968f560ce1d13845c2a48d34 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Tue, 29 Sep 2026 03:13:57 +0900 Subject: [PATCH 1/2] fix(security): annotate fixed-prefix maturin urlopen for Bandit B310 ab2e9db12 added an unannotated urlopen in verify_release_maturin_tool_assets.py. The pinned Bandit gate (MEDIUM/MEDIUM) now fails on main and on every PR. The URL is a fixed https://github.com prefix and the filename is allowlisted before fetch, so mark it the same way as the other audited urlopen sites. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01WDHB12uwrJ5Uzm8gNSz52N --- scripts/ci/verify_release_maturin_tool_assets.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/ci/verify_release_maturin_tool_assets.py b/scripts/ci/verify_release_maturin_tool_assets.py index 90fa1517b7..426ebb532f 100644 --- a/scripts/ci/verify_release_maturin_tool_assets.py +++ b/scripts/ci/verify_release_maturin_tool_assets.py @@ -33,7 +33,8 @@ def _download(filename: str) -> bytes: url = f"https://github.com/PyO3/maturin/releases/download/v1.15.0/{filename}" - with urlopen(Request(url, headers={"User-Agent": "cwl-release-gate"}), timeout=60) as response: + # URL is a fixed https://github.com prefix; only the vetted asset filename varies. + with urlopen(Request(url, headers={"User-Agent": "cwl-release-gate"}), timeout=60) as response: # nosec B310 raw = response.read(MAX_ASSET_BYTES + 1) if len(raw) > MAX_ASSET_BYTES: raise ValueError("maturin release asset exceeds inspection limit") From c1b0aae0e906a9850f3a302cb72ea32231989c64 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Wed, 30 Sep 2026 08:13:16 +0900 Subject: [PATCH 2/2] fix(security): suppress reviewed maturin urlopen for Semgrep The same fixed-prefix urlopen that Bandit flags as B310 is reported by Semgrep p/default as dynamic-urllib-use-detected (level warning), which fails the repository-wide SAST gate on every open PR. verify_assets admits only the fixed maturin v1.15.0 asset filename set before fetching, so add the rule-scoped nosemgrep next to nosec, matching materialize_base_python_requirements.py. The pinned Semgrep image reports 1 finding before and 0 after. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01HMFn3QpKVj9ptCjtYDBp55 --- scripts/ci/verify_release_maturin_tool_assets.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/scripts/ci/verify_release_maturin_tool_assets.py b/scripts/ci/verify_release_maturin_tool_assets.py index 426ebb532f..f38b7e0e89 100644 --- a/scripts/ci/verify_release_maturin_tool_assets.py +++ b/scripts/ci/verify_release_maturin_tool_assets.py @@ -33,8 +33,11 @@ def _download(filename: str) -> bytes: url = f"https://github.com/PyO3/maturin/releases/download/v1.15.0/{filename}" - # URL is a fixed https://github.com prefix; only the vetted asset filename varies. - with urlopen(Request(url, headers={"User-Agent": "cwl-release-gate"}), timeout=60) as response: # nosec B310 + # URL is a fixed https://github.com prefix; only the asset filename varies, and + # verify_assets admits only the fixed maturin v1.15.0 filename set before fetching. + with urlopen( # nosemgrep: python.lang.security.audit.dynamic-urllib-use-detected.dynamic-urllib-use-detected # nosec B310 + Request(url, headers={"User-Agent": "cwl-release-gate"}), timeout=60 + ) as response: raw = response.read(MAX_ASSET_BYTES + 1) if len(raw) > MAX_ASSET_BYTES: raise ValueError("maturin release asset exceeds inspection limit")