From 2059d4d2eeb41efee0236ff537302475d8ca1546 Mon Sep 17 00:00:00 2001 From: Bruno Oliveira da Silva Date: Thu, 30 May 2024 17:29:41 -0300 Subject: [PATCH] Snyk report to identify branches impacted by a CVE Closes #29813 Signed-off-by: Bruno Oliveira da Silva --- .github/scripts/snyk-report.sh | 49 +++++++++++++++++++++++++++------- 1 file changed, 40 insertions(+), 9 deletions(-) diff --git a/.github/scripts/snyk-report.sh b/.github/scripts/snyk-report.sh index 1238cb8411..5630d94107 100755 --- a/.github/scripts/snyk-report.sh +++ b/.github/scripts/snyk-report.sh @@ -1,7 +1,14 @@ #!/bin/bash -e KEYCLOAK_REPO="keycloak/keycloak" -# Prevent duplicates by checking if a similar title exists +BRANCH_NAME=$(git rev-parse --abbrev-ref HEAD) + +# Extract the version number if BRANCH_NAME contains a slash +if [[ $BRANCH_NAME == *\/* ]]; then + BRANCH_NAME=$(echo $BRANCH_NAME | grep -oP '\d+\.\d+') +fi + +# Prevent duplicates by checking if a similar CVE ID exists check_github_issue_exists() { local issue_title="$1" # Extract the CVE ID @@ -13,10 +20,11 @@ check_github_issue_exists() { # Check for bad credentials if printf "%s" "$response" | jq -e '.message == "Bad credentials"' > /dev/null; then printf "Error: Bad credentials\n%s\n" "$response" + echo "Error: Bad credentials. Aborting script." exit 1 fi - # Check if we reached GitHub rate limiting + # Check for rate limiting if printf "%s" "$response" | jq -e '.message == "API rate limit exceeded"' > /dev/null; then printf "Error: API rate limit exceeded\n%s\n" "$response" exit 1 @@ -29,9 +37,10 @@ check_github_issue_exists() { fi if [[ $count -gt 0 ]]; then - return 0 + local issue_id=$(echo "$response" | jq -r '.items[0].number') + echo "$issue_id" else - return 1 + echo "1" fi } @@ -41,8 +50,8 @@ create_github_issue() { local body="$2" local api_url="https://api.github.com/repos/$KEYCLOAK_REPO/issues" - local data=$(jq -n --arg title "$title" --arg body "$body" \ - '{title: $title, body: $body, labels: ["status/triage", "kind/cve", "kind/bug"]}') + local data=$(jq -n --arg title "$title" --arg body "$body" --arg branch "backport/$BRANCH_NAME" \ + '{title: $title, body: $body, labels: ["status/triage", "kind/cve", "kind/bug", $branch]}') local response=$(curl -s -w "%{http_code}" -X POST -H "Authorization: token $GITHUB_TOKEN" -H "Content-Type: application/json" -d "$data" "$api_url") local http_code=$(echo "$response" | tail -n1) @@ -54,12 +63,31 @@ create_github_issue() { fi } +# Update existing issue based on the branches affected +update_github_issue() { + local issue_id="$1" + local api_url="https://api.github.com/repos/$KEYCLOAK_REPO/issues/$issue_id" + local existing_labels=$(curl -s -H "Authorization: token $GITHUB_TOKEN" -H "Accept: application/vnd.github.v3+json" "$api_url" | jq '.labels | .[].name' | jq -s .) + local new_label="backport/$BRANCH_NAME" + local updated_labels=$(echo "$existing_labels" | jq --arg new_label "$new_label" '. + [$new_label] | unique') + local data=$(jq -n --argjson labels "$updated_labels" '{labels: $labels}') + local response=$(curl -s -w "%{http_code}" -X PATCH -H "Authorization: token $GITHUB_TOKEN" -H "Content-Type: application/json" -d "$data" "$api_url") + local http_code=$(echo "$response" | tail -n1) + + if [[ $http_code -eq 200 ]]; then + return 0 + else + printf "Issue update failed with status: %s\n" "$http_code" + exit 1 + fi +} + check_dependencies() { command -v jq >/dev/null 2>&1 || { echo >&2 "jq is required. Exiting."; exit 1; } } # Parse the CVE report coming from SNYK -parse_and_print_vulnerabilities() { +parse_and_process_vulnerabilities() { jq -c '.vulnerabilities[] | select(.type != "license")' | while IFS= read -r vulnerability; do local cve_title=$(echo "$vulnerability" | jq -r '(.identifiers.CVE[0] // .id) + " - " + (.title // "N/A")') local module=$(echo "$vulnerability" | jq -r '((.mavenModuleName.groupId // "unknown") + ":" + (.mavenModuleName.artifactId // "unknown"))') @@ -68,8 +96,11 @@ parse_and_print_vulnerabilities() { local description=$(echo "$vulnerability" | jq -r '.description // "N/A"') printf -v body "%s\n%s\n%s\n%s" "$title" "$module" "$from_path" "$description" - if ! check_github_issue_exists "$cve_title"; then + issue_id=$(check_github_issue_exists "$cve_title") + if [[ $issue_id -eq 1 ]]; then create_github_issue "$title" "$body" + else + update_github_issue "$issue_id" fi done } @@ -82,7 +113,7 @@ main() { echo "Usage: cat snyk-report.json | $0" exit 1 else - parse_and_print_vulnerabilities + parse_and_process_vulnerabilities fi }