Skip to content

sec: dynamic urllib use in supply_chain_risk.py allows file:// scheme #169

@longieirl

Description

@longieirl

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:

  1. urllib silently accepts file:// URLs — a later refactor accepting CLI args could inadvertently expose this.
  2. 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)

Metadata

Metadata

Assignees

Labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions