Skip to content

Commit

Permalink
sast-snyk-check: increased version to 0.3
Browse files Browse the repository at this point in the history
Solves: https://issues.redhat.com/browse/OSH-737

In this version, the severity-threshold argument is introduced and enabled by default to high and the results are parsed with csgrep to be uploaded with the fingerprint. Also, results are filtered using the newly introduced csfilter-kfp and KFP_GIT_URL variable and known false positives won't be shown.
  • Loading branch information
jperezdealgaba committed Sep 19, 2024
1 parent d42191e commit e85b7e6
Show file tree
Hide file tree
Showing 3 changed files with 251 additions and 0 deletions.
15 changes: 15 additions & 0 deletions task/sast-snyk-check/0.3/MIGRATION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Migration from 0.2 to 0.3

Version 0.3:

- The `--severity-threshold` argument has been introduced and enabled by default with "high" value. Only high or superior vulnerabilities will be shown. Possible values for this argument are: `low`, `medium` and `high`.
- The results are parsed using `csgrep` and they are uploaded as results with a generated fingerprint.
- There are no default arguments as "--all-projects --exclude=test*,vendor,deps" are ignored by Snyk Code
- The results are uploaded as SARIF files to the registry
- SARIF produced by Snyk Code is not included in the CI log.
- The findings are filtered using the known-false-positives repository (https://gitlab.cee.redhat.com/osh/known-false-positives/)
- The KFP_GIT_URL parameter has been introduced to indicate the repository to filter false positives. If this variable is left empty, the results won't be filtered. At the same time, we can store all excluded findings in a file using the RECORD_EXCLUDED parameter and specify a NVR with the PROJECT_NVR

## Action from users

Renovate bot PR will be created with warning icon for a sast-snyk-check which is expected, no action from users are required.
39 changes: 39 additions & 0 deletions task/sast-snyk-check/0.3/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# sast-snyk-check task

## Description:

The sast-snyk-check task uses Snyk Code tool to perform Static Application Security Testing (SAST) for Snyk, a popular cloud-native application security platform.

Snyk's SAST tool uses a combination of static analysis and machine learning techniques to scan an application's source code for potential security vulnerabilities, including common issues such as SQL injection, cross-site scripting (XSS), and code injection attacks.

> NOTE: This task is executed only if the user provides a Snyk token stored in a secret in their namespace. The name of the secret then needs to be supplied in the `snyk-secret` pipeline parameter.
## Params:

| name | description |
|--------------------------|--------------------------------------------------------------------------------------------------------------|
| SNYK_SECRET | Name of secret which contains Snyk token. |
| ARGS | Append arguments. |
| SEVERITY_THRESHOLD | Only vulnerabilities of the specified level or higher are reported (Possible values are low, medium or high) |
| KFP_GIT_URL | Link to the known-false-positives repository. If left blank, results won't be filtered |
| PROJECT_NVR | Name-Version-Release (NVR) of the scanned project, used to find path exclusions (it is optional) |
| RECORD_EXCLUDED | File to store all excluded findings to (it is optional) |

## How to obtain a snyk-token and enable snyk task on the pipeline:

Follow the steps given [here](https://redhat-appstudio.github.io/docs.appstudio.io/Documentation/main/how-to-guides/testing_applications/enable_snyk_check_for_a_product/)

## Results:

| name | description |
|---------------|----------------------------|
| TEST_OUTPUT | Tekton task test output. |

## Source repository for image:

https://github.com/konflux-ci/konflux-test

## Additional links:

* https://snyk.io/product/snyk-code/
* https://snyk.io/
197 changes: 197 additions & 0 deletions task/sast-snyk-check/0.3/sast-snyk-check.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
apiVersion: tekton.dev/v1
kind: Task
metadata:
labels:
app.kubernetes.io/version: "0.3"
annotations:
tekton.dev/pipelines.minVersion: "0.12.1"
tekton.dev/tags: "konflux"
name: sast-snyk-check
spec:
description: >-
Scans source code for security vulnerabilities, including common issues such as SQL injection, cross-site scripting (XSS), and code injection attacks using Snyk Code, a Static Application Security Testing (SAST) tool.
results:
- description: Tekton task test output.
name: TEST_OUTPUT
params:
- name: SNYK_SECRET
description: Name of secret which contains Snyk token.
default: snyk-secret
- name: ARGS
type: string
description: Append arguments.
default: ""
- description: Image URL.
name: image-url
type: string
# In a future 0.4 version of the task, drop the default to make this required
default: ""
- description: Image digest to report findings for.
name: image-digest
type: string
# In a future 0.4 version of the task, drop the default to make this required
default: ""
- name: SEVERITY_THRESHOLD
type: string
description: Report only vulnerabilities at the specified level or higher (Options are low, medium or high).
default: "high"
- name: KFP_GIT_URL
type: string
description: URL from repository to download known false positives files
default: "https://gitlab.cee.redhat.com/osh/known-false-positives.git"
- name: PROJECT_NVR
type: string
description: Name-Version-Release (NVR) of the scanned project, used to find path exclusions (it is optional)
default: ""
- name: RECORD_EXCLUDED
type: string
description: File to store all excluded findings to (it is optional)
default: ""

volumes:
- name: snyk-secret
secret:
secretName: $(params.SNYK_SECRET)
optional: true
steps:
- name: sast-snyk-check
image: quay.io/redhat-appstudio/konflux-test:v1.4.7@sha256:cf6808a3bd605630a5d9f20595ff7c43f8645c00381219d32f5a11e88fe37072
# per https://kubernetes.io/docs/concepts/containers/images/#imagepullpolicy-defaulting
# the cluster will set imagePullPolicy to IfNotPresent
workingDir: $(workspaces.workspace.path)/hacbs/$(context.task.name)
volumeMounts:
- name: snyk-secret
mountPath: "/etc/secrets"
readOnly: true
env:
- name: SNYK_SECRET
value: $(params.SNYK_SECRET)
- name: ARGS
value: $(params.ARGS)
- name: SEVERITY_THRESHOLD
value: $(params.SEVERITY_THRESHOLD)
- name: KFP_GIT_URL
value: $(params.KFP_GIT_URL)
- name: PROJECT_NVR
value: $(params.PROJECT_NVR)
- name: RECORD_EXCLUDED
value: $(params.RECORD_EXCLUDED)
script: |
#!/usr/bin/env bash
set -euo pipefail
. /utils.sh
trap 'handle_error $(results.TEST_OUTPUT.path)' EXIT
# Installation of Red Hat certificates for cloning Red Hat internal repositories
curl -sS https://certs.corp.redhat.com/certs/2015-IT-Root-CA.pem > /etc/pki/ca-trust/source/anchors/2015-RH-IT-Root-CA.crt
curl -sS https://certs.corp.redhat.com/certs/2022-IT-Root-CA.pem > /etc/pki/ca-trust/source/anchors/2022-IT-Root-CA.pem
update-ca-trust
SNYK_TOKEN_PATH="/etc/secrets/snyk_token"
if [ -f "${SNYK_TOKEN_PATH}" ] && [ -s "${SNYK_TOKEN_PATH}" ]; then
# SNYK token is provided
SNYK_TOKEN="$(cat ${SNYK_TOKEN_PATH})"
export SNYK_TOKEN
else
to_enable_snyk='[here](https://redhat-appstudio.github.io/docs.appstudio.io/Documentation/main/how-to-guides/testing_applications/enable_snyk_check_for_a_product/)'
note="Task $(context.task.name) skipped: If you wish to use the Snyk code SAST task, please create a secret name snyk-secret with the key "snyk_token" containing the Snyk token by following the steps given ${to_enable_snyk}"
TEST_OUTPUT=$(make_result_json -r SKIPPED -t "$note")
echo "${TEST_OUTPUT}" | tee "$(results.TEST_OUTPUT.path)"
exit 0
fi
SNYK_EXIT_CODE=0
SOURCE_CODE_DIR=$(workspaces.workspace.path)
# shellcheck disable=SC2086
# We do want to expand ARGS (it can be multiple CLI flags, not just one)
snyk code test $ARGS --severity-threshold=$SEVERITY_THRESHOLD "$SOURCE_CODE_DIR" --max-depth=1 --sarif-file-output=sast_snyk_check_out.json 1>&2>> stdout.txt || SNYK_EXIT_CODE=$?
test_not_skipped=0
SKIP_MSG="We found 0 supported files"
grep -q "$SKIP_MSG" stdout.txt || test_not_skipped=$?
# In order to generate csdiff/v1, we need to add the whole path of the source code as Snyk only provides an URI to embed the context
csgrep --mode=json --prepend-path-prefix="$SOURCE_CODE_DIR"/ sast_snyk_check_out.json | csgrep --mode=json --embed-context 3 | csgrep --mode=json --strip-path-prefix="$SOURCE_CODE_DIR"/source/ > sast_snyk_check_out_all_findings.json
echo "Results:"
(set -x; csgrep --mode=evtstat sast_snyk_check_out_all_findings.json)
# We check if the KFP_GIT_URL variable is set to apply the filters or not
if [[ -z "${KFP_GIT_URL}" ]]; then
echo "KFP_GIT_URL variable not defined. False positives won't be filtered"
mv sast_snyk_check_out_all_findings.json filtered_sast_snyk_check_out.json
else
echo "Filtering false positives in results files using csfilter-kfp..."
CMD=(
csfilter-kfp
--verbose
--kfp-git-url="${KFP_GIT_URL}"
)
if [[ -n "${PROJECT_NVR}" ]]; then
CMD+=(--project-nvr="${PROJECT_NVR}")
fi
if [[ -n "${RECORD_EXCLUDED}" ]]; then
CMD+=(--record-excluded="${RECORD_EXCLUDED}")
fi
"${CMD[@]}" sast_snyk_check_out_all_findings.json > filtered_sast_snyk_check_out.json
status=$?
if [ "$status" -ne 0 ]; then
echo "Error: failed to filter known false positives" >&2
return 1
else
echo "Message: Succeed to filter known false positives" >&2
SCAN_RESULT="filtered_sast_unicode_check_out.json"
fi
echo "Results after filtering:"
(set -x; csgrep --mode=evtstat filtered_sast_snyk_check_out.json)
fi
csgrep --mode=sarif filtered_sast_snyk_check_out.json > sast_snyk_check_out.sarif
if [[ "$SNYK_EXIT_CODE" -eq 0 ]] || [[ "$SNYK_EXIT_CODE" -eq 1 ]]; then
TEST_OUTPUT=
parse_test_output '$(context.task.name)' sarif sast_snyk_check_out.sarif || true
# When the test is skipped, the "SNYK_EXIT_CODE" is 3 and it can also be 3 in some other situation
elif [[ "$test_not_skipped" -eq 0 ]]; then
note="Task $(context.task.name) success: Snyk code test found zero supported files."
ERROR_OUTPUT=$(make_result_json -r SUCCESS -t "$note")
else
note="Task $(context.task.name) failed: For details, check Tekton task log."
ERROR_OUTPUT=$(make_result_json -r ERROR -t "$note")
fi
echo "${TEST_OUTPUT:-${ERROR_OUTPUT}}" | tee $(results.TEST_OUTPUT.path)
- name: upload
image: quay.io/konflux-ci/oras:latest@sha256:f4b891ee3038a5f13cd92ff4f473faad5601c2434d1c6b9bccdfc134d9d5f820
workingDir: $(workspaces.workspace.path)/hacbs/$(context.task.name)
env:
- name: IMAGE_URL
value: $(params.image-url)
- name: IMAGE_DIGEST
value: $(params.image-digest)
script: |
#!/usr/bin/env bash
UPLOAD_FILE=sast_snyk_check_out.sarif
MEDIA_TYPE=application/sarif+json
if [ -z "${IMAGE_URL}" ] || [ -z "${IMAGE_DIGEST}" ]; then
echo 'No image-url or image-digest param provided. Skipping upload.'
exit 0;
fi
if [ ! -f "${UPLOAD_FILE}" ]; then
echo "No ${UPLOAD_FILE} exists. Skipping upload."
exit 0;
fi
echo "Selecting auth"
select-oci-auth $IMAGE_URL > $HOME/auth.json
echo "Attaching to ${IMAGE_URL}"
oras attach --no-tty --registry-config "$HOME/auth.json" --artifact-type "${MEDIA_TYPE}" "${IMAGE_URL}" "${UPLOAD_FILE}:${MEDIA_TYPE}"
workspaces:
- name: workspace

0 comments on commit e85b7e6

Please sign in to comment.