From 1645911bedca67bc4baa6ee5f33615b65583cbba Mon Sep 17 00:00:00 2001 From: farrell-m Date: Fri, 20 Dec 2024 12:03:04 +0000 Subject: [PATCH] integrate with snyk --- .github/workflows/pr-merge-main.yml | 29 +++++++- .github/workflows/push-branch.yml | 35 +++++++++- .gitignore | 2 + .snyk | 8 +++ README.md | 39 +++++++++++ snyk/snyk_delta_all_projects.sh | 102 ++++++++++++++++++++++++++++ 6 files changed, 212 insertions(+), 3 deletions(-) create mode 100644 .snyk create mode 100755 snyk/snyk_delta_all_projects.sh diff --git a/.github/workflows/pr-merge-main.yml b/.github/workflows/pr-merge-main.yml index ce71c88..316b31b 100644 --- a/.github/workflows/pr-merge-main.yml +++ b/.github/workflows/pr-merge-main.yml @@ -56,4 +56,31 @@ jobs: - name: Update version uses: gradle/gradle-build-action@749f47bda3e44aa060e82d7b3ef7e40d953bd629 with: - arguments: release -Prelease.useAutomaticVersion=true \ No newline at end of file + arguments: release -Prelease.useAutomaticVersion=true + + vulnerability-report: + if: github.event.pull_request.merged == true + runs-on: ubuntu-latest + + env: + SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }} + SNYK_ORG: legal-aid-agency + SNYK_TEST_EXCLUDE: generated + + steps: + - uses: actions/checkout@v3 + - name: Generate Snyk report and upload to LAA Dashboard + uses: snyk/actions/gradle@0.4.0 + continue-on-error: true + with: + command: monitor + args: --org=${SNYK_ORG} --all-projects --exclude=$SNYK_TEST_EXCLUDE + - name: Generate sarif Snyk report + uses: snyk/actions/gradle@0.4.0 + continue-on-error: true + with: + args: --org=${SNYK_ORG} --all-projects --exclude=$SNYK_TEST_EXCLUDE --sarif-file-output=snyk-report.sarif + - name: Upload result to GitHub Code Scanning + uses: github/codeql-action/upload-sarif@v2 + with: + sarif_file: snyk-report.sarif \ No newline at end of file diff --git a/.github/workflows/push-branch.yml b/.github/workflows/push-branch.yml index c6f020a..d7e7dbb 100644 --- a/.github/workflows/push-branch.yml +++ b/.github/workflows/push-branch.yml @@ -47,10 +47,41 @@ jobs: uses: gradle/gradle-build-action@749f47bda3e44aa060e82d7b3ef7e40d953bd629 with: arguments: updateSnapshotVersion - - name: Publish package uses: gradle/gradle-build-action@749f47bda3e44aa060e82d7b3ef7e40d953bd629 with: arguments: publish env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + vulnerability-scan: + runs-on: ubuntu-latest + + env: + SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }} + SNYK_ORG: legal-aid-agency + SNYK_TEST_EXCLUDE: generated + + steps: + - uses: actions/checkout@v3 + - name: Set up JDK 21 + uses: actions/setup-java@v3 + with: + java-version: '21' + distribution: 'temurin' + - uses: snyk/actions/setup@0.4.0 + - name: Install snyk-delta + run: | + npm config set prefix '~/.local/' + mkdir -p ~/.local/bin + export PATH="$HOME/.local/bin/:$PATH" + npm install -g snyk-delta + - name: Identify new vulnerabilities + run: ./snyk/snyk_delta_all_projects.sh --org=$SNYK_ORG --exclude=$SNYK_TEST_EXCLUDE + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + - name: Run code test + uses: snyk/actions/gradle@0.4.0 + with: + command: code test + args: --org=${SNYK_ORG} diff --git a/.gitignore b/.gitignore index d2c422e..bbb6cc1 100644 --- a/.gitignore +++ b/.gitignore @@ -93,3 +93,5 @@ test-results/ .idea +# Snyk +.dccache diff --git a/.snyk b/.snyk new file mode 100644 index 0000000..14b2e28 --- /dev/null +++ b/.snyk @@ -0,0 +1,8 @@ +# Snyk (https://snyk.io) policy file, patches or ignores known vulnerabilities. +version: v1.25.1 +ignore: {} +patch: {} +exclude: + global: + - caab-service/src/test + - caab-service/src/integrationTest diff --git a/README.md b/README.md index 0c48830..7abbbb2 100644 --- a/README.md +++ b/README.md @@ -22,3 +22,42 @@ This API uses components from the [LAA CCMS Common Library](https://github.com/m - [laa-ccms-spring-boot-plugin](https://github.com/ministryofjustice/laa-ccms-spring-boot-common?tab=readme-ov-file#laa-ccms-spring-boot-gradle-plugin-for-java--spring-boot-projects) - [laa-ccms-spring-boot-starter-auth](https://github.com/ministryofjustice/laa-ccms-spring-boot-common/tree/main/laa-ccms-spring-boot-starters/laa-ccms-spring-boot-starter-auth) + +## Snyk code analysis (CI/CD) +This project publishes vulnerability scans to the [LAA Snyk Dashboard (Google SSO)](https://app.snyk.io/org/legal-aid-agency). + +If you cannot see the LAA organisation when logged into the dashboard, +please ask your lead developer/architect to have you added. + +Scans will be triggered in two ways: + +- Main branch - on commit, a vulnerability scan will be run and published to both the Snyk + server and GitHub Code Scanning. Vulnerabilites will not fail the build. +- Feature branches - on commit, a vulnerability scan will be run to identify any new + vulnerabilites (compared to the main branch). If new vulnerabilites have been raised. A code + scan will also run to identify known security issues within the source code. If any issues are + found, the build will fail. + +### Running Snyk locally +To run Snyk locally, you will need to [install the Snyk CLI](https://docs.snyk.io/snyk-cli/install-or-update-the-snyk-cli). + +Once installed, you will be able to run the following commands: + +```shell +snyk test +``` +For open-source vulnerabilies and licence issues. See [`snyk test`](https://docs.snyk.io/snyk-cli/commands/test). + +```shell +snyk code test +``` +For Static Application Security Testing (SAST) - known security issues. See [`snyk code test`](https://docs.snyk.io/snyk-cli/commands/code-test). + +A [JetBrains Plugin](https://plugins.jetbrains.com/plugin/10972-snyk-security) is also available to integrate with your IDE. In addition to +vulnerabilities, this plugin will also report code quality issues. + +### Configuration (`.snyk`) + +The [.snyk](.snyk) file is used to configure exclusions for scanning. If a vulnerability is not +deemed to be a threat, or will be dealt with later, it can be added here to stop the pipeline +failing. See [documentation](https://docs.snyk.io/manage-risk/policies/the-.snyk-file) for more details. diff --git a/snyk/snyk_delta_all_projects.sh b/snyk/snyk_delta_all_projects.sh new file mode 100755 index 0000000..541e655 --- /dev/null +++ b/snyk/snyk_delta_all_projects.sh @@ -0,0 +1,102 @@ +#!/bin/bash + + +# Copyright 2018 Snyk Ltd. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Permalink: https://github.com/snyk-tech-services/snyk-delta/blob/1a45cc1ec6b390d8e1b266b157e00453a4d12eb5/snyk_delta_all_projects.sh + +# Call this script as you would call snyk test | snyk-delta, minus the --all-projects and --json flags +# This is an interim fix until snyk-delta supports all projects itself (or snyk supports a --new flag) +# example: /bin/bash snyk_delta_all_projects.sh --severity=high --exclude=tests,resources -- -s config.yaml +# runs snyk test --all-projects --json $* +# requires jq to be installed + +set -euo pipefail + +exit_code=0 +snyk_test_json='' +formatted_json='' +args=("$*") + +run_snyk_delta () { + # add in any other arguments you would like to use + snyk-delta +} + +run_snyk_test () { + echo "Running: snyk test --all-projects --json" $args + local snyk_exit_code=0 + { + + snyk_test_json=`snyk test --all-projects --json $args` + + } || { + snyk_exit_code=$? + if [ $snyk_exit_code -eq 2 ] + then + echo 'snyk test command was not successful, retry with -d to see more information' + exit 2 + fi + } + + +} + +format_snyk_test_output() { + echo "Processing snyk test --json output" + { + formatted_json=`echo $snyk_test_json | jq -r 'if type=="array" then .[] else . end | @base64'` + } || { + echo 'failed to process snyk-test result' + exit 2 + } +} + + +####### +# 1. run snyk test +run_snyk_test + +# 2. format results to support single & multiple results returned +format_snyk_test_output + +# 3. call snyk-delta for each result +for test in `echo $formatted_json`; do + single_result="$(echo ${test} | base64 -d)" # use "base64 -d -i" on Windows, which will ignore any "gardage" characters echoing may add + project_name="$(echo ${single_result} | jq -r '.displayTargetFile')" + echo 'Processing: ' ${project_name} + if echo ${single_result} | run_snyk_delta + then + project_exit_code=$? + echo 'Finished processing' + else + project_exit_code=$? + if [ $project_exit_code -gt 1 ] + then + echo 'snyk-delta encountered an error, retrying.' + echo ${single_result} | run_snyk_delta + fi + echo 'Finished processing' + fi + + if [ $project_exit_code -gt $exit_code ] + then + exit_code=$project_exit_code + fi + echo "Project: ${project_name} | Exit code: ${project_exit_code}" +done + +echo "Overall exit code for snyk-delta-all-projects.sh: ${exit_code}" +exit $exit_code