Patching CVEs in Robusta: Automated Workflow
This skill automates the process of identifying and patching CVE vulnerabilities in the Robusta Docker image and Python dependencies, focusing on critical, high, and medium severity issues.
Overview
The workflow follows this systematic process:
- Vulnerability Scanning - Identify all CVEs in dependencies and Docker image
- Severity Filtering - Focus on critical, high, and medium severity issues
- Root Cause Analysis - Determine which packages/dependencies introduce vulnerabilities
- Upstream Research - Check if newer releases already include fixes
- Patch Implementation - Apply fixes via dependency upgrades or Dockerfile changes
- Validation - Verify CVE fixes and ensure application functionality
Step-by-Step Process
1. Vulnerability Scanning
Use multiple scanning tools to identify vulnerabilities:
# Scan Docker image for vulnerabilities
docker build -t robusta:latest .
docker scout cves robusta:latest
# Scan Python dependencies for vulnerabilities
pip-audit
safety check
# Validate pyproject.toml metadata and lockfile consistency (does not perform vulnerability scanning)
poetry check
# For CVE scanning of Python dependencies, use pip-audit, safety, or poetry-audit-plugin
What to extract:
- Affected package name and version
- CVE ID and severity level
- Fixed version (if available)
- Affected version range
2. Severity Filtering
Process vulnerabilities in this order:
- Critical - Must be fixed before release
- High - Should be fixed before release
- Medium - Fix when safe and non-breaking
Create a prioritized list and document each CVE:
CVE-XXXX-XXXXX (Critical): Package X - affects >=1.0.0,<1.2.0
Fixed in: 1.2.5
Status: Needs patching
CVE-YYYY-YYYYY (High): Package Y - affects >=2.0.0,<2.1.0
Fixed in: 2.1.3
Status: Needs patching
3. Python Dependency Patches
Two main strategies:
Strategy A: Direct Upgrade (Preferred)
- Check
poetry.lockfor affected packages - Update
pyproject.tomlwith patched version - Run
poetry update package-name - Verify in
poetry.lockthat lock file has updated to fixed version
Strategy B: Transitive Dependency Fix
- Identify the parent package bringing in vulnerable version
- Upgrade parent package to one with updated dependencies
- This automatically pulls in the fixed transitive dependency
4. Dockerfile Patches
For system-level vulnerabilities (non-Python packages):
Strategy A: Upgrade Base Image
- Check if newer Python 3.11-slim image includes fixes
- Update FROM statement:
FROM python:3.11-slim→ newer version
Strategy B: Explicit Package Installation
- Add specific package upgrade in RUN commands
- Example:
apt-get install -y libssl3for OpenSSL CVEs
Strategy C: Apply Patches
- Use patching tools for targeted fixes in builder stage
- Document with comments explaining which CVEs are fixed
5. Validation Checklist
✓ CVE Verification
- Run
docker scout cvesagain on patched image - Confirm target CVE no longer appears
- Note any remaining high/critical issues for tracking
✓ Build Verification
# Build the Docker image
docker build -t robusta:test .
# Verify build succeeds with no errors
echo "Build successful"
✓ Functional Testing
# Run basic smoke tests
pytest tests/ -v
✓ Dependency Check
# Verify no new vulnerabilities introduced
docker scout cves robusta:test --no-cache
# Validate pyproject.toml metadata and lockfile consistency
poetry check --lock
6. Documentation
Update these files with CVE fix details:
Dockerfile Comments:
# Patching CVE-XXXX-XXXXX (Critical): Package X
RUN apt-get install -y package-name
Key Considerations
Python Package CVEs
- Check if vulnerability is in the installed wheel vs source
- For indirect dependencies, finding the transitive source is critical
- Use
poetry why package-nameto understand dependency relationships - Go version matters for Go-based Python bindings (e.g., Cryptography)
System Library CVEs
- libexpat1, libssl, libc vulnerabilities are common
- These often have fixes in newer base images
- When possible, upgrade the base Python image before manual fixes
Testing Strategy
- Always rebuild and scan after each patch
- One CVE at a time is safer; group similar fixes together
- Document any CVEs that can't be patched with reasoning
Breaking Changes
- Verify patched versions don't introduce breaking changes
- Check release notes and migration guides
- Run full test suite, not just smoke tests for major upgrades
Implementation Notes
- Work through CVEs in severity order (Critical → High → Medium)
- For each CVE, follow the complete cycle: identify → research → patch → validate
- Commit each logical group of fixes separately
- Keep diagnostics available:
docker scout cvesoutput, dependency trees, test results - If a patch can't be safely applied, document why in the code comments
Common Issues and Solutions
Issue: Patch introduces breaking changes
Solution:
- Check if breaking change is in major version bump
- Review if dependency needs to be pinned differently
- Consider if a workaround exists (e.g., compatibility shim)
Issue: Transitive dependency is vulnerable
Solution:
- Find which package brings it in:
poetry why vulnerable-package - Update the parent package instead
- Re-lock dependencies and verify fix
Issue: CVE disappears after unrelated patch
Solution:
- Good sign - often due to transitive dependency updates
- Still verify with
docker scout cveson final image - Update documentation to credit upstream fixes
Source: robusta-dev/robusta — distributed by TomeVault.