-
Notifications
You must be signed in to change notification settings - Fork 113
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add GitHub action that checks the latest release for vulnerabilities …
…and reports them in an issue Signed-off-by: Sascha Schwarze <[email protected]>
- Loading branch information
1 parent
859fe4f
commit 1871613
Showing
2 changed files
with
130 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |