Escanear Paquetes Python en busca de CVEs Conocidos con
Cómo usar pip-audit para escanear dependencias Python en busca de vulnerabilidades conocidas, configurar ignore lists, integrar con CI/CD y remediar findings.
Nota para desarrolladores hispanohablantes: Esta guía incluye ejemplos y convenciones de nomenclatura adaptadas a equipos que trabajan en español. Cuando existen diferencias significativas en terminología técnica entre el inglés y el español, se indican explícitamente para facilitar la comunicación en equipos multiculturales.
Overview
pip-audit es una herramienta para escanear dependencias de paquetes Python en busca de vulnerabilidades de seguridad conocidas. Consulta la PyPI Advisory Database (OSV) y reporta CVEs que afectan tus paquetes instalados. A diferencia de safety (que requiere una API key paga para coverage completo), pip-audit es gratis, open-source, y usa la base de datos OSV.dev mantenida por Google.
When to Use
- Escanear proyectos Python en busca de dependencias vulnerables
- Pipelines CI/CD para atrapar paquetes vulnerables antes del deployment
- Security audits regulares de entornos de producción
- Chequear si un upgrade de paquete introduce nuevas vulnerabilidades
- Validar que una vulnerabilidad fue patcheada después de upgradear
When NOT to Use
- Escanear source code en busca de patrones inseguros — usá Bandit en su lugar
- Proyectos non-Python — pip-audit solo chequea paquetes Python
- Cuando necesitás SCA (Software Composition Analysis) para licencias — usá
pip-licenses - Para detección de vulnerabilidades en runtime — pip-audit es static, chequea versiones instaladas
Solution
Instalar pip-audit
pip install pip-audit
# Usando poetry
poetry add --group dev pip-audit
# Usando pipenv
pipenv install --dev pip-audit
# Usando uv
uv add --dev pip-audit
Scan básico
# Escanear el entorno actual
pip-audit
# Escanear un archivo requirements.txt
pip-audit -r requirements.txt
# Escanear múltiples requirements files
pip-audit -r requirements.txt -r requirements-dev.txt
# Output en formato JSON
pip-audit -f json -o audit-report.json
# Output en formato CSV
pip-audit -f csv -o audit-report.csv
# Output en Markdown
pip-audit -f markdown -o audit-report.md
Escanear con manifests de proyecto
# Escanear pyproject.toml (poetry/setuptools/hatch)
pip-audit --requirement pyproject.toml
# Escanear Pipfile.lock
pip-audit --requirement Pipfile.lock
# Escanear poetry.lock
pip-audit --requirement poetry.lock
# Escanear uv.lock
pip-audit --requirement uv.lock
Strict mode — fallar en cualquier vulnerabilidad
# Exit con non-zero code si se encuentran vulnerabilidades
pip-audit --strict
# Usar en CI/CD para fallar el build
pip-audit --strict -f json -o audit-report.json
Ignorar vulnerabilidades específicas
# Ignorar por CVE ID
pip-audit --ignore-vuln CVE-2023-12345
# Ignorar múltiples CVEs
pip-audit --ignore-vuln CVE-2023-12345 --ignore-vuln CVE-2023-67890
# Ignorar por GHSA (GitHub Security Advisory) ID
pip-audit --ignore-vuln GHSA-xxxx-xxxx-xxxx
Archivo de configuración
# pyproject.toml
[tool.pip-audit]
strict = true
requirement = ["requirements.txt"]
ignore-vuln = ["CVE-2023-12345", "GHSA-xxxx-xxxx-xxxx"]
output-format = "json"
output-file = "audit-report.json"
Fixear vulnerabilidades automáticamente
# Upgradear automáticamente paquetes vulnerables
pip-audit --fix
# Dry run — mostrar qué se upgradearía
pip-audit --fix --dry-run
# Fixear y escribir a requirements.txt
pip-audit --fix --require-hashes
Escanear con hash checking
# Verificar hashes de paquetes durante el scan
pip-audit --require-hashes -r requirements.txt
# Esto asegura que los paquetes no fueron tampered
Integración con CI/CD usando GitHub Actions
# .github/workflows/pip-audit.yml
name: pip-audit
on: [push, pull_request, schedule]
# Schedule: correr semanalmente para atrapar nuevos CVEs
on:
push:
pull_request:
schedule:
- cron: '0 6 * * 1' # Todos los lunes 6 AM UTC
jobs:
pip-audit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Install pip-audit
run: pip install pip-audit
- name: Run pip-audit
run: |
pip-audit -r requirements.txt -f json -o audit-report.json || true
- name: Check for HIGH severity vulnerabilities
run: |
HIGH_COUNT=$(python -c "
import json
with open('audit-report.json') as f:
data = json.load(f)
# Contar dependencias con vulnerabilidades
count = sum(1 for dep in data.get('dependencies', []) if dep.get('vulns'))
print(count)
")
if [ "$HIGH_COUNT" -gt 0 ]; then
echo "Found $HIGH_COUNT packages with vulnerabilities"
cat audit-report.json
exit 1
fi
- name: Upload report
if: always()
uses: actions/upload-artifact@v4
with:
name: pip-audit-report
path: audit-report.json
CI/CD con Poetry
# .github/workflows/pip-audit-poetry.yml
name: pip-audit (Poetry)
on: [push, pull_request]
jobs:
audit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Install Poetry
run: pip install poetry
- name: Install dependencies
run: poetry install --no-root
- name: Run pip-audit
run: |
poetry run pip-audit --requirement poetry.lock --strict -f json -o audit-report.json
- name: Upload report
if: always()
uses: actions/upload-artifact@v4
with:
name: pip-audit-report
path: audit-report.json
Pre-commit hook
# .pre-commit-config.yaml
repos:
- repo: https://github.com/pypa/pip-audit
rev: v2.7.3
hooks:
- id: pip-audit
args: ["--strict", "--requirement", "requirements.txt"]
files: ^requirements\.txt$
Integración con Makefile
# Makefile
.PHONY: audit
audit:
pip-audit -r requirements.txt --strict -f json -o audit-report.json
@echo "Audit complete. Report: audit-report.json"
.PHONY: audit-fix
audit-fix:
pip-audit -r requirements.txt --fix --dry-run
.PHONY: audit-html
audit-html:
pip-audit -r requirements.txt -f html -o audit-report.html
Workflow de remediación
# 1. Identificar paquetes vulnerables
pip-audit -r requirements.txt
# Output:
# Name Version Fix Versions CVE ID Description
# requests 2.28.0 2.31.0 CVE-2023-32681 Proxy-Authorization header leak
# 2. Chequear qué cambió en el fix
pip install requests==2.31.0 --dry-run
# 3. Upgradear el paquete vulnerable
pip install --upgrade requests==2.31.0
# 4. Actualizar requirements.txt
pip freeze | grep requests > requirements.txt
# 5. Re-escanear para verificar el fix
pip-audit -r requirements.txt
Usar pip-audit con constraints
# Escanear con constraints (e.g., Python version constraints)
pip-audit -r requirements.txt -c constraints.txt
# constraints.txt
# requests>=2.31.0
# urllib3>=2.0.0
Variants
pip-audit con Docker
# Dockerfile — escanear durante build
FROM python:3.12-slim AS audit
RUN pip install pip-audit
COPY requirements.txt .
RUN pip-audit -r requirements.txt --strict
FROM python:3.12-slim
COPY --from=audit /app /app
WORKDIR /app
RUN pip install -r requirements.txt
CMD ["python", "main.py"]
pip-audit con uv
# Instalar pip-audit con uv
uv add --dev pip-audit
# Escanear uv.lock
uv run pip-audit --requirement uv.lock --strict
# Escanear en CI
uv run pip-audit --requirement uv.lock -f json -o audit-report.json
pip-audit con Dependabot
# .github/dependabot.yml
version: 2
updates:
- package-ecosystem: "pip"
directory: "/"
schedule:
interval: "weekly"
# Dependabot abre PRs para paquetes desactualizados
# pip-audit atrapa CVEs que Dependabot podría perder
Escanear virtual environments
# Escanear el virtual environment actual
source .venv/bin/activate
pip-audit
# Escanear un entorno específico
pip-audit --path /path/to/venv
# Escanear el system Python
pip-audit --system
Best Practices
-
For a deeper guide, see Find Security Issues in Python Code with Bandit.
-
Corré pip-audit en CI/CD en cada push — atrapá paquetes vulnerables early
-
Scheduleá scans semanales — nuevos CVEs se publican diariamente
-
Usá
--stricten CI — fallá el build en cualquier vulnerabilidad -
Documentá los CVEs ignorados — creá una política de ignore con fechas de expiración
-
Combiná con Bandit — pip-audit chequea dependencias, Bandit chequea código
-
Pineá versiones de paquetes — usá
requirements.txtcon versiones exactas, no ranges -
Revisá los audit reports regularmente — no solo ignores y olvides
-
Usá
--fixcon precaución — upgradear paquetes puede introducir breaking changes
Common Mistakes
- Ignorar todas las vulnerabilidades: usar
--ignore-vulnpara cada finding sin investigar. Algunos CVEs son críticos y necesitan atención inmediata. - No pinear versiones: escanear requirements no pineados (
requests>=2.0) da resultados inexactos. Pineá versiones exactas. - Solo escanear requirements de producción: las dev dependencies también pueden tener vulnerabilidades. Escaneá ambas.
- No schedulear scans regulares: correr pip-audit una vez no es suficiente. Nuevos CVEs se publican diariamente.
- Upgradear sin testear:
--fixupgradear paquetes automáticamente, lo que puede romper tu código. Siempre testeá después de upgradear.
FAQ
¿Qué es pip-audit?
Una herramienta que escanea dependencias de paquetes Python en busca de vulnerabilidades de seguridad conocidas usando la base de datos OSV.dev. Es gratis, open-source, y mantenida por la Python Packaging Authority (PyPA).
¿En qué se diferencia pip-audit de safety?
pip-audit es gratis y usa la base de datos OSV.dev. safety requiere una API key paga para coverage completo de vulnerabilidades. Ambos escanean dependencias Python, pero pip-audit es la opción gratis recomendada.
¿Qué base de datos usa pip-audit?
pip-audit usa la base de datos OSV.dev mantenida por Google, que agrega vulnerabilidades de PyPA Advisory Database, GitHub Security Advisories, y NVD.
¿Debería usar pip-audit o Dependabot?
Ambos. Dependabot abre PRs para upgradear paquetes desactualizados. pip-audit escanea en busca de CVEs conocidos y puede atrapar issues que Dependabot se pierde. Usalos juntos.
¿Puede pip-audit fixear vulnerabilidades automáticamente?
Sí, usá pip-audit --fix para upgradear automáticamente paquetes vulnerables. Usá --dry-run primero para ver qué cambiaría. Siempre testeá después de upgradear.
Recursos Relacionados
Find Security Issues in Python Code with Bandit
How to use Bandit to scan Python code for common security vulnerabilities, configure ignore lists, integrate with CI/CD, and interpret results.
RecipeStrict Type Checking in Python with mypy
How to configure mypy strict mode for Python projects, handle common type errors, use Protocol and TypeGuard, and integrate with CI/CD.
RecipeShare Workflow Logic with GitHub Actions Reusable Workflows
How to create and consume reusable workflows in GitHub Actions, covering inputs, secrets, conditional jobs, matrix strategy, and organization-wide sharing.