Project Goal: Demonstrate hands-on Software Composition Analysis (SCA) capabilities using open-source tools to identify, analyze, and remediate container vulnerabilities.
Overall Risk Assessment: π΄ CRITICAL (95/100)
| Metric | Result | Impact |
|---|---|---|
| Total Vulnerabilities | 3,286 across 4 images | Massive attack surface |
| Critical Severity | 330 CVEs | Remote Code Execution risk |
| High Severity | 2,956 CVEs | Data breach potential |
| Unfixable (EOL OS) | 100% | Requires base image migration |
| Remediation Effort | 2-4 hours | 98-99% reduction possible |
Key Finding: End-of-Life operating systems (Debian 9/10) accumulate vulnerabilities with no patch availability. Migrating to Alpine Linux reduces vulnerabilities by 98.3% (470 β 8 CVEs).
Business Impact:
- Without remediation: High probability of exploitation via known CVEs (CVSS 9.8/10)
- With remediation: Attack surface reduced by 99.6% using distroless containers
- Cost: 2 hours development time vs. potential $4.2M average breach cost (IBM 2025)
What is this? I built a Software Composition Analysis (SCA) lab using Trivy to learn how to find vulnerabilities in Docker containers. This project closes my knowledge gap with commercial tools like BlackDuck.
What I found: I scanned 4 container images (2 custom apps + 2 base images) and identified 3,286 total vulnerabilities. My custom vulnerable applications alone had 1,646 critical/high vulnerabilities because they use End-of-Life operating systems that no longer receive security patches.
ββββββββββββββββββββ¬βββββββββββββ¬βββββββββββ¬ββββββββ¬βββββββββββββββ
β Image β Total Vul β CRITICAL β HIGH β Base OS β
ββββββββββββββββββββΌβββββββββββββΌβββββββββββΌββββββββΌβββββββββββββββ€
β vuln-node-app β 468 β 80 β 388 β Debian 9 EOL β
β vuln-python-app β 1,178 β 85 β 1,093 β Debian 10 EOLβ
β node:14.17.0 β 470 β 30 β 440 β Debian 9 EOL β
β python:3.8.10 β 1,170 β 85 β 1,085 β Debian 10 EOLβ
ββββββββββββββββββββ΄βββββββββββββ΄βββββββββββ΄ββββββββ΄βββββββββββββββ
Why this matters: If you deploy containers with these images, you inherit all these vulnerabilities. Industrial equipment with long lifecycles (5-10 years) needs continuous scanning to catch these risks.
βββββββββββββββββββ
β Pull/Build β
β Docker Image β
ββββββββββ¬βββββββββ
β
βΌ
βββββββββββββββββββ ββββββββββββββββββββ
β Trivy Scan βββββββΆβ Vulnerability β
β (CRITICAL/HIGH)β β Database (83MB) β
ββββββββββ¬βββββββββ ββββββββββββββββββββ
β
βΌ
βββββββββββββββββββ
β Generate β
β JSON Report β
β (3.8 MB) β
ββββββββββ¬βββββββββ
β
βΌ
βββββββββββββββββββ ββββββββββββββββββββ
β Parse with jq βββββββΆβ Extract CVEs β
β Filter Results β β Group by Packageβ
ββββββββββ¬βββββββββ ββββββββββββββββββββ
β
βΌ
βββββββββββββββββββ
β Investigate β
β Top CVEs in β
β NIST NVD β
ββββββββββ¬βββββββββ
β
βΌ
βββββββββββββββββββ
β Document β
β Findings & β
β Remediation β
βββββββββββββββββββ
brew install trivyI created intentionally vulnerable Docker containers to understand dependency risks:
# Build Node.js app with old packages
cd 01-container-scanning/vulnerable-node-app
docker build -t vuln-node-app .# Build Python app with old packages
cd ../vulnerable-python-app
docker build -t vuln-python-app .# Scan both apps
trivy image --severity CRITICAL,HIGH vuln-node-app
trivy image --severity CRITICAL,HIGH vuln-python-appNode.js App Scan Results:
- Total: 468 vulnerabilities (80 CRITICAL, 388 HIGH)
- Debian 9.13 OS: 434 vulnerabilities
- Node.js packages: 34 vulnerabilities (express, axios, lodash, moment)
Python App Scan Results:
- Total: 1,178 vulnerabilities (85 CRITICAL, 1,093 HIGH)
- Debian 10 OS: 1,166 vulnerabilities
- Python packages: 12 vulnerabilities (Flask, cryptography, urllib3, setuptools)
I also scanned the official base images to compare:
# Scan official images
trivy image --severity CRITICAL,HIGH node:14.17.0
trivy image --severity CRITICAL,HIGH python:3.8.10I parsed the 3.8 MB JSON output to find patterns:
- 30 CRITICAL CVEs in node:14.17.0
- 40% of critical vulns affect libwebp (image processing)
- 7 expat vulnerabilities (XML parser used everywhere)
- dpkg vulnerability (Debian package manager itself is vulnerable)
See FINDINGS.md for detailed CVE analysis.
I compared different base images:
| Base Image | Vulnerabilities | Fix Time |
|---|---|---|
| node:14.17.0 (Debian 9) | 470 | Baseline |
| node:20-alpine3.19 | ~8 | 98% reduction |
| gcr.io/distroless/nodejs20 | ~2 | 99.6% reduction |
Lesson: Just changing the base image cuts vulnerabilities by 98%.
opensource-sca-security-lab/
βββ ASLabs_Logo.png # Brand logo
βββ FINDINGS.md # Detailed CVE analysis & investigation
βββ VISUAL_SUMMARY.md # Data visualization and charts
βββ README.md # This file
βββ Screenshots/ # Visual proof of scans
β βββ 01-docker-build-node-app.png
β βββ 02-docker-build-python-app.png
β βββ 03-node-scan-summary.png
β βββ 04-node-package-vulnerabilities.png
β βββ 05-python-scan-summary.png
β βββ 06-python-critical-cves.png
βββ 01-container-scanning/
β βββ vulnerable-node-app/ # Test Node.js app
β β βββ Dockerfile # node:14.17.0 + vulnerable packages
β β βββ package.json # express 4.17.1, axios 0.21.1, etc.
β β βββ app.js
β βββ vulnerable-python-app/ # Test Python app
β β βββ Dockerfile # python:3.8.10 + vulnerable packages
β β βββ requirements.txt # Flask 2.0.1, cryptography 3.3.2, etc.
β β βββ app.py
β βββ scan-results/
β βββ node-14-detailed.json # 3.8 MB full Trivy scan output
β βββ vuln-node-app-scan.txt # 758 KB scan log (468 vulns)
β βββ vuln-python-app-scan.txt # 97 KB scan log (1,178 vulns)
βββ 04-automation/
βββ scan-all.sh # Batch scanning script
-
EOL Operating Systems Are Dangerous
Debian 9 reached End-of-Life in 2022, so none of the 470 vulnerabilities get security patches. The only fix is upgrading the entire base image. -
Development Packages Shouldn't Be in Production
I foundlibexpat1-dev,libwebp-devin the results. These are compiler headers that increase attack surface without any runtime benefit. -
JSON Parsing Is Essential
Trivy outputs 3.8 MB of JSON. I had to learnjqto extract useful insights:# Count CRITICAL CVEs by package jq -r '.Results[].Vulnerabilities[] | select(.Severity == "CRITICAL") | .PkgName' scan-results.json | sort | uniq -c | sort -rn
-
Not All CVEs Are Equal
Some CRITICAL CVEs require specific conditions to exploit. I learned to read NIST NVD descriptions to understand real vs. theoretical risk.
-
First scan took 17 minutes because Trivy downloads an 83 MB vulnerability database. I had to set
TRIVY_TIMEOUT=15m. -
Too much data - 1,640 vulnerabilities is overwhelming. I focused on CRITICAL severity first (30 CVEs), then investigated the top 5 by researching them in NIST NVD.
-
Understanding what SCA actually is - I thought it was just "scanning dependencies." It's really about supply chain transparency: knowing everything in your software stack and tracking vulnerabilities throughout the product lifecycle.
- Trivy v0.68.2 - Open-source container scanner
- Docker - Container platform
- jq - JSON parsing
- NIST NVD - CVE database for research
- Generate SBOMs in CycloneDX format using
trivy sbomβ Completed Jan 23, 2026 - Automate scanning pipeline with GitHub Actions
- Add CVSS vector strings to all top CVEs β Completed in FINDINGS.md
- Create risk prioritization matrix (Likelihood Γ Impact) β Completed in FINDINGS.md
- Map vulnerabilities to OWASP Top 10 categories
CycloneDX SBOMs generated for supply chain visibility:
| Image | SBOM File | Size | Components |
|---|---|---|---|
| node:14.17.0 | 03-sbom-generation/container-sboms/node-14-sbom.json |
1.4 MB | Debian 9 + Node.js packages |
| python:3.8.10 | 03-sbom-generation/container-sboms/python-3.8-sbom.json |
888 KB | Debian 10 + Python packages |
Generation Command:
trivy image --format cyclonedx --output sbom.json <image>- Trivy Documentation
- NIST National Vulnerability Database
- Debian Security Tracker
- Docker Security Best Practices
ASLabs - AllyShip Security Laboratories
LinkedIn: Precious Robert
Email: support@allyshipglobal.com
GitHub: https://github.com/robertpreshyl/opensource-sca-security-lab
Status: Portfolio project demonstrating hands-on SCA vulnerability analysis








