forked from konflux-ci/build-definitions
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
use kustomize to build sast-coverity-check
... from the build-container task
- Loading branch information
Showing
3 changed files
with
1,103 additions
and
247 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
apiVersion: kustomize.config.k8s.io/v1beta1 | ||
Check failure on line 1 in task/sast-coverity-check/0.2/kustomization.yaml GitHub Actions / Check Trusted Artifact variants
|
||
kind: Kustomization | ||
|
||
resources: | ||
- ../../buildah/0.2 | ||
|
||
patches: | ||
- path: patch.yaml | ||
target: | ||
kind: Task |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,360 @@ | ||
# Task name | ||
- op: replace | ||
path: /metadata/name | ||
value: sast-coverity-check | ||
|
||
# Task description | ||
- op: replace | ||
path: /spec/description | ||
value: |- | ||
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. | ||
# Replace task results | ||
- op: replace | ||
path: /spec/results | ||
value: | ||
- description: Short summary of SAST scan results. | ||
name: SCAN_OUTPUT | ||
- description: Tekton task test output. | ||
name: TEST_OUTPUT | ||
- description: SAST scanning results artifact URL. | ||
name: SAST_RESULT_URL | ||
|
||
################### | ||
# Task steps | ||
################### | ||
|
||
# Remove all buildah task steps except build | ||
- op: remove | ||
path: /spec/steps/5 # upload-sbom | ||
- op: remove | ||
path: /spec/steps/4 # inject-sbom-and-push | ||
- op: remove | ||
path: /spec/steps/3 # prepare-sboms | ||
- op: remove | ||
path: /spec/steps/2 # analyse-dependencies-java-sbom | ||
- op: remove | ||
path: /spec/steps/1 # sbom-syft-generate | ||
|
||
# Tune the build step (the only one left). | ||
|
||
# Change build step image | ||
- op: replace | ||
path: /spec/steps/0/image | ||
# New image shoould be based on quay.io/konflux-ci/buildah-task:latest or have all the tooling that the original image has. | ||
value: quay.io/redhat-user-workloads/sast-tenant/sast-scanner/coverity@sha256:fdbe6b5c8d335c1f6cba2950c411ade10a3e4ab9530aae983069ced2b60470d8 | ||
|
||
# Change build step resources | ||
- op: replace | ||
path: /spec/steps/0/computeResources/limits/cpu | ||
value: 4 | ||
- op: replace | ||
path: /spec/steps/0/computeResources/limits/memory | ||
value: 4Gi | ||
- op: replace | ||
path: /spec/steps/0/computeResources/requests/cpu | ||
value: 2 | ||
- op: replace | ||
path: /spec/steps/0/computeResources/requests/memory | ||
value: 2Gi | ||
|
||
# Additional volumes | ||
- op: add | ||
path: /spec/volumes/- | ||
value: | ||
name: cov-license | ||
secret: | ||
secretName: $(params.COV_LICENSE) | ||
optional: false | ||
- op: add | ||
path: /spec/steps/0/env/- | ||
value: | ||
name: ADDITIONAL_VOLUME_MOUNTS | ||
value: |- | ||
/opt:/opt | ||
/shared:/shared | ||
# Additional parameters | ||
- op: add | ||
path: /spec/params/- | ||
value: | ||
name: IMAGE_URL | ||
type: string | ||
- op: add | ||
path: /spec/params/- | ||
value: | ||
name: COV_LICENSE | ||
type: string | ||
description: Name of secret which contains the Coverity license | ||
default: "cov-license" | ||
- op: add | ||
path: /spec/params/- | ||
value: | ||
name: PROJECT_NAME | ||
type: string | ||
default: "" | ||
- op: add | ||
path: /spec/params/- | ||
value: | ||
name: RECORD_EXCLUDED | ||
type: string | ||
default: "false" | ||
- op: add | ||
path: /spec/params/- | ||
value: | ||
description: Arguments to be appended to the coverity capture command | ||
name: COV_CAPTURE_ARGS | ||
type: string | ||
default: "" | ||
- op: add | ||
path: /spec/params/- | ||
value: | ||
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" | ||
- op: add | ||
path: /spec/params/- | ||
value: | ||
name: IMP_FINDINGS_ONLY | ||
type: string | ||
description: Report only important findings. Default is true. To report all findings, specify "false" | ||
default: "true" | ||
- op: add | ||
path: /spec/params/- | ||
value: | ||
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: "" | ||
|
||
# Add prepare and postprocess steps | ||
|
||
# Prepare step | ||
- op: add | ||
path: /spec/steps/0 | ||
value: | ||
name: prepare | ||
image: quay.io/redhat-user-workloads/sast-tenant/sast-scanner/coverity@sha256:fdbe6b5c8d335c1f6cba2950c411ade10a3e4ab9530aae983069ced2b60470d8 | ||
computeResources: | ||
limits: | ||
memory: 1Gi | ||
cpu: '1' | ||
requests: | ||
memory: 0.5Gi | ||
cpu: '0.5' | ||
workingDir: $(workspaces.source.path) | ||
env: | ||
- name: DOCKERFILE | ||
value: $(params.DOCKERFILE) | ||
script: | | ||
set -x | ||
# Dockerfile discovery logic is copied from buildah task | ||
SOURCE_CODE_DIR=source | ||
if [ -e "$SOURCE_CODE_DIR/$CONTEXT/$DOCKERFILE" ]; then | ||
dockerfile_path="$(pwd)/$SOURCE_CODE_DIR/$CONTEXT/$DOCKERFILE" | ||
elif [ -e "$SOURCE_CODE_DIR/$DOCKERFILE" ]; then | ||
dockerfile_path="$(pwd)/$SOURCE_CODE_DIR/$DOCKERFILE" | ||
elif echo "$DOCKERFILE" | grep -q "^https\?://"; then | ||
echo "Fetch Dockerfile from $DOCKERFILE" | ||
dockerfile_path=$(mktemp --suffix=-Dockerfile) | ||
http_code=$(curl -s -L -w "%{http_code}" --output "$dockerfile_path" "$DOCKERFILE") | ||
if [ "$http_code" != 200 ]; then | ||
echo "No Dockerfile is fetched. Server responds $http_code" | ||
exit 1 | ||
fi | ||
http_code=$(curl -s -L -w "%{http_code}" --output "$dockerfile_path.dockerignore.tmp" "$DOCKERFILE.dockerignore") | ||
if [ "$http_code" = 200 ]; then | ||
echo "Fetched .dockerignore from $DOCKERFILE.dockerignore" | ||
mv "$dockerfile_path.dockerignore.tmp" "$SOURCE_CODE_DIR/$CONTEXT/.dockerignore" | ||
fi | ||
else | ||
echo "Cannot find Dockerfile $DOCKERFILE" | ||
exit 1 | ||
fi | ||
# create a wrapper script to instrument RUN lines | ||
tee /shared/cmd-wrap.sh << EOF | ||
#!/bin/bash -x | ||
id >&2 | ||
proj_dir=\$(pwd) | ||
[ / = "\$proj_dir" ] && proj_dir=\$HOME | ||
[ -z "\$proj_dir" ] && proj_dir=\$(echo ~) | ||
# TODO: propagate COV_CAPTURE_ARGS | ||
env COV_HOST=konflux /opt/coverity/bin/coverity --ticker-mode=no-spin capture --dir=/shared/idir --project-dir="\$proj_dir" -- "\$@" | ||
EC=\$? | ||
# make sure that idir will be writable by other users in subsequent RUN directives | ||
chmod -R a+rwX /shared/idir | ||
exit \$EC | ||
EOF | ||
chmod 0755 /shared/cmd-wrap.sh | ||
# instrument all RUN lines in Dockerfile | ||
cstrans-df-run --verbose /shared/cmd-wrap.sh < "$dockerfile_path" > /shared/Containerfile | ||
# Make the buildah task use the instrumented Dockerfile | ||
- op: replace | ||
path: /spec/steps/1/env/1/value # steps -> build -> env -> DOCKERFILE | ||
value: /shared/Containerfile | ||
|
||
# Postprocess step | ||
- op: add | ||
path: /spec/steps/2 | ||
value: | ||
name: postprocess | ||
image: quay.io/redhat-user-workloads/sast-tenant/sast-scanner/coverity@sha256:fdbe6b5c8d335c1f6cba2950c411ade10a3e4ab9530aae983069ced2b60470d8 | ||
computeResources: | ||
limits: | ||
memory: 4Gi | ||
cpu: 4 | ||
requests: | ||
memory: 2Gi | ||
cpu: 2 | ||
volumeMounts: | ||
- name: cov-license | ||
mountPath: "/etc/secrets/cov" | ||
readOnly: true | ||
- name: trusted-ca | ||
mountPath: /mnt/trusted-ca | ||
readOnly: true | ||
env: | ||
- name: IMAGE_URL | ||
value: $(params.IMAGE_URL) | ||
- name: COV_LICENSE | ||
value: $(params.COV_LICENSE) | ||
- 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: 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'] | ||
|
||
workingDir: $(workspaces.source.path) | ||
script: | | ||
set -exo pipefail | ||
# shellcheck source=/dev/null | ||
. /usr/local/share/konflux-test/utils.sh | ||
trap 'handle_error $(results.TEST_OUTPUT.path)' EXIT | ||
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=/shared/idir | ||
COVERITY_RESULTS_FILE=$(workspaces.source.path)/coverity-results.json | ||
COV_LICENSE_PATH=/etc/secrets/cov/cov-license | ||
SOURCE_CODE_DIR=$(workspaces.source.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 | ||
if ! [ -d "$COVERITY_DIR" ]; then | ||
# fallback to buildless scan if $COVERITY_DIR does not exist | ||
echo -e 'capture:\n build-command-inference: false' > "$SOURCE_CODE_DIR"/coverity.yml | ||
# shellcheck disable=SC2086 | ||
env COV_HOST=konflux /opt/coverity/bin/coverity capture $COV_CAPTURE_ARGS --project-dir "$SOURCE_CODE_DIR" --dir "$COVERITY_DIR" || : | ||
fi | ||
# analyze the intermediate code captured in $COVERITY_DIR | ||
# shellcheck disable=SC2086 | ||
/opt/coverity/bin/cov-analyze $COV_ANALYZE_ARGS --dir="$COVERITY_DIR" | ||
# export scan results | ||
/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" \ | ||
> coverity-results-raw.json | ||
csgrep --mode=evtstat coverity-results-raw.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 coverity-results-raw.json coverity-results.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[@]}" coverity-results-raw.json > coverity-results.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 coverity-results.json) | ||
fi | ||
csgrep --mode=sarif coverity-results.json > "$(workspaces.source.path)"/coverity-results.sarif | ||
if [[ -z "$(csgrep --mode=evtstat coverity-results.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.source.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)" | ||
# ===================================================================================== | ||
sast_dir="/shared/sast-results" | ||
ls -l "$sast_dir" | ||
# read the collected SAST scanning results | ||
UPLOAD_FILE=gcc-analyzer.sarif | ||
csgrep --mode=sarif --event=^warning --remove-duplicates --file-glob "${sast_dir}/*" \ | ||
| tee "${UPLOAD_FILE}" | csgrep | ||
# upload scan results | ||
MEDIA_TYPE=application/sarif+json | ||
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}" |
Oops, something went wrong.