Summary
Semgrep (python.lang.security.audit.dynamic-urllib-use-detected) flagged scripts/supply_chain_risk.py line 59, where urllib.request.urlopen is called with a URL that includes a dynamic package_name variable.
urllib supports the file:// scheme, so if package_name were ever tainted by external input (e.g. a crafted pyproject.toml or CLI argument), an attacker could cause the function to read arbitrary local files instead of fetching from PyPI.
Affected location
scripts/supply_chain_risk.py:59
url = f"https://pypi.org/pypi/{package_name}/json"
with urllib.request.urlopen(url, timeout=5) as response:
Current risk assessment
Low in practice — package_name is sourced from pyproject.toml parsing within the same process, not from user input. However, the pattern is worth hardening because:
urllib silently accepts file:// URLs — a later refactor accepting CLI args could inadvertently expose this.
requests is already a transitive dependency and gives cleaner error handling.
Fix
Replace urllib with requests and add an explicit scheme check:
import requests
def fetch_pypi_metadata(package_name: str) -> dict:
try:
response = requests.get(
f"https://pypi.org/pypi/{package_name}/json",
timeout=5,
)
response.raise_for_status()
return response.json()
except requests.RequestException:
return {}
requests only supports http:// and https:// schemes, eliminating the file:// vector entirely.
References
- Semgrep rule:
python.lang.security.audit.dynamic-urllib-use-detected
- Detected by: Semgrep OSS static analysis (
p/security-audit)
Summary
Semgrep (
python.lang.security.audit.dynamic-urllib-use-detected) flaggedscripts/supply_chain_risk.pyline 59, whereurllib.request.urlopenis called with a URL that includes a dynamicpackage_namevariable.urllibsupports thefile://scheme, so ifpackage_namewere ever tainted by external input (e.g. a craftedpyproject.tomlor CLI argument), an attacker could cause the function to read arbitrary local files instead of fetching from PyPI.Affected location
scripts/supply_chain_risk.py:59Current risk assessment
Low in practice —
package_nameis sourced frompyproject.tomlparsing within the same process, not from user input. However, the pattern is worth hardening because:urllibsilently acceptsfile://URLs — a later refactor accepting CLI args could inadvertently expose this.requestsis already a transitive dependency and gives cleaner error handling.Fix
Replace
urllibwithrequestsand add an explicit scheme check:requestsonly supportshttp://andhttps://schemes, eliminating thefile://vector entirely.References
python.lang.security.audit.dynamic-urllib-use-detectedp/security-audit)