Skip to content

Commit

Permalink
Add GitHub action that checks the latest release for vulnerabilities …
Browse files Browse the repository at this point in the history
…and reports them in an issue

Signed-off-by: Sascha Schwarze <[email protected]>
  • Loading branch information
SaschaSchwarze0 committed Oct 29, 2024
1 parent 859fe4f commit 1871613
Show file tree
Hide file tree
Showing 2 changed files with 130 additions and 0 deletions.
95 changes: 95 additions & 0 deletions .github/report-release-vulnerabilities.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
#!/usr/bin/env bash

set -euo pipefail

# download the release.yaml
gh release download --clobber --pattern release.yaml --output /tmp/release.yaml

# extract the images
readarray -t images < <(grep ghcr.io /tmp/release.yaml | sed -E 's/(image|value)://' | tr -d ' ' | sort -u)

# capture whether vulnerabilities exist
hasVulnerabilities=false

# iterate the images
true>/tmp/report.md
for image in "${images[@]}"; do
echo "[INFO] Checking image ${image}"
echo "## ${image}" >>/tmp/report.md

# OS vulnerabilities
echo " [INFO] Checking for OS vulnerabilities"
echo "### OS vulnerabilities" >>/tmp/report.md
osVulns="$(trivy image --format json --ignore-unfixed --no-progress --pkg-types os --scanners vuln --skip-db-update --timeout 10m "${image}")"
osVulnsFound=false
while read -r id pkg severity vulnerableVersion fixedVersion; do
if [ "${id}" == "" ]; then
continue
fi

if [ "${osVulnsFound}" == "false" ]; then
echo "| Vulnerability | Package | Severity | Version |" >>/tmp/report.md
echo "| -- | -- | -- | -- |" >>/tmp/report.md
osVulnsFound=true
hasVulnerabilities=true
fi

severityLower="$(tr '[:upper:]' '[:lower:]' <<<"${severity}")"

echo " [INFO] Found ${id} in ${pkg} with severity ${severityLower}. Requires upgrade from ${vulnerableVersion} to ${fixedVersion}."
echo "| ${id} | ${pkg} | ${severityLower} | ${vulnerableVersion} -> ${fixedVersion} |" >>/tmp/report.md
done <<<"$(jq --raw-output '.Results[0].Vulnerabilities[] | [ .VulnerabilityID, .PkgName, .Severity, .InstalledVersion, .FixedVersion ] | @tsv' <<<"${osVulns}")"

if [ "${osVulnsFound}" == "false" ]; then
echo " [INFO] No vulnerabilities found."
echo "No vulnerabilities found." >>/tmp/report.md
fi

# Go vulnerabilities
echo " [INFO] Checking for Go vulnerabilities"
echo "### Go vulnerabilities" >>/tmp/report.md
entrypoint="$(crane config "${image}" | jq -r '.config.Entrypoint[0]')"
crane export "${image}" - | tar -xf - -C /tmp "${entrypoint}"
goVulns="$(govulncheck -format json -mode binary "/tmp${entrypoint}")"
goVulnsFound=false
while read -r id pkg vulnerableVersion fixedVersion; do
if [ "${id}" == "" ]; then
continue
fi

if [ "${goVulnsFound}" == "false" ]; then
echo "| Vulnerability | Package | Version |" >>/tmp/report.md
echo "| -- | -- | -- |" >>/tmp/report.md
goVulnsFound=true
hasVulnerabilities=true
fi

echo " [INFO] Found ${id} in ${pkg}. Requires upgrade from ${vulnerableVersion} to ${fixedVersion}."
echo "| ${id} | ${pkg} | ${vulnerableVersion} -> ${fixedVersion} |" >>/tmp/report.md
done <<<"$(jq --raw-output 'select(.finding != null and .finding.fixed_version != null) | [ .finding.osv, .finding.trace[0].module, .finding.trace[0].version, .finding.fixed_version ] | @tsv' <<<"${goVulns}" | sort -u)"

if [ "${goVulnsFound}" == "false" ]; then
echo " [INFO] No vulnerabilities found."
echo "No vulnerabilities found." >>/tmp/report.md
fi
done

# check if issue exists, if yes, update description, otherwise create one, or close it if vulnerabilities are gone
issues="$(gh issue list --label release-vulnerabilities --json number)"

if [ "$(jq length <<<"${issues}")" == "0" ]; then
if [ "${hasVulnerabilities}" == "true" ]; then
# create new issue
echo "[INFO] Creating new issue"
gh issue create --label release-vulnerabilities --title "Vulnerabilities found in latest release" --body-file /tmp/report.md
fi
else
issueNumber="$(jq '.[0].number' <<<"${issues}")"
if [ "${hasVulnerabilities}" == "true" ]; then
# update issue
echo "[INFO] Updating existing issue ${issueNumber}"
gh issue edit "${issueNumber}" --body-file /tmp/report.md
else
gh issue close --reason "No vulnerabilities found in the latest release"
fi
fi
35 changes: 35 additions & 0 deletions .github/workflows/report-release-vulnerabilities.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
---
# This workflow downloads the latest release and checks it for OS and Go vulnerabilities.
# An issue is opened with a summary
name: Report release vulnerabilities
on:
schedule:
- cron: '0 0 * * *'
workflow_dispatch: {}
jobs:
report-vulnerabilities:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Install Go
uses: actions/setup-go@v5
with:
go-version: '1.22.x'
cache: true
check-latest: true
- name: Install Retry
run: curl --silent --location https://raw.githubusercontent.com/homeport/retry/main/hack/download.sh | bash
- name: Install Trivy
run: make install-trivy
- name: Update Trivy database
env:
TRIVY_USERNAME: ${{ github.repository_owner }}
TRIVY_PASSWORD: ${{ github.token }}
run: retry trivy image --download-db-only
- name: Install govulncheck
run: go install golang.org/x/vuln/cmd/govulncheck@latest
- name: Run vulnerability check
env:
GH_TOKEN: ${{ github.token }}
run: ./.github/report-release-vulnerabilities.sh

0 comments on commit 1871613

Please sign in to comment.