How to Fix Vulnerable Dependency Errors in requirements.txt for PCI DSS Compliance
If you work with Python applications handling cardholder data, PCI DSS v4.0 Requirement 6.2.3 requires applying critical security patches within one month and others quarterly. Vulnerabilities in dependencies—even transitive ones listed in your requirements.txt—can fail automated scans under Requirement 11.3. We’ll cover tools like pip-audit and safety to detect these, then show how to fix them through upgrades, pinning, and locking for reproducible builds.
Why PCI DSS Matters for Python Dependencies\n\nPCI DSS Requirement 6.2 mandates timely patching of vulnerabilities in all software, including third-party dependencies. Transitive dependencies—those pulled in indirectly—count fully toward compliance. Requirement 11.3 requires quarterly external scans that will flag unpatched CVEs.\n\nWe’ve seen supply chain risks play out recently: the 2024 XZ Utils incident nearly compromised Linux distributions through a malicious dependency update. In PCI environments handling cardholder data, such issues could lead to breaches. Let’s address this systematically: audit your requirements.txt, upgrade or pin vulnerable packages, generate locked files with hashes, and enforce via CI/CD.
Step 1: Detect Vulnerabilities
pip-audit (PyPA Official, Free)
pip install pip-audit
pip-audit -r requirements.txt # Scans transitive deps
```bash
Output:
```bash
requests==2.31.0 : CVE-2024-XXXXX (Critical)
Fix: >=2.32.0
```bash
### safety CLI (from PyUp)\n\nSafety uses a curated vulnerability database, focusing on Python packages with verified entries.\n\n```bash\npip install safety\nsafety check -r requirements.txt --bare # Fail-fast for CI\n```\n\nUse safety when you prefer a more selective, Python-specific database, though it may miss ecosystem-wide issues found in OSV.bash
pip-audit draws from the OSV database for broad coverage, while safety uses a curated vulnerability database. Choose pip-audit for comprehensiveness in compliance audits; safety may suit faster CI checks.
## Step 2: Fix & Pin Versions
1. **Upgrade**:
```bash
pip install --upgrade requests>=2.32.0
```bash
2. **requirements.in** (top-level):
```bash
requests>=2.32.0
flask>=3.0.0 # Example
```bash
3. **Lock to requirements.txt** (exact + hashes for reproducibility/Req 6.2):
**uv** (notable for speed):
```bash
curl -LsSf https://astral.sh/uv/install.sh | sh
uv pip compile requirements.in --hashes -o requirements.txt
uv pip sync requirements.txt
```bash
**pip-tools**:
```bash
pip install pip-tools
pip-compile --generate-hashes requirements.in
pip-sync requirements.txt
```bash
Verify: `pip-audit -r requirements.txt` → clean.
## Step 3: CI/CD Enforcement (Req 6.2 Proof)
GitHub Actions:
```yaml\n- name: PCI DSS Dependency Audit\n run: |\n pipx install pip-audit safety # Or uv tool install\n pip-audit -r requirements.txt || exit 1\n safety check -r requirements.txt --bare || exit 1\n```
Pre-commit:
```yaml
- repo: https://github.com/pypa/pip-audit
rev: v2.10.0
hooks:
- id: pip-audit
args: [-r, requirements.txt]
```bash
## Common Pitfalls and Troubleshooting\n\nBefore moving to verification, note these issues we often encounter:\n\n- **Transitive dependencies**: Tools like pip-audit scan them fully, but without locking, `pip install` may pull new vulnerable versions. Always lock.\n- **Safe ignores**: Use `pip-audit --ignore-vuln CVE-XXXX` only for false positives or accepted risks, and document the decision in your security policy.\n- **Hash mismatches**: After upgrades, regenerate locks—old hashes won't match new wheels.\n- **Alternatives like httpx**: Sometimes swapping libraries (requests → httpx) resolves persistent issues without version constraints.\n\nSchedule quarterly lock regeneration and scans to stay ahead.
| Tool | PCI Fit | Speed | Hashes |
|------------|----------------------|-------|--------|
| pip-audit | Excellent (OSV) | Fast | Yes |
| safety | Good (curated DB) | Fast | No |
| uv lock | Excellent reproducibility | Fast | Yes |
## Verify PCI Readiness
```bash
pip-audit -r requirements.txt --format json | jq '.[].vulns | length' # 0 = compliant
```bash
## Wrapping Up\n\nWith pinned versions, hashed locks, and CI enforcement, you'll satisfy PCI DSS Requirements 6.2.3 and 11.3. We recommend running `pip-audit -r requirements.txt` regularly and automating quarterly reviews. Test these steps in your project—what vulnerabilities do you find? For more, see our guides on [specific CVEs](21-cve-2024-xxxxx-critical-vulnerability-in-requests-2-31-and-immediate-mitigation-steps.md) and [pip-audit](16-security-vulnerabilities-cves-pip-audit-safety.md). Sponsored by Durable Programming
Need help maintaining or upgrading your Python application? Durable Programming specializes in keeping Python apps secure, performant, and up-to-date.
Hire Durable Programming