Skip to content
Merged
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
51 changes: 50 additions & 1 deletion .github/workflows/snyk.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,11 @@ jobs:
- uses: taiki-e/install-action@1e29709c0ec63babbe8f266397a465f29a825f91 # v2.87.31
with:
tool: cargo-cyclonedx@0.5.9
# `snyk test` applies .snyk itself; `snyk sbom test` does not, so its ignores
# are applied here: a finding is dropped when .snyk ignores its ID for every
# path ('*') with an `expires` still to come. Without a .snyk nothing is
# ignored. Snyk exiting above 1 (an error), or output the filter cannot
# read, fails the job.
- name: Test each dependency set
env:
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
Expand All @@ -64,6 +69,50 @@ jobs:
if [ -z "$SNYK_TOKEN" ]; then
echo "::error::The SNYK_TOKEN repository secret is not set, so nothing was scanned."
fi
# {"<ID>": "<latest unexpired expires>"} for each ID .snyk ignores everywhere.
ignored='{}'
if [ -f .snyk ]; then
ignored=$(yq -o=json '.ignore // {}' .snyk | jq -c '
with_entries(.value = ([.value[] | .["*"]? | .expires? // empty
| select((sub("\\.[0-9]+"; "") | fromdateiso8601) > now)] | max))
Comment on lines +76 to +77

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔴 HIGH RISK

Iterate over the wildcard path-rule array before reading expires, for example by changing .["*"]? | .expires? to .["*"][]? | .expires?.

TIP React 👍 if this review is right, or reply with what's wrong and how it could be better to help improve the reviewer.

| with_entries(select(.value != null))')
fi
report=$RUNNER_TEMP/snyk.json
# Tests one SBOM and prints each finding as open or ignored; fails on an
# open finding or a result it cannot read.
sbom_test() {
local code=0 findings open
echo "== $1"
snyk sbom test --experimental --json --file="$1" > "$report" || code=$?
if [ "$code" -gt 1 ] || [ ! -s "$report" ]; then
cat "$report"; echo
echo "::error::snyk sbom test failed on $1 (exit $code)."
return 1
fi
# One line per vulnerable path, `open` or `ignored`.
if ! findings=$(jq -rn --argjson ignored "$ignored" '
[inputs | if type == "array" then .[] else . end]
| if length == 0 then error("no result in the Snyk output") else .[] end
| if (.vulnerabilities | type) == "array" then .vulnerabilities[]
else error("no vulnerabilities list in the Snyk output") end
| $ignored[.id] as $until
| "\(if $until then "ignored" else "open" end) [\(.severity // "?" | ascii_upcase)] \(.title) (\(.id)) in \(.packageName)@\(.version) via \(.from // [] | join(" > "))\(if $until then ", ignored until \($until)" else "" end)"
' "$report"); then
cat "$report"; echo
echo "::error::Could not read the Snyk results for $1."
return 1
fi
[ -z "$findings" ] || printf '%s\n' "$findings"
open=$(printf '%s\n' "$findings" | grep -c '^open ' || true)
if [ "$open" -gt 0 ]; then
echo "::error::$open open Snyk finding(s) in $1."
return 1
elif [ "$code" -eq 1 ] && [ -z "$findings" ]; then
cat "$report"; echo
echo "::error::Snyk failed $1 without listing a vulnerability."
return 1
fi
}
status=0
while IFS=: read -r kind target; do
[ -n "$kind" ] || continue
Expand All @@ -82,7 +131,7 @@ jobs:
|| { echo "::error::Cannot list the SBOMs for $target"; status=1; continue; }
[ -s "$list" ] || { echo "::error::cargo cyclonedx wrote no SBOM for $target"; status=1; continue; }
while IFS= read -r -d '' sbom; do
[ -z "$SNYK_TOKEN" ] || snyk sbom test --experimental --file="$sbom" || status=1
[ -z "$SNYK_TOKEN" ] || sbom_test "$sbom" || status=1
done < "$list" ;;
*) echo "::error::Unknown dependency set $kind:$target"; status=1 ;;
esac
Expand Down
Loading