Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions .github/actions/scan-dependencies/action.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,13 @@ runs:
run: |
export BUILD_DATETIME=${{ inputs.build_datetime }}
./scripts/reports/scan-vulnerabilities.sh
- name: "Generate vulnerabilities summary"
shell: bash
run: |
./scripts/reports/parse-vulnerabilities.sh vulnerabilities-repository-report.json | tee vulnerabilities-summary.md
if [[ -n "${GITHUB_STEP_SUMMARY:-}" ]]; then
cat vulnerabilities-summary.md >> "$GITHUB_STEP_SUMMARY"
fi
- name: "Compress vulnerabilities report"
shell: bash
run: zip vulnerabilities-repository-report.json.zip vulnerabilities-repository-report.json
Expand All @@ -52,6 +59,23 @@ runs:
name: vulnerabilities-repository-report.json.zip
path: ./vulnerabilities-repository-report.json.zip
retention-days: 21
- name: "Upload vulnerabilities summary as an artefact"
if: ${{ !env.ACT }}
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: vulnerabilities-summary.md
path: ./vulnerabilities-summary.md
retention-days: 21
- name: "Fail if Critical or High vulnerabilities found"
shell: bash
run: |
CRITICAL_COUNT=$(jq '[.matches[] | select(.vulnerability.severity == "Critical")] | length' vulnerabilities-repository-report.json)
HIGH_COUNT=$(jq '[.matches[] | select(.vulnerability.severity == "High")] | length' vulnerabilities-repository-report.json)
echo "Critical: $CRITICAL_COUNT, High: $HIGH_COUNT"
if [[ "$CRITICAL_COUNT" -gt 0 || "$HIGH_COUNT" -gt 0 ]]; then
echo "::error::Found $CRITICAL_COUNT Critical and $HIGH_COUNT High severity vulnerabilities"
exit 1
fi
- name: "Check prerequisites for sending the reports"
shell: bash
id: check
Expand Down
107 changes: 107 additions & 0 deletions scripts/reports/parse-vulnerabilities.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
#!/bin/bash
#
Comment thread
timireland marked this conversation as resolved.
# WARNING: This file is managed via the repository template.
# Local changes may diverge from the template source of truth.
#
# Parse vulnerability report JSON and output a human-readable summary
# Usage: ./parse-vulnerabilities.sh <path-to-report.json>
#

set -euo pipefail

if [[ $# -lt 1 ]]; then
echo "Usage: $0 <vulnerability-report.json>"
exit 1
fi

REPORT_FILE="$1"

if [[ ! -f "$REPORT_FILE" ]]; then
echo "Error: File not found: $REPORT_FILE"
exit 1
fi

if ! command -v jq &> /dev/null; then
echo "Error: jq is required but not installed"
exit 1
fi

# Get counts by severity
count_unique_severity() {
local severity="$1"

jq -r --arg sev "$severity" '
[.matches[] | select(.vulnerability.severity == $sev) | {
id: .vulnerability.id,
package: .artifact.name,
version: .artifact.version
}]
| unique_by(.id + .package + .version)
| length
' "$REPORT_FILE"
}

echo "## Vulnerability Report Summary"
echo ""

CRITICAL_COUNT=$(count_unique_severity "Critical")
HIGH_COUNT=$(count_unique_severity "High")
MEDIUM_COUNT=$(count_unique_severity "Medium")
LOW_COUNT=$(count_unique_severity "Low")
TOTAL=$((CRITICAL_COUNT + HIGH_COUNT + MEDIUM_COUNT + LOW_COUNT))

echo "**Total: $TOTAL vulnerabilities** ($CRITICAL_COUNT Critical, $HIGH_COUNT High, $MEDIUM_COUNT Medium, $LOW_COUNT Low)"
echo ""

# Function to print vulnerabilities for a given severity
print_severity_section() {
local severity="$1"
local count="$2"

if [[ "$count" -eq 0 ]]; then
return
fi

echo "### $severity ($count)"
echo ""
echo "| Package | Language | Version | Fix | Description |"
echo "|---------|---------|---------|-----|-------------|"

jq -r --arg sev "$severity" '
[.matches[] | select(.vulnerability.severity == $sev) | {
id: .vulnerability.id,
severity: .vulnerability.severity,
package: .artifact.name,
language: .artifact.language,
version: .artifact.version,
fix: (.vulnerability.fix.versions[0] // "N/A"),
description: .vulnerability.description
}]
| unique_by(.id + .package + .version)
| sort_by(.package)
| .[]
| "| \(.package) | \(.language) | \(.version) | \(.fix) | \(.description[0:70])... |"
' "$REPORT_FILE"

echo ""
}

print_severity_section "Critical" "$CRITICAL_COUNT"
print_severity_section "High" "$HIGH_COUNT"
print_severity_section "Medium" "$MEDIUM_COUNT"
print_severity_section "Low" "$LOW_COUNT"

# Priority packages summary
echo "---"
echo ""
echo "### Priority Packages to Update"
echo ""

jq -r '
[.matches[] | select(.vulnerability.severity == "Critical" or .vulnerability.severity == "High") | .artifact.name]
| unique
| sort
| join(", ")
' "$REPORT_FILE" | fold -s -w 80

echo ""