Skip to content

Commit

Permalink
sast-coverity-check: do not require IMAGE_DIGEST parameter
Browse files Browse the repository at this point in the history
... which is not used for anything

Related: konflux-ci#1653
  • Loading branch information
kdudka committed Dec 12, 2024
1 parent 7ca55eb commit 327d455
Show file tree
Hide file tree
Showing 3 changed files with 323 additions and 3 deletions.
4 changes: 1 addition & 3 deletions pipelines/template-build/template-build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -250,10 +250,8 @@ spec:
- coverity-availability-check
taskRef:
name: sast-coverity-check
version: "0.1"
version: "0.2"
params:
- name: image-digest
value: $(tasks.build-image-index.results.IMAGE_DIGEST)
- name: image-url
value: $(tasks.build-image-index.results.IMAGE_URL)
workspaces:
Expand Down
46 changes: 46 additions & 0 deletions task/sast-coverity-check/0.2/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# sast-coverity-check task

## Description:

The sast-coverity-check task uses Coverity tool to perform Static Application Security Testing (SAST). In this task, we use the buildless mode, where Coverity has the ability to capture source code without the need of building the product.

The documentation for this mode can be found here: https://sig-product-docs.synopsys.com/bundle/coverity-docs/page/commands/topics/coverity_capture.html

The characteristics of these tasks are:

- Perform buildless scanning with Coverity
- The whole source code is scanned (by scanning `$(workspaces.source.path)` )
- Only important findings are reported by default. A parameter ( `IMP_FINDINGS_ONLY`) is provided to override this configuration.
- The csdiff/v1 SARIF fingerprints are provided for all findings
- A parameter ( `KFP_GIT_URL`) is provided to remove false positives providing a known false positives repository. By default, no repository is provided.

> NOTE: This task is executed only if there is a Coverity license set up in the environment. Please check coverity-availability-check task for more information.
## Params:

| name | description | default value | required |
|---------------------------|---------------------------------------------------------------------------------------------------------------------------------------|---------------------------|----------|
| COV_CAPTURE_ARGS | Append arguments to the Coverity Capture CLI command | "" | no |
| COV_ANALYZE_ARGS | Append arguments to the cov-analyze CLI command | "" | no |
| COV_LICENSE | Name of secret which contains the Coverity license | cov-license | no |
| AUTH_TOKEN_COVERITY_IMAGE | Name of secret which contains the authentication token for pulling the Coverity image | auth-token-coverity-image | no |
| IMP_FINDINGS_ONLY | Report only important findings. Default is true. To report all findings, specify "false" | true | no |
| KFP_GIT_URL | Known False Positives git URL, optionally taking a revision delimited by #; If empty, filtering of known false positives is disabled. | "" | no |
| PROJECT_NAME | Name of the scanned project, used to find path exclusions. By default, the Konflux component name will be used. | "" | no |
| RECORD_EXCLUDED | If set to `true`, excluded findings will be written to a file named `excluded-findings.json` for auditing purposes. | false | no |

## Results:

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

## Source repository for image:

// TODO: Add reference to private repo for the container image once the task is migrated to repo


## Additional links:

* https://sig-product-docs.synopsys.com/bundle/coverity-docs/page/commands/topics/coverity_capture.html
* https://sig-product-docs.synopsys.com/bundle/coverity-docs/page/cli/topics/options_reference.html
276 changes: 276 additions & 0 deletions task/sast-coverity-check/0.2/sast-coverity-check.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,276 @@
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-coverity-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 Coverity. At the moment, this task only uses the buildless mode, which does not build the project in order to analyze it.
results:
- description: Tekton task test output.
name: TEST_OUTPUT
params:
- description: Image URL.
name: image-url
type: string
- name: caTrustConfigMapName
type: string
description: The name of the ConfigMap to read CA bundle data from.
default: trusted-ca
- name: caTrustConfigMapKey
type: string
description: The name of the key in the ConfigMap that contains the CA bundle data.
default: ca-bundle.crt
- description: Arguments to be appended to the coverity capture command
name: COV_CAPTURE_ARGS
type: string
default: ""
- description: Arguments to be appended to the cov-analyze command
name: COV_ANALYZE_ARGS
type: string
default: "--enable HARDCODED_CREDENTIALS --security --concurrency --spotbugs-max-mem=4096"
- name: COV_LICENSE
description: Name of secret which contains the Coverity license
default: cov-license
- name: AUTH_TOKEN_COVERITY_IMAGE
description: Name of secret which contains the authentication token for pulling the Coverity image.
default: "auth-token-coverity-image"
- name: IMP_FINDINGS_ONLY
type: string
description: Report only important findings. Default is true. To report all findings, specify "false"
default: "true"
- name: KFP_GIT_URL
type: string
description: URL from repository to download known false positives files
# FIXME: Red Hat internal projects will default to https://gitlab.cee.redhat.com/osh/known-false-positives.git when KONFLUX-4530 is resolved
default: ""
- name: PROJECT_NAME
description: Name of the scanned project, used to find path exclusions.
By default, the Konflux component name will be used.
type: string
default: ""
- name: RECORD_EXCLUDED
type: string
description: Write excluded records in file. Useful for auditing (defaults to false).
default: "false"
volumes:
- name: cov-license
secret:
secretName: $(params.COV_LICENSE)
optional: false
- name: auth-token-coverity-image
secret:
secretName: $(params.AUTH_TOKEN_COVERITY_IMAGE)
optional: false
- name: trusted-ca
configMap:
name: $(params.caTrustConfigMapName)
items:
- key: $(params.caTrustConfigMapKey)
path: ca-bundle.crt
optional: true
steps:
- name: sast-coverity-check
# image: $(steps.secrets-check.results.image)
image: quay.io/redhat-user-workloads/sast-tenant/sast-scanner/coverity@sha256:d8e1266319d310443b183f8c14e083932b70f665fd72a61ff90b30e46b9398f0
computeResources:
requests:
memory: "16Gi"
cpu: "8"
limits:
memory: "32Gi"
cpu: "16"
# 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: cov-license
mountPath: "/etc/secrets/cov"
readOnly: true
- name: trusted-ca
mountPath: /mnt/trusted-ca
readOnly: true
env:
- name: COV_ANALYZE_ARGS
value: $(params.COV_ANALYZE_ARGS)
- name: COV_CAPTURE_ARGS
value: $(params.COV_CAPTURE_ARGS)
- name: KFP_GIT_URL
value: $(params.KFP_GIT_URL)
- name: COV_LICENSE
value: $(params.COV_LICENSE)
- name: IMP_FINDINGS_ONLY
value: $(params.IMP_FINDINGS_ONLY)
- name: PROJECT_NAME
value: $(params.PROJECT_NAME)
- name: RECORD_EXCLUDED
value: $(params.RECORD_EXCLUDED)
- name: COMPONENT_LABEL
valueFrom:
fieldRef:
fieldPath: metadata.labels['appstudio.openshift.io/component']
script: |
#!/usr/bin/env bash
set -eo pipefail
# shellcheck source=/dev/null
. /usr/local/share/konflux-test/utils.sh
trap 'handle_error $(results.TEST_OUTPUT.path)' EXIT
echo 'Starting Coverity buildless scan'
export HOME="/var/tmp/coverity/home"
if [[ -z "${PROJECT_NAME}" ]]; then
PROJECT_NAME=${COMPONENT_LABEL}
fi
echo "The PROJECT_NAME used is: ${PROJECT_NAME}"
COVERITY_DIR=/var/tmp/coverity/idir
COVERITY_RESULTS_FILE=$(workspaces.workspace.path)/coverity-buildless-results.json
COV_LICENSE_PATH=/etc/secrets/cov/cov-license
SOURCE_CODE_DIR=$(workspaces.workspace.path)
# Installing Coverity license
cp "$COV_LICENSE_PATH" /opt/coverity/bin/license.dat
# Installation of Red Hat certificates for cloning Red Hat internal repositories
ca_bundle=/mnt/trusted-ca/ca-bundle.crt
if [ -f "$ca_bundle" ]; then
echo "INFO: Using mounted CA bundle: $ca_bundle"
cp -vf $ca_bundle /etc/pki/ca-trust/source/anchors
update-ca-trust
fi
# Create configuration file for coverity buildless
echo -e 'capture:\n build-command-inference: false' > "$SOURCE_CODE_DIR"/coverity.yml
set +e -x
# Buildless scan
# shellcheck disable=SC2086
env COV_HOST=konflux /opt/coverity/bin/coverity capture $COV_CAPTURE_ARGS --project-dir "$SOURCE_CODE_DIR" --dir "$COVERITY_DIR"
COV_CAPTURE_EXIT_CODE=$?
set -x
if [[ "$COV_CAPTURE_EXIT_CODE" -eq 0 ]]; then
echo "Coverity capture scan finished successfully"
else
echo "Coverity capture command failed with exit code ${COV_CAPTURE_EXIT_CODE}. Exiting..."
note="Task $(context.task.name) failed: For details, check Tekton task log."
ERROR_OUTPUT=$(make_result_json -r ERROR -t "$note")
exit 1
fi
# Analysis phase
set -x
/opt/coverity/bin/cov-manage-emit --dir $COVERITY_DIR reset-host-name
# shellcheck disable=SC2086
/opt/coverity/bin/cov-analyze $COV_ANALYZE_ARGS --dir="$COVERITY_DIR"
COV_ANALYZE_EXIT_CODE=$?
set +x
if [[ "$COV_ANALYZE_EXIT_CODE" -eq 0 ]]; then
echo "cov-analyze scan finished successfully"
else
echo "cov-analyze scan failed with exit code ${COV_ANALYZE_EXIT_CODE}. Exiting..."
note="Task $(context.task.name) failed: For details, check Tekton task log."
ERROR_OUTPUT=$(make_result_json -r ERROR -t "$note")
exit 1
fi
set -e
/opt/coverity/bin/cov-format-errors --dir="$COVERITY_DIR" --json-output-v10 "$COVERITY_RESULTS_FILE"
# We parse the results, embed context, remove duplicates and store them in SARIF format.
IMP_LEVEL=1
if [ "${IMP_FINDINGS_ONLY}" == "false" ]; then
IMP_LEVEL=0
fi
(cd "$SOURCE_CODE_DIR" && csgrep --mode=json --imp-level="$IMP_LEVEL" --remove-duplicates --embed-context=3 "$COVERITY_RESULTS_FILE") \
| csgrep --mode=json --strip-path-prefix="$SOURCE_CODE_DIR"/source/ \
| csgrep --mode=json --strip-path-prefix="$HOME" \
> sast_coverity_buildless_check_all_findings.json
echo "Results:"
(set -x && csgrep --mode=evtstat sast_coverity_buildless_check_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_coverity_buildless_check_all_findings.json filtered_sast_coverity_buildless_check_all_findings.json
else
echo "Filtering false positives in results files using csfilter-kfp..."
CMD=(
csfilter-kfp
--verbose
--kfp-git-url="${KFP_GIT_URL}"
--project-nvr="${PROJECT_NAME}"
)
if [ "${RECORD_EXCLUDED}" == "true" ]; then
CMD+=(--record-excluded="excluded-findings.json")
fi
"${CMD[@]}" sast_coverity_buildless_check_all_findings.json > filtered_sast_coverity_buildless_check_all_findings.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
fi
echo "Results after filtering:"
(set -x $$ csgrep --mode=evtstat filtered_sast_coverity_buildless_check_all_findings.json)
fi
csgrep --mode=sarif filtered_sast_coverity_buildless_check_all_findings.json > "$(workspaces.workspace.path)"/coverity-results.sarif
if [[ -z "$(csgrep --mode=evtstat filtered_sast_coverity_buildless_check_all_findings.json)" ]]; then
note="Task $(context.task.name) success: No finding was detected"
ERROR_OUTPUT=$(make_result_json -r SUCCESS -t "$note")
echo "${ERROR_OUTPUT}" | tee "$(results.TEST_OUTPUT.path)"
else
TEST_OUTPUT=
parse_test_output "$(context.task.name)" sarif "$(workspaces.workspace.path)"/coverity-results.sarif || true
note="Task $(context.task.name) failed: For details, check Tekton task log."
echo "${ERROR_OUTPUT}" | tee "$(results.TEST_OUTPUT.path)"
fi
echo "${TEST_OUTPUT:-${ERROR_OUTPUT}}" | tee "$(results.TEST_OUTPUT.path)"
- name: upload
image: quay.io/konflux-ci/oras:latest@sha256:99737f436051e6d3866eb8a8706463c35abf72c87f05090ff42ff642f6729661
workingDir: $(workspaces.workspace.path)
env:
- name: IMAGE_URL
value: $(params.image-url)
script: |
#!/usr/bin/env bash
if [ -z "${IMAGE_URL}" ]; then
echo 'No image-url param provided. Skipping upload.'
exit 0
fi
UPLOAD_FILES="coverity-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
if [ "${UPLOAD_FILES}" == "excluded-findings.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

0 comments on commit 327d455

Please sign in to comment.