ReviewOS

also looking at this

craft-native/craft

fix(security): validate vulnerability scans and pin scanner downloads

#300
Merged glennmichael123 wants to merge codex/failure-safe-vulnerability-scan into main
5 files +192 -56
.github/workflows/sbom.ymlmodified+21-56
Changes to .github/workflows/sbom.yml
@@ -33,8 +33,13 @@ jobs:
3333
3434 - name: Install SBOM tools
3535 run: |
36 # Install Syft for comprehensive SBOM (works with bun.lock)
37 curl -sSfL https://raw.githubusercontent.com/anchore/syft/main/install.sh | sh -s -- -b /usr/local/bin
36 set -euo pipefail
37 mkdir -p "$RUNNER_TEMP/syft"
38 cd "$RUNNER_TEMP/syft"
39 curl --fail --location --retry 3 --output syft.tar.gz https://github.com/anchore/syft/releases/download/v1.52.0/syft_1.52.0_linux_amd64.tar.gz
40 echo 'caeedb81fb0491615f1ebd1761e4145d41ee86dd2cc7bf80669f9f5ad9d6133d syft.tar.gz' | sha256sum --check --strict
41 tar -xzf syft.tar.gz syft
42 echo "$RUNNER_TEMP/syft" >> "$GITHUB_PATH"
3843
3944 - name: Generate comprehensive SBOM (Syft)
4045 run: |
@@ -228,11 +233,13 @@ jobs:
228233 output-file: sbom/github-sbom.json
229234
230235 vulnerability-scan:
231 # name: SBOM Vulnerability Scan
232236 needs: generate
233237 runs-on: ubuntu-latest
234238
235239 steps:
240 - uses: actions/checkout@v6
241 - uses: oven-sh/setup-bun@v2
242
236243 - name: Download SBOM
237244 uses: actions/download-artifact@v4
238245 with:
@@ -241,64 +248,22 @@ jobs:
241248
242249 - name: Install Grype
243250 run: |
244 curl -sSfL https://raw.githubusercontent.com/anchore/grype/main/install.sh | sh -s -- -b /usr/local/bin
251 set -euo pipefail
252 mkdir -p "$RUNNER_TEMP/grype"
253 cd "$RUNNER_TEMP/grype"
254 curl --fail --location --retry 3 --output grype.tar.gz https://github.com/anchore/grype/releases/download/v0.119.0/grype_0.119.0_linux_amd64.tar.gz
255 echo '3fa2dc4b924621ab65404cf08d0b8438d896d80ab949c9d5a4ca283c36004c9b grype.tar.gz' | sha256sum --check --strict
256 tar -xzf grype.tar.gz grype
257 echo "$RUNNER_TEMP/grype" >> "$GITHUB_PATH"
245258
246 - name: Scan SBOM for vulnerabilities
247 id: scan
248 run: |
249 mkdir -p scan-results
250
251 # Scan the full SBOM
252 if [ -f "sbom/full-sbom.cyclonedx.json" ]; then
253 grype sbom:sbom/full-sbom.cyclonedx.json \
254 --output json \
255 --file scan-results/vulnerabilities.json \
256 || true
257
258 grype sbom:sbom/full-sbom.cyclonedx.json \
259 --output table \
260 --file scan-results/vulnerabilities.txt \
261 || true
262 fi
263
264 # Count vulnerabilities by severity
265 if [ -f "scan-results/vulnerabilities.json" ]; then
266 CRITICAL=$(jq '[.matches[] | select(.vulnerability.severity == "Critical")] | length' scan-results/vulnerabilities.json 2>/dev/null || echo "0")
267 HIGH=$(jq '[.matches[] | select(.vulnerability.severity == "High")] | length' scan-results/vulnerabilities.json 2>/dev/null || echo "0")
268 MEDIUM=$(jq '[.matches[] | select(.vulnerability.severity == "Medium")] | length' scan-results/vulnerabilities.json 2>/dev/null || echo "0")
269 LOW=$(jq '[.matches[] | select(.vulnerability.severity == "Low")] | length' scan-results/vulnerabilities.json 2>/dev/null || echo "0")
270
271 echo "critical=$CRITICAL" >> $GITHUB_OUTPUT
272 echo "high=$HIGH" >> $GITHUB_OUTPUT
273 echo "medium=$MEDIUM" >> $GITHUB_OUTPUT
274 echo "low=$LOW" >> $GITHUB_OUTPUT
275 fi
276
277 - name: Generate vulnerability report
278 run: |
279 echo "## Vulnerability Scan Results" >> $GITHUB_STEP_SUMMARY
280 echo "" >> $GITHUB_STEP_SUMMARY
281 echo "| Severity | Count |" >> $GITHUB_STEP_SUMMARY
282 echo "|----------|-------|" >> $GITHUB_STEP_SUMMARY
283 echo "| Critical | $ |" >> $GITHUB_STEP_SUMMARY
284 echo "| High | $ |" >> $GITHUB_STEP_SUMMARY
285 echo "| Medium | $ |" >> $GITHUB_STEP_SUMMARY
286 echo "| Low | $ |" >> $GITHUB_STEP_SUMMARY
287
288 if [ "$" -gt 0 ] || [ "$" -gt 0 ]; then
289 echo "" >> $GITHUB_STEP_SUMMARY
290 echo "⚠️ **Action Required:** Critical or High severity vulnerabilities found!" >> $GITHUB_STEP_SUMMARY
291 fi
259 - name: Scan and validate vulnerability report
260 run: bun scripts/scan-sbom.ts sbom/full-sbom.cyclonedx.json scan-results
292261
293262 - name: Upload scan results
263 if: ${{ always() }}
294264 uses: actions/upload-artifact@v4
295265 with:
296266 name: vulnerability-scan
297267 path: scan-results/
268 if-no-files-found: warn
298269 retention-days: 90
299
300 - name: Fail on critical vulnerabilities
301 if: steps.scan.outputs.critical > 0
302 run: |
303 echo "::error::Critical vulnerabilities found in dependencies!"
304 exit 1