Skip to content

Commit e52f763

Browse files
sast: initial task for Coverity Buildless
Solves: https://issues.redhat.com/browse/OSH-740 Initial version of the Coverity Buildless task. The code will be scanned using coverity buildless mode, then the results are processuing using csgrep and the results are later filtered using csfilter-kfp.
1 parent d42191e commit e52f763

File tree

3 files changed

+275
-0
lines changed

3 files changed

+275
-0
lines changed
+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# sast-coverity-buildless-check task
2+
3+
## Description:
4+
5+
The sast-coverity-buildless-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.
6+
7+
The documentation for this mode can be found here: https://sig-product-docs.synopsys.com/bundle/coverity-docs/page/commands/topics/coverity_capture.html
8+
9+
The characteristics of these tasks are:
10+
11+
- Perform buildless scanning with Coverity
12+
- The whole source code is scanned (by scanning `$(workspaces.source.path)` )
13+
- Only important findings are reported by default. A parameter ( `SEVERITY_THRESHOLD`) is provided to override this configuration.
14+
- The csdiff/v1 SARIF fingerprints are provided for all findings
15+
- [Known false positives](https://gitlab.cee.redhat.com/osh/known-false-positives/) are eliminated by default. A parameter ( `KFP_GIT_URL`) is provided to disable this feature or to configure a custom known false positives repository.
16+
17+
> NOTE: This task is executed only if there is a Coverity license set up in the environment. The Coverity license can be used by Red Hat employees only and it needs to be protected such that external users cannot access the license.
18+
19+
## Params:
20+
21+
| name | description |
22+
|--------------------|---------------------------------------------------------------------------------------------------------------------------------------------|
23+
| COV_CAPTURE_ARGS | Append arguments to the Coverity Capture CLI command |
24+
| COV_ANALYZE_ARGS | Append arguments to the cov-analyze CLI command |
25+
| COV_LICENSE | Name of secret which contains the Coverity license |
26+
| SEVERITY_THRESHOLD | Report only vulnerabilities at the specified level or higher. Default is 1 (Report important findings). To report all findings, specify "0" |
27+
| KFP_GIT_URL | Known False Positives git URL, optionally taking a revision delimited by #; If empty, filtering of known false positives is disabled. |
28+
| PROJECT_NVR | Name-Version-Release (NVR) of the scanned project, used to find path exclusions (it is optional) |
29+
| RECORD_EXCLUDED | File to store all excluded findings to (it is optional) |
30+
31+
## Results:
32+
33+
| name | description |
34+
|-------------------|--------------------------|
35+
| TEST_OUTPUT | Tekton task test output. |
36+
37+
## Source repository for image:
38+
39+
// TODO: Add reference to private repo for the container image once the task is migrated to repo
40+
41+
42+
## Additional links:
43+
44+
* https://sig-product-docs.synopsys.com/bundle/coverity-docs/page/commands/topics/coverity_capture.html
45+
* https://scan.coverity.com/
46+
* https://sig-product-docs.synopsys.com/bundle/coverity-docs/page/cli/topics/options_reference.html
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,224 @@
1+
apiVersion: tekton.dev/v1
2+
kind: Task
3+
metadata:
4+
labels:
5+
app.kubernetes.io/version: "0.1"
6+
annotations:
7+
tekton.dev/pipelines.minVersion: "0.12.1"
8+
tekton.dev/tags: "konflux"
9+
name: sast-coverity-check
10+
spec:
11+
description: >-
12+
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 captureless mode doesn't build the project in order to analyze it.
13+
results:
14+
- description: Tekton task test output.
15+
name: TEST_OUTPUT
16+
params:
17+
- description: Image URL.
18+
name: image-url
19+
type: string
20+
# In a future 0.2 version of the task, drop the default to make this required
21+
default: ""
22+
- description: Image digest to report findings for.
23+
name: image-digest
24+
type: string
25+
# In a future 0.2 version of the task, drop the default to make this required
26+
default: ""
27+
- description: Arguments to be appenden to the coverity capture command
28+
name: COV_CAPTURE_ARGS
29+
type: string
30+
default: ""
31+
- description: Arguments to be appenden to the coverity analyze command
32+
name: COV_ANALYZE_ARGS
33+
type: string
34+
default: "--enable HARDCODED_CREDENTIALS --security --concurrency --spotbugs-max-mem=4096"
35+
- name: COV_LICENSE
36+
description: Name of secret which contains the Coverity license
37+
default: cov-license
38+
- name: SEVERITY_THRESHOLD
39+
type: string
40+
description: Report only vulnerabilities at the specified level or higher. Default is 1 (report only important findings)
41+
default: "1"
42+
- name: KFP_GIT_URL
43+
type: string
44+
description: URL from repository to download known false positives files
45+
default: "https://gitlab.cee.redhat.com/osh/known-false-positives.git"
46+
- name: PROJECT_NVR
47+
type: string
48+
description: Name-Version-Release (NVR) of the scanned project, used to find path exclusions (it is optional)
49+
default: ""
50+
- name: RECORD_EXCLUDED
51+
type: string
52+
description: File to store all excluded findings to (it is optional)
53+
default: ""
54+
volumes:
55+
- name: cov-license
56+
secret:
57+
secretName: $(params.COV_LICENSE)
58+
optional: false
59+
steps:
60+
- name: sast-coverity-check
61+
# TODO: Change image
62+
image: quay.io/redhat-user-workloads/sast-tenant/sast-scanner/coverity@sha256:ce98d4a80a2b77cd1b51fb11d563515226331fdf9521daa1b82da5b0a99e8d22
63+
computeResources:
64+
requests:
65+
memory: "16Gi"
66+
cpu: "8"
67+
limits:
68+
memory: "32Gi"
69+
cpu: "16"
70+
# per https://kubernetes.io/docs/concepts/containers/images/#imagepullpolicy-defaulting
71+
# the cluster will set imagePullPolicy to IfNotPresent
72+
workingDir: $(workspaces.workspace.path)/hacbs/$(context.task.name)
73+
volumeMounts:
74+
- name: cov-license
75+
mountPath: "/etc/secrets"
76+
readOnly: true
77+
env:
78+
- name: COV_ANALYZE_ARGS
79+
value: $(params.COV_ANALYZE_ARGS)
80+
- name: COV_CAPTURE_ARGS
81+
value: $(params.COV_CAPTURE_ARGS)
82+
- name: KFP_GIT_URL
83+
value: $(params.KFP_GIT_URL)
84+
- name: SEVERITY_THRESHOLD
85+
value: $(params.SEVERITY_THRESHOLD)
86+
- name: PROJECT_NVR
87+
value: $(params.PROJECT_NVR)
88+
- name: RECORD_EXCLUDED
89+
value: $(params.RECORD_EXCLUDED)
90+
script: |
91+
#!/usr/bin/env bash
92+
set -eo pipefail
93+
. /usr/local/share/konflux-test/utils.sh
94+
trap 'handle_error $(results.TEST_OUTPUT.path)' EXIT
95+
96+
echo 'Starting Coverity buildless scan'
97+
SOURCE_CODE_DIR=$(workspaces.workspace.path)
98+
COVERITY_DIR=/tmp/cov-scan/cov
99+
COVERITY_RESULTS_FILE=coverity-buildless-results.js
100+
COV_LICENSE_PATH=/etc/secrets/cov-license
101+
# Installing Coverity license
102+
cp /etc/secrets/cov-license /opt/coverity/bin/license.dat
103+
if test -z "$(find /opt -name 'license.dat')"; then
104+
echo "No license file for Coverity was detected. Exiting..."
105+
exit 1
106+
fi
107+
108+
# Installation of Red Hat certificates for cloning Red Hat internal repositories
109+
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
110+
curl -sS https://certs.corp.redhat.com/certs/2022-IT-Root-CA.pem > /etc/pki/ca-trust/source/anchors/2022-IT-Root-CA.pem
111+
update-ca-trust
112+
113+
# Create configuration file for coverity buildless
114+
echo -e 'capture:\n build-command-inference: false' > $SOURCE_CODE_DIR/coverity.yml
115+
116+
# Captureless scan
117+
env COV_HOST=konflux HOME=/tmp/cov-scan/home /opt/coverity/bin/coverity capture $COV_CAPTURE_ARGS --project-dir $SOURCE_CODE_DIR --dir $COVERITY_DIR
118+
COV_CAPTURE_EXIT_CODE=$?
119+
120+
if [[ "$COV_CAPTURE_EXIT_CODE" -eq 0 ]]; then
121+
echo "Coverity capture scan finished successfully"
122+
else
123+
echo "Coverity capture command failed with exit code ${COV_CAPTURE_EXIT_CODE}. Exiting..."
124+
exit 1
125+
fi
126+
127+
# Analysis phase
128+
/opt/coverity/bin/cov-manage-emit --dir $COVERITY_DIR reset-host-name
129+
/opt/coverity/bin/cov-analyze $COV_ANALYZE_ARGS --dir=$COVERITY_DIR
130+
COV_ANALYZE_EXIT_CODE=$?
131+
132+
if [[ "$COV_ANALYZE_EXIT_CODE" -eq 0 ]]; then
133+
echo "Coverity analyze scan finished successfully"
134+
else
135+
echo "Coverity analyze scan failed with exit code ${COV_ANALYZE_EXIT_CODE}. Exiting..."
136+
exit 1
137+
fi
138+
139+
/opt/coverity/bin/cov-format-errors --dir=$COVERITY_DIR --json-output-v10 $COVERITY_RESULTS_FILE
140+
# We parse the results, embed context, remove duplicates and store them in SARIF format.
141+
csgrep --mode=json --imp-level="$SEVERITY_THRESHOLD" --prepend-path-prefix=$SOURCE_CODE_DIR/ $COVERITY_RESULTS_FILE \
142+
| csgrep --mode=json --remove-duplicates --embed-context 3 \
143+
| csgrep --mode=json --strip-path-prefix="$SOURCE_CODE_DIR"/source/ \
144+
| csgrep --mode=json --strip-path-prefix="/tmp/cov-scan/home" \
145+
> sast_coverity_buildless_check_all_findings.json
146+
147+
echo "Results:"
148+
(set -x; csgrep --mode=evtstat sast_coverity_buildless_check_all_findings.json)
149+
150+
# We check if the KFP_GIT_URL variable is set to apply the filters or not
151+
if [[ -z "${KFP_GIT_URL}" ]]; then
152+
mv sast_coverity_buildless_check_all_findings.json filtered_sast_coverity_buildless_check_all_findings.json
153+
else
154+
echo "Filtering false positives in results files using csfilter-kfp..."
155+
CMD=(
156+
csfilter-kfp
157+
--verbose
158+
--kfp-git-url="${KFP_GIT_URL}"
159+
)
160+
if [[ -n "${PROJECT_NVR}" ]]; then
161+
CMD+=(--project-nvr="${PROJECT_NVR}")
162+
fi
163+
if [[ -n "${RECORD_EXCLUDED}" ]]; then
164+
CMD+=(--record-excluded="${RECORD_EXCLUDED}")
165+
fi
166+
167+
"${CMD[@]}" sast_coverity_buildless_check_all_findings.json > filtered_sast_coverity_buildless_check_all_findings.json
168+
status=$?
169+
if [ "$status" -ne 0 ]; then
170+
echo "Error: failed to filter known false positives" >&2
171+
return 1
172+
else
173+
echo "Message: Succeed to filter known false positives" >&2
174+
SCAN_RESULT="filtered_sast_unicode_check_out.json"
175+
fi
176+
177+
echo "Results after filtering:"
178+
(set -x; csgrep --mode=evtstat filtered_sast_coverity_buildless_check_all_findings.json)
179+
fi
180+
181+
csgrep --mode=sarif filtered_sast_coverity_buildless_check_all_findings.json > $(workspaces.workspace.path)/hacbs/$(context.task.name)/coverity-buildless-results.sarif
182+
183+
if [[ -z "$(csgrep --mode=evtstat filtered_sast_coverity_buildless_check_all_findings.json)" ]]; then
184+
note="Task $(context.task.name) success: No finding was detected"
185+
ERROR_OUTPUT=$(make_result_json -r SUCCESS -t "$note")
186+
else
187+
TEST_OUTPUT=
188+
parse_test_output $(context.task.name) sarif $(workspaces.workspace.path)/hacbs/$(context.task.name)/coverity-buildless-results.sarif || true
189+
note="Task $(context.task.name) failed: For details, check Tekton task log."
190+
ERROR_OUTPUT=$(make_result_json -r ERROR -t "$note")
191+
fi
192+
193+
echo "${TEST_OUTPUT:-${ERROR_OUTPUT}}" | tee $(results.TEST_OUTPUT.path)
194+
195+
- name: upload
196+
image: quay.io/konflux-ci/oras:latest@sha256:99737f436051e6d3866eb8a8706463c35abf72c87f05090ff42ff642f6729661
197+
workingDir: $(workspaces.workspace.path)/hacbs/$(context.task.name)
198+
env:
199+
- name: IMAGE_URL
200+
value: $(params.image-url)
201+
- name: IMAGE_DIGEST
202+
value: $(params.image-digest)
203+
script: |
204+
#!/usr/bin/env bash
205+
206+
UPLOAD_FILE=coverity-buildless-results.sarif
207+
MEDIA_TYPE=application/sarif+json
208+
209+
if [ -z "${IMAGE_URL}" ] || [ -z "${IMAGE_DIGEST}" ]; then
210+
echo 'No image-url or image-digest param provided. Skipping upload.'
211+
exit 0;
212+
fi
213+
214+
if [ ! -f "${UPLOAD_FILE}" ]; then
215+
echo "No ${UPLOAD_FILE} exists. Skipping upload."
216+
exit 0;
217+
fi
218+
219+
echo "Selecting auth"
220+
select-oci-auth $IMAGE_URL > $HOME/auth.json
221+
echo "Attaching to ${IMAGE_URL}"
222+
oras attach --no-tty --registry-config "$HOME/auth.json" --artifact-type "${MEDIA_TYPE}" "${IMAGE_URL}" "${UPLOAD_FILE}:${MEDIA_TYPE}"
223+
workspaces:
224+
- name: workspace

task/sast-coverity-check/OWNERS

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# See the OWNERS docs: https://go.k8s.io/owners
2+
approvers:
3+
- integration-team
4+
reviewers:
5+
- integration-team

0 commit comments

Comments
 (0)