Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sast: Add sast-unicode-check task for testing #1401

Merged
merged 2 commits into from
Oct 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion .tekton/pull-request.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ metadata:
name: build-definitions-pull-request
annotations:
pipelinesascode.tekton.dev/on-cel-expression: (event == "pull_request" && target_branch == "main" && ( !has(body.pull_request) || !body.pull_request.draft) ) || (event == "push" && target_branch.startsWith("gh-readonly-queue/main/"))
pipelinesascode.tekton.dev/task: "[task/git-clone/0.1/git-clone.yaml, .tekton/tasks/buildah.yaml, .tekton/tasks/task-lint.yaml, .tekton/tasks/e2e-test.yaml, task/sast-snyk-check/0.2/sast-snyk-check.yaml]"
pipelinesascode.tekton.dev/task: "[task/git-clone/0.1/git-clone.yaml, .tekton/tasks/buildah.yaml, .tekton/tasks/task-lint.yaml, .tekton/tasks/e2e-test.yaml, task/sast-snyk-check/0.2/sast-snyk-check.yaml, task/sast-unicode-check/0.1/sast-unicode-check.yaml]"
pipelinesascode.tekton.dev/max-keep-runs: "5"
spec:
params:
Expand Down Expand Up @@ -52,6 +52,14 @@ spec:
workspaces:
- name: workspace
workspace: workspace
- name: sast-unicode-check
runAfter:
- build-container
taskRef:
name: sast-unicode-check
workspaces:
- name: workspace
workspace: workspace
- name: build-container
runAfter:
- task-lint-check
Expand Down
29 changes: 29 additions & 0 deletions task/sast-unicode-check/0.1/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# sast-unicode-check task

## Description:

The sast-unicode-check task uses [find-unicode-control](https://github.com/siddhesh/find-unicode-control.git) tool to perform Static Application Security Testing (SAST) to look for non-printable unicode characters in all text files in a source tree.

## Parameters:

| name | description | Default Value | Required |
|------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------|----------|
| FIND_UNICODE_CONTROL_GIT_URL | URL from repository to find unicode control. | "https://github.com/siddhesh/find-unicode-control.git#c2accbfbba7553a8bc1ebd97089ae08ad8347e58" | No |
| FIND_UNICODE_CONTROL_ARGS | arguments for find-unicode-control command. | "-p bidi -v -d -t" | 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_NVR | Name-Version-Release (NVR) of the scanned project. It is used to find path exclusions (it is 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 |

## Results:

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

## Source repository for image:

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

## Additional links:

* https://github.com/siddhesh/find-unicode-control.git
259 changes: 259 additions & 0 deletions task/sast-unicode-check/0.1/sast-unicode-check.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,259 @@
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-unicode-check
spec:
description: >-
Scans source code for non-printable unicode characters in all text files.
results:
- description: Tekton task test output.
name: TEST_OUTPUT
params:
- name: image-url
type: string
description: Image URL.
default: ""
- name: FIND_UNICODE_CONTROL_GIT_URL
type: string
description: URL from repository to find unicode control.
default: "https://github.com/siddhesh/find-unicode-control.git#c2accbfbba7553a8bc1ebd97089ae08ad8347e58"
- name: FIND_UNICODE_CONTROL_ARGS
type: string
description: arguments for find-unicode-control command.
default: "-p bidi -v -d -t"
- 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_NVR
type: string
description: |
Name-Version-Release (NVR) of the scanned project.
It is used to find path exclusions (it is optional).
default: ""
- name: RECORD_EXCLUDED
type: string
description: |
Whether to record the excluded findings (defaults to false).
If `true`, the the excluded findings will be stored in `excluded-findings.json`.
default: "false"
- 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
volumes:
- name: trusted-ca
configMap:
name: $(params.caTrustConfigMapName)
hanchuntao marked this conversation as resolved.
Show resolved Hide resolved
items:
- key: $(params.caTrustConfigMapKey)
path: ca-bundle.crt
optional: true
steps:
- name: sast-unicode-check
image: quay.io/redhat-appstudio/konflux-test:v1.4.6@sha256:5f298d8d990dfa82023e50029b71b08e19c3c9cedb181dfc4bc86c9ecad8700c
# 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:
hanchuntao marked this conversation as resolved.
Show resolved Hide resolved
- mountPath: /mnt/trusted-ca
name: trusted-ca
readOnly: true
env:
- name: KFP_GIT_URL
value: $(params.KFP_GIT_URL)
- name: FIND_UNICODE_CONTROL_GIT_URL
value: $(params.FIND_UNICODE_CONTROL_GIT_URL)
- name: FIND_UNICODE_CONTROL_ARGS
value: $(params.FIND_UNICODE_CONTROL_ARGS)
- name: PROJECT_NVR
value: $(params.PROJECT_NVR)
- name: RECORD_EXCLUDED
value: $(params.RECORD_EXCLUDED)
- name: SOURCE_CODE_DIR
value: $(workspaces.workspace.path)
script: |
#!/usr/bin/env bash
set -exuo pipefail

# shellcheck source=/dev/null
. /utils.sh
trap 'handle_error $(results.TEST_OUTPUT.path)' EXIT

SCAN_PROP=""

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

# Clone the source code from upstream repo
GIT_URL=$(echo "${FIND_UNICODE_CONTROL_GIT_URL}" | awk -F'#' '{print $1}')
REV=$(echo "${FIND_UNICODE_CONTROL_GIT_URL}" | awk -F'#' '{print $2}')

# Clone find-unicode-control repository
if ! git clone "${GIT_URL}" find-unicode-control; then
echo "Failed to clone the repository: ${GIT_URL}" >&2
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

if [[ -n "${REV}" ]]; then
if ! git -C ./find-unicode-control/ checkout "${REV}"; then
echo "Failed to checkout the repository: ${GIT_URL} to ${REV}" >&2
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
SCAN_PROP="find-unicode-control-git-url:${FIND_UNICODE_CONTROL_GIT_URL}"
else
git_url_suffix=$(git -C ./find-unicode-control/ rev-parse HEAD)
SCAN_PROP="find-unicode-control-git-url:${FIND_UNICODE_CONTROL_GIT_URL}#${git_url_suffix}"
hanchuntao marked this conversation as resolved.
Show resolved Hide resolved
fi

# Find unicode control
FUC_EXIT_CODE=0
mapfile -t fuc_args <<< "${FIND_UNICODE_CONTROL_ARGS}"
LANG=en_US.utf8 ./find-unicode-control/find_unicode_control.py "${fuc_args[@]}" "${SOURCE_CODE_DIR}/source" \
>raw_sast_unicode_check_out.txt \
2>raw_sast_unicode_check_out.log \
hanchuntao marked this conversation as resolved.
Show resolved Hide resolved
|| FUC_EXIT_CODE=$?
if [[ "${FUC_EXIT_CODE}" -ne 0 ]] && [[ "${FUC_EXIT_CODE}" -ne 1 ]]; then
echo "Failed to run find-unicode-control command" >&2
cat raw_sast_unicode_check_out.log
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

# Translate the output format
if ! sed -i raw_sast_unicode_check_out.txt -E -e 's|(.*:[0-9]+)(.*)|\1: warning:\2|' -e 's|^|Error: UNICONTROL_WARNING:\n|'; then
echo "Error: failed to translate the unicontrol output format" >&2
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

# Process all results as configured with CSGERP_OPTS
CSGERP_OPTS=(
--mode=json
--remove-duplicates
--embed-context=3
--set-scan-prop="${SCAN_PROP}"
--strip-path-prefix="${SOURCE_CODE_DIR}"/source/
)
# In order to generate csdiff/v1, we need to add the whole path of the source code as
# sast-unicode-check only provides an URI to embed the context
if ! csgrep "${CSGERP_OPTS[@]}" raw_sast_unicode_check_out.txt > processed_sast_unicode_check_out.json 2> processed_sast_unicode_check_out.err; then
echo "Error occurred while running csgrep with CSGERP_OPTS:"
cat processed_sast_unicode_check_out.err
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

csgrep --mode=evtstat processed_sast_unicode_check_out.json

# Filter known false positives if KFP_GIT_URL is set
if [ -n "${KFP_GIT_URL}" ]; then
echo "Filtering false positives in results files using ${KFP_GIT_URL}..." >&2

# Build initial csfilter-kfp command
csfilter_kfp_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_kfp_cmd+=(--project-nvr="${PROJECT_NVR}")
fi

# Append --record-excluded option if RECORD_EXCLUDED is true
if [[ "${RECORD_EXCLUDED}" == "true" ]]; then
csfilter_kfp_cmd+=(--record-excluded="excluded-findings.json")
fi

if ! "${csfilter_kfp_cmd[@]}" processed_sast_unicode_check_out.json > sast_unicode_check_out.json 2> sast_unicode_check_out.error; then
echo "Failed to filter known false positives" >&2
cat sast_unicode_check_out.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)"
exit 1
fi
else
echo "KFP_GIT_URL is not set. Skipping false positive filtering." >&2
mv processed_sast_unicode_check_out.json sast_unicode_check_out.json
fi

# Generate sarif report
csgrep --mode=sarif sast_unicode_check_out.json > sast_unicode_check_out.sarif
if [[ "${FUC_EXIT_CODE}" -eq 0 ]]; then
note="Task $(context.task.name) success: No finding was detected"
ERROR_OUTPUT=$(make_result_json -r SUCCESS -t "$note")
elif [[ "${FUC_EXIT_CODE}" -eq 1 ]] && [[ ! -s sast_unicode_check_out.sarif ]]; then
note="Task $(context.task.name) success: Some findings were detected, but filtered by known false positive"
ERROR_OUTPUT=$(make_result_json -r SUCCESS -t "$note")
else
echo "sast-unicode-check test failed because of the following issues:"
cat sast_unicode_check_out.json
TEST_OUTPUT=
parse_test_output "$(context.task.name)" sarif sast_unicode_check_out.sarif || true
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)
script: |
#!/usr/bin/env bash

if [ -z "${IMAGE_URL}" ]; then
echo 'No image-url param provided. Skipping upload.'
exit 0;
fi

UPLOAD_FILES="sast_unicode_check_out.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
5 changes: 5 additions & 0 deletions task/sast-unicode-check/OWNERS
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# See the OWNERS docs: https://go.k8s.io/owners
approvers:
- integration-team
reviewers:
- integration-team
Loading