# Supply Chain Security ## Rule Verify integrity of all dependencies. Generate SBOMs. Monitor for vulnerabilities. **Source:** [OWASP Top 10 2025 - A03 Software Supply Chain Failures](https://owasp.org/Top10/2025/A03_2025-Software_Supply_Chain_Failures/) ## Attack Examples - **SolarWinds (2019)**: Compromised build system, 18,000 orgs affected - **Bybit (2025)**: Supply chain attack in wallet software, $1.5B theft - **Shai-Hulud (2025)**: Self-propagating npm worm, 500+ packages ## Correct Pattern ```python # Generate and maintain SBOM import subprocess import json import hashlib def generate_sbom(project_path: str) -> dict: """Generate Software Bill of Materials.""" # Use CycloneDX or SPDX format result = subprocess.run( ["cyclonedx-py", "poetry", "-o", "sbom.json"], cwd=project_path, capture_output=True ) with open(f"{project_path}/sbom.json") as f: return json.load(f) # Verify package integrity def verify_package(package_path: str, expected_hash: str) -> bool: """Verify package hash before installation.""" with open(package_path, "rb") as f: actual_hash = hashlib.sha256(f.read()).hexdigest() return actual_hash == expected_hash # Pin dependencies with hashes # requirements.txt with hashes: # requests==2.28.0 --hash=sha256:abc123... # Lock file example (poetry.lock, package-lock.json) def verify_lockfile_integrity(lockfile_path: str) -> bool: """Ensure lockfile hasn't been tampered with.""" # Compare against known-good version in version control ... ``` ## Incorrect Pattern ```python # Wrong: no version pinning # requirements.txt # requests # flask # Wrong: pulling from arbitrary sources pip install https://sketchy-site.com/package.tar.gz # Wrong: no integrity verification def install_dependency(name): os.system(f"pip install {name}") # No hash check # Wrong: auto-updating without verification def auto_update(): os.system("pip install --upgrade -r requirements.txt") ``` ## Dependency Scanning ```python # Integrate vulnerability scanning in CI def scan_dependencies() -> list[dict]: """Scan for known vulnerabilities.""" # Use tools like: # - OWASP Dependency-Check # - Snyk # - GitHub Dependabot # - OSV (Open Source Vulnerabilities) result = subprocess.run( ["pip-audit", "--format=json"], capture_output=True ) return json.loads(result.stdout) def block_on_critical(vulnerabilities: list[dict]) -> bool: """Fail CI on critical vulnerabilities.""" critical = [v for v in vulnerabilities if v["severity"] == "CRITICAL"] if critical: raise SecurityError(f"Critical vulnerabilities found: {critical}") return True ``` ## CI/CD Hardening ```python # Verify CI/CD pipeline integrity PIPELINE_REQUIREMENTS = { "mfa_required": True, "branch_protection": True, "signed_commits": True, "code_review_required": True, "secrets_scanning": True, } def audit_pipeline(config: dict) -> list[str]: """Audit CI/CD configuration.""" issues = [] for requirement, expected in PIPELINE_REQUIREMENTS.items(): if config.get(requirement) != expected: issues.append(f"Missing: {requirement}") return issues ``` ## Edge Cases - Transitive dependencies (deps of deps) can be vulnerable - Typosquatting attacks (similar package names) - Dependency confusion (internal vs public package names) - Compromised maintainer accounts - Post-install scripts can execute arbitrary code - IDE extensions and dev tools are part of supply chain