Skip to main content

pypi-security-best-practices

Guide for implementing security best practices when using Python packages from PyPI with uv and pip

Informações da origem

Repositório
reason-machines/security-skills
Última atividade na origem
8 de junho de 2026 às 20:19
Idioma detectado do SKILL.md
inglês
Estrelas
12
Forks
1

Opções de instalação

Por padrão, está selecionado o prompt que primeiro revisa a origem. Você pode mudar para um comando direto ou baixar uma cópia local.

Revise os arquivos de origem

Leia o SKILL.md e os arquivos complementares exibidos pelo SkillsMP antes de decidir se vai instalar.

Exibindo SKILL.md

SKILL.md
Instruções da origem · Visualização somente leitura
name
pypi-security-best-practices
description
Guide for implementing security best practices when using Python packages from PyPI with uv and pip
triggers
["how do I secure my Python package installations","show me PyPI security best practices","how to prevent supply chain attacks in Python","configure uv with security hardening","implement dependency cooldown for PyPI packages","verify package hashes with pip and uv","secure my Python development environment","protect against malicious PyPI packages"]
# PyPI Security Best Practices > Skill by [ara.so](https://ara.so) — Security Skills collection. This skill provides comprehensive guidance on securing Python package installations from PyPI, covering supply chain attack mitigation, dependency verification, and secure development practices for both `uv` and `pip` package managers. ## Overview PyPI security best practices help protect against supply chain attacks like the LiteLLM/Telnyx incident (119k+ malicious downloads in under 3 hours) and other compromised package scenarios. This guide covers secure package installation, dependency management, and development environment hardening. **Key Security Principles:** - Prefer binary-only installations to avoid arbitrary code execution - Implement dependency cooldowns to avoid newly-published malicious packages - Pin dependencies with cryptographic hash verification - Use deterministic installations and prevent dependency confusion - Scan for vulnerabilities and verify package health ## Installation ### uv (Recommended) ```bash # Install uv (macOS/Linux) curl -LsSf https://astral.sh/uv/install.sh | sh # Install uv (Windows) powershell -c "irm https://astral.sh/uv/install.ps1 | iex" # Verify installation uv --version ``` ### pip ```bash # pip is included with Python 3.4+ python -m pip --version # Upgrade to latest pip python -m pip install --upgrade pip ``` ### Security Tools ```bash # Install pip-audit for vulnerability scanning python -m pip install pip-audit # Install uv-secure for lockfile scanning uv tool install uv-secure ``` ## Core Security Practices ### 1. Binary-Only Installations Source distributions can execute arbitrary code via `setup.py`. Enforce binary-only installs: **With uv:** ```bash # Command line uv pip install --only-binary :all: requests # In pyproject.toml [tool.uv.pip] only-binary = [":all:"] # In uv.toml [pip] only-binary = [":all:"] ``` **With pip:** ```bash # Command line pip install --only-binary :all: requests # Environment variable export PIP_ONLY_BINARY=:all: pip install requests # In pip.conf (Linux/macOS: ~/.config/pip/pip.conf) [install] only-binary = :all: ``` ### 2. Dependency Cooldowns Avoid newly-published malicious packages by excluding recent releases: **With uv:** ```toml # pyproject.toml [tool.uv] exclude-newer = "7 days" # Recommended for general use # Or more aggressive for production exclude-newer = "30 days" ``` ```bash # Command line usage uv lock --exclude-newer "7 days" uv sync --exclude-newer "7 days" # Environment variable export UV_EXCLUDE_NEWER="7 days" uv sync ``` **Per-package overrides:** ```toml # pyproject.toml - exempt security patches [tool.uv] exclude-newer = "7 days" exclude-newer-package = { requests = "1 day" } ``` **With pip (v26.1+):** ```ini # ~/.config/pip/pip.conf [install] uploaded-prior-to = P7D ``` ```bash # Command line (absolute date) pip install --uploaded-prior-to=2026-06-01 requests # Bypass cooldown for urgent patches pip install --uploaded-prior-to=P0D requests==2.32.3 ``` **Dependabot cooldown:** ```yaml # .github/dependabot.yml version: 2 updates: - package-ecosystem: "pip" directory: "/" schedule: interval: "weekly" cooldown: 7 # Wait 7 days after release ``` **Renovate cooldown:** ```json { "packageRules": [ { "matchDatasources": ["pypi"], "minimumReleaseAge": "7 days" } ] } ``` ### 3. Hash Verification Always verify package integrity with cryptographic hashes: **With uv (automatic in lockfile):** ```bash # Generate lockfile with hashes uv lock # Install with hash verification (automatic) uv sync # For requirements.txt workflow uv pip compile --generate-hashes requirements.in -o requirements.txt uv pip install -r requirements.txt ``` **Example lockfile entry:** ```toml [[package]] name = "requests" version = "2.32.3" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "certifi" }, { name = "charset-normalizer" }, ] wheels = [ { url = "https://files.pythonhosted.org/packages/.../requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6" }, ] ``` **With pip:** ```bash # Generate hashed requirements pip-compile --generate-hashes requirements.in # Install with hash verification pip install --require-hashes -r requirements.txt ``` **Example requirements.txt with hashes:** ```txt requests==2.32.3 \ --hash=sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6 \ --hash=sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760 certifi==2024.2.2 \ --hash=sha256:0569859f95fc761b18b45ef421b1290a0f65f147e92a1e5eb3e635f9a5e4e66f ``` ### 4. Deterministic Installations Use lockfiles for reproducible builds: **With uv:** ```bash # Create lockfile uv lock # Install exact versions from lockfile uv sync # Install without updating lockfile uv sync --frozen ``` **With pip:** ```bash # Generate pinned requirements pip freeze > requirements.txt # Or use pip-tools pip-compile requirements.in -o requirements.txt # Install exact versions pip install -r requirements.txt ``` ### 5. Prevent Dependency Confusion Configure package sources to prevent private/public namespace collisions: **With uv:** ```toml # pyproject.toml [[tool.uv.index]] name = "company-internal" url = "https://pypi.company.com/simple" explicit = true # Only use for explicitly specified packages [[tool.uv.index]] name = "pypi" url = "https://pypi.org/simple" default = true ``` **With pip:** ```ini # pip.conf [global] index-url = https://pypi.org/simple extra-index-url = https://pypi.company.com/simple [install] # Require that private packages come from internal index trusted-host = pypi.company.com ``` ### 6. Vulnerability Scanning Regularly scan dependencies for known vulnerabilities: **With pip-audit:** ```bash # Scan installed packages pip-audit # Scan requirements file pip-audit -r requirements.txt # Output as JSON pip-audit --format json -o audit.json # Fix vulnerabilities automatically pip-audit --fix # Ignore specific vulnerabilities pip-audit --ignore-vuln PYSEC-2024-1234 ``` **With uv-secure:** ```bash # Scan uv lockfile uv-secure scan # Fail CI on vulnerabilities uv-secure scan --exit-code # Generate SARIF for GitHub uv-secure scan --format sarif -o results.sarif ``` **In CI/CD (GitHub Actions):** ```yaml name: Security Scan on: [push, pull_request] jobs: scan: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Install uv uses: astral-sh/setup-uv@v3 - name: Scan for vulnerabilities run: | uv tool install uv-secure uv-secure scan --exit-code ``` ### 7. Harden Package Installs with Security Tools **Socket.dev for real-time protection:** ```bash # Install Socket CLI npm install -g @socketsecurity/cli # Scan Python dependencies socket python scan requirements.txt # Monitor CI/CD socket ci ``` **Phylum for supply chain analysis:** ```bash # Install Phylum curl -sSL https://sh.phylum.io/ | sh # Analyze dependencies phylum analyze requirements.txt # Block malicious packages in CI phylum check requirements.txt --fail-on-critical ``` ## Secure Local Development ### 8. No Plaintext Secrets in .env Files Use secret management instead of plaintext `.env` files: **With 1Password:** ```bash # Store secret op item create --category=password \ --title "API_KEY" \ --vault "Development" \ password="${API_KEY_VALUE}" # Load secrets into environment eval $(op inject -i .env.template -o .env) # Run with secrets op run -- python app.py ``` **.env.template (commit this):** ```bash API_KEY=op://Development/API_KEY/password DATABASE_URL=op://Development/DATABASE_URL/password ``` **With doppler:** ```bash # Install doppler brew install dopplerhq/cli/doppler # macOS # or curl -Ls https://cli.doppler.com/install.sh | sh # Login and setup doppler login doppler setup # Run with secrets doppler run -- python app.py ``` ### 9. Work in Dev Containers Isolate development environments with containers: **devcontainer.json:** ```json { "name": "Python Development", "image": "mcr.microsoft.com/devcontainers/python:3.12", "features": { "ghcr.io/devcontainers/features/uv:1": {} }, "postCreateCommand": "uv sync", "customizations": { "vscode": { "extensions": [ "ms-python.python", "charliermarsh.ruff" ] } }, "remoteEnv": { "UV_EXCLUDE_NEWER": "7 days" } } ``` **Docker Compose for local development:** ```yaml # docker-compose.yml version: '3.8' services: app: build: . volumes: - .:/workspace - uv-cache:/root/.cache/uv environment: - UV_EXCLUDE_NEWER=7 days - UV_NO_SYNC=1 command: uv run python app.py volumes: uv-cache: ``` ## Maintainer Security Practices ### 10. Enable 2FA for PyPI Accounts ```bash # PyPI requires 2FA for all accounts # Visit https://pypi.org/manage/account/two-factor/ # Use TOTP app or security key (recommended) ``` ### 11. Publish with Trusted Publishing (OIDC) **GitHub Actions workflow:** ```yaml name: Publish to PyPI on: release: types: [published] permissions: id-token: write # Required for trusted publishing jobs: publish: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: astral-sh/setup-uv@v3 - name: Build package run: uv build - name: Publish to PyPI uses: pypa/gh-action-pypi-publish@release/v1 with: # No API token needed - uses OIDC skip-existing: true ``` **Configure on PyPI:** 1. Go to https://pypi.org/manage/account/publishing/ 2. Add GitHub repository 3. Specify workflow name and environment ### 12. Publish with Package Attestations Generate provenance attestations: ```yaml name: Publish with Attestations on: release: types: [published] permissions: id-token: write contents: read attestations: write jobs: publish: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: astral-sh/setup-uv@v3 - name: Build run: uv build - name: Generate attestations uses: actions/attest-build-provenance@v1 with: subject-path: dist/* - name: Publish uses: pypa/gh-action-pypi-publish@release/v1 with: attestations: true ``` **Verify attestations:** ```bash # Download and verify package attestations pip download --no-deps requests==2.32.3 gh attestation verify requests-2.32.3-py3-none-any.whl \ --owner psf ``` ### 13. Secure CI/CD Release Pipeline **Branch protection and signed commits:** ```yaml # .github/workflows/release.yml name: Secure Release on: push: tags: - 'v*' jobs: security-check: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 # Verify signed commits - name: Verify signatures run: | git verify-commit HEAD || exit 1 # Scan dependencies - name: Vulnerability scan run: | uv tool install uv-secure uv-secure scan --exit-code # SBOM generation - name: Generate SBOM uses: anchore/sbom-action@v0 with: format: cyclonedx-json output-file: sbom.json - name: Upload SBOM uses: actions/upload-artifact@v4 with: name: sbom path: sbom.json
Ver no GitHub
Este SKILL.md e muito grande, entao o SkillsMP mostra aqui apenas a primeira secao. Ver no GitHub