diff --git a/task/sast-shell-check/0.1/README.md b/task/sast-shell-check/0.1/README.md new file mode 100644 index 0000000000..8c18d94f0d --- /dev/null +++ b/task/sast-shell-check/0.1/README.md @@ -0,0 +1,32 @@ +# sast-shell-check task + +## Description: + +The sast-shell-check task uses [shellcheck](https://www.shellcheck.net/) tool to perform Static Application Security Testing (SAST), a popular cloud-native application security platform. + +ShellCheck is a static analysis tool, gives warnings and suggestions for bash/sh shell scripts. + +## Params: + +| Name | Description | Default Value | Required | +|-------------------|----------------------------------------------------------------------------------------------|---------------|----------| +| KFP_GIT_URL | Git repository to download known false positives files from. | "" | No | +| PROJECT_NVR | Name-Version-Release (NVR) of the scanned project, used to find path exclusions (optional). | "" | No | +| RECORD_EXCLUDED | Whether to record the excluded findings (defaults to false).
If `true`, the the excluded findings will be stored in `excluded-findings.json`. | "false" | No | +| CSGREP_EVENT_FILTER | ShellCheck event filter for csgrep. | "\[SC(1020|1035|1054|1066|1068|1073|1080|1083|1099|1113|1115|1127|1128|1143|2043|2050|2055|2057|2066|2069|2071|2077|2078|2091|2092|2157|2171|2193|2194|2195|2215|2216|2218|2224|2225|2242|2256|2258|2261)\]$" | No | + +## Results: + +| name | description | +|-----------------------|--------------------------| +| TEST_OUTPUT | Tekton task test output. | + +## Source repository for image: + +https://github.com/konflux-ci/konflux-test + +## Additional links: + +* https://www.shellcheck.net/wiki/Home +* https://github.com/koalaman/shellcheck +* https://github.com/csutils/csmock diff --git a/task/sast-shell-check/0.1/sast-shell-check.yaml b/task/sast-shell-check/0.1/sast-shell-check.yaml new file mode 100644 index 0000000000..c24e0a784e --- /dev/null +++ b/task/sast-shell-check/0.1/sast-shell-check.yaml @@ -0,0 +1,175 @@ +apiVersion: tekton.dev/v1 +kind: Task +metadata: + labels: + app.kubernetes.io/version: "0.1" + annotations: + tekton.dev/pipelines.minVersion: "0.12.1" + tekton.dev/tags: "konflux" + name: sast-shell-check +spec: + description: >- + ShellCheck is a static analysis tool, gives warnings and suggestions for bash/sh shell scripts. + results: + - description: Tekton task test output. + name: TEST_OUTPUT + params: + - name: image-url + description: Image URL. + type: string + default: "" + - name: image-digest + description: Image digest to report findings for. + type: string + default: "" + - name: KFP_GIT_URL + description: git repository to download known false positives files from + type: string + default: "" + - name: PROJECT_NVR + description: Name-Version-Release (NVR) of the scanned project, used to find path exclusions + type: string + default: "" + - name: RECORD_EXCLUDED + type: string + description: | + Whether to record the excluded findings (default to false). + If `true`, the excluded findings will be stored in `excluded-findings.json`. + default: "false" + - name: CSGREP_EVENT_FILTER + description: ShellCheck event filter for csgrep. + type: string + default: '\[SC(1020|1035|1054|1066|1068|1073|1080|1083|1099|1113|1115|1127|1128|1143|2043|2050|2055|2057|2066|2069|2071|2077|2078|2091|2092|2157|2171|2193|2194|2195|2215|2216|2218|2224|2225|2242|2256|2258|2261)\]$' + steps: + - name: sast-shell-check + image: quay.io/redhat-appstudio/konflux-test:v1.4.5@sha256:801a105ba0f9c7f58f5ba5cde1a3b4404009fbebb1028779ca2c5de211e94940 + # 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) + env: + - name: KFP_GIT_URL + value: $(params.KFP_GIT_URL) + - name: PROJECT_NVR + value: $(params.PROJECT_NVR) + - name: RECORD_EXCLUDED + value: $(params.RECORD_EXCLUDED) + - name: CSGREP_EVENT_FILTER + value: $(params.CSGREP_EVENT_FILTER) + script: | + #!/usr/bin/env bash + set -x + . /utils.sh + + # install dependencies + microdnf install -y csdiff + + # FIXME: once https://github.com/konflux-ci/konflux-test/pull/303 is available in latest image, + # work around below is no longer needed + microdnf install -y ShellCheck + microdnf download csmock-plugin-shellcheck && rpm -ivh --nodeps ./csmock-plugin-shellcheck-*.rpm && rm -f ./csmock-plugin-shellcheck-*.rpm + + OUTPUT_FILE="shellcheck-results.json" + SOURCE_CODE_DIR=$(workspaces.workspace.path)/source + + # generate all shellcheck result JSON files to $SC_RESULTS_DIR, which defaults to ./shellcheck-results/ + /usr/share/csmock/scripts/run-shellcheck.sh "$SOURCE_CODE_DIR" + + CSGREP_OPTS=( + --mode=json + --strip-path-prefix="$SOURCE_CODE_DIR"/ + --event='error|warning' + --remove-duplicates + --embed-context=3 + ) + csgrep "${CSGREP_OPTS[@]}" ./shellcheck-results/*.json > "$OUTPUT_FILE" + + if [ $? -ne 0 ]; then + echo "Error occurred while running 'run-shellcheck.sh'" + note="Task $(context.task.name) failed: For details, check Tekton task log." + ERROR_OUTPUT=$(make_result_json -r ERROR -t "$note") + echo "${ERROR_OUTPUT}" | tee "$(results.TEST_OUTPUT.path)" + exit 1 + fi + + # Filter known false positives if KFP_GIT_URL is set + if [ -n "${KFP_GIT_URL}" ]; then + echo "Filtering known false positives using ${KFP_GIT_URL}" + + # build initial csfilter-kfp command + csfilter_cmd="csfilter-kfp --verbose --kfp-git-url=${KFP_GIT_URL}" + + # Append --project-nvr option if PROJECT_NVR is set + if [ -n "${PROJECT_NVR}" ]; then + csfilter_cmd+=" --project-nvr=${PROJECT_NVR}" + fi + + if [[ "${RECORD_EXCLUDED}" == "true" ]]; then + csfilter_cmd+=" --record-excluded=excluded-findings.json" + fi + + # Execute the command and capture any errors + if ! "${csfilter_cmd[@]}" "$OUTPUT_FILE" > "${OUTPUT_FILE}.filtered" 2> "${OUTPUT_FILE}.error"; then + echo "Error occurred while filtering known false positives:" + cat "${OUTPUT_FILE}.error" + note="Task $(context.task.name) failed: For details, check Tekton task log." + ERROR_OUTPUT=$(make_result_json -r ERROR -t "$note") + echo "${ERROR_OUTPUT}" | tee "$(results.TEST_OUTPUT.path)" + rm -f "${OUTPUT_FILE}.filtered" "${OUTPUT_FILE}.error" + exit 1 + else + mv "${OUTPUT_FILE}.filtered" "$OUTPUT_FILE" + echo "Filtered results saved back to $OUTPUT_FILE" + fi + else + echo "KFP_GIT_URL is not set. Skipping false positive filtering." + fi + + csgrep --mode=json --event "$CSGREP_EVENT_FILTER" "$OUTPUT_FILE" + + echo "ShellCheck results have been saved to $OUTPUT_FILE" + + csgrep --mode=evtstat "$OUTPUT_FILE" + csgrep --mode=sarif "$OUTPUT_FILE" > shellcheck-results.sarif + + note="Task $(context.task.name) completed successfully." + TEST_OUTPUT=$(make_result_json -r SUCCESS -t "$note") + echo "${TEST_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 + set -e + + if [ -z "${IMAGE_URL}" ] || [ -z "${IMAGE_DIGEST}" ]; then + echo 'No image-url or image-digest param provided. Skipping upload.' + exit 0 + fi + + UPLOAD_FILES="shellcheck-results.sarif excluded-findings.json" + + for UPLOAD_FILE in ${UPLOAD_FILES}; do + if [ ! -f "${UPLOAD_FILE}" ]; then + echo "No ${UPLOAD_FILE} exists. Skipping upload." + continue + fi + + # Determine the media type based on the file extension + if [[ "${UPLOAD_FILE}" == *.json ]]; then + MEDIA_TYPE="application/json" + else + MEDIA_TYPE="application/sarif+json" + 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}" + done + workspaces: + - name: workspace diff --git a/task/sast-shell-check/OWNERS b/task/sast-shell-check/OWNERS new file mode 100644 index 0000000000..27203edec2 --- /dev/null +++ b/task/sast-shell-check/OWNERS @@ -0,0 +1,5 @@ +# See the OWNERS docs: https://go.k8s.io/owners +approvers: + - integration-team +reviewers: + - integration-team