diff --git a/actions/SCA/grype_image/action.yaml b/actions/SCA/grype_image/action.yaml index 99c9f85..279c032 100644 --- a/actions/SCA/grype_image/action.yaml +++ b/actions/SCA/grype_image/action.yaml @@ -6,7 +6,6 @@ inputs: target: description: 'The target to be scanned, here the name of the docker image.' required: true - default: '.' report_name: description: 'The name of the report to be written.' required: true diff --git a/actions/SCA/grype_sbom/action.yaml b/actions/SCA/grype_sbom/action.yaml new file mode 100644 index 0000000..ef89774 --- /dev/null +++ b/actions/SCA/grype_sbom/action.yaml @@ -0,0 +1,62 @@ +name: 'SecObserve Grype SBOM' +description: 'Scans CycloneDX SBOMs for vulnerabilities with Grype' +author: 'MaibornWolff' + +inputs: + target: + description: 'The target to be scanned, here the name of a CycloneDX SBOM.' + required: true + report_name: + description: 'The name of the report to be written.' + required: true + further_parameters: + description: 'Further parameters to be given to the scanner.' + required: false + default: '' + so_upload: + description: 'No upload of observations into SecObserve if value is not "true", default is "true".' + required: false + default: 'true' + so_api_base_url: + description: 'Base URL of the SecObserve backend' + required: true + so_api_token: + description: 'API token of the user to be used for the import.' + required: true + so_product_name: + description: 'Name of the product which observations are imported. The product has to exist before starting the import.' + required: true + so_branch_name: + description: 'Name of the product branch which observations are imported. If the branch does not exist yet, it is automatically created.' + required: false + so_origin_service: + description: 'Service name to be set for all imported observations.' + required: false + so_origin_docker_image_name_tag: + description: 'Name:Tag of Docker image to be set for all imported observations.' + required: false + so_origin_endpoint_url: + description: 'URL of endpoint to be set for all imported observations.' + required: false + so_suppress_licenses: + description: 'Suppress importing license information if value is "true", default is "true".' + required: false + default: 'true' + +runs: + using: 'docker' + image: 'docker://maibornwolff/secobserve-scanners:latest' + entrypoint: '/entrypoints/entrypoint_grype_sbom.sh' + env: + TARGET: ${{ inputs.target }} + REPORT_NAME: ${{ inputs.report_name }} + FURTHER_PARAMETERS: ${{ inputs.further_parameters }} + SO_UPLOAD: ${{ inputs.so_upload }} + SO_API_BASE_URL: ${{ inputs.so_api_base_url }} + SO_API_TOKEN: ${{ inputs.so_api_token }} + SO_PRODUCT_NAME: ${{ inputs.so_product_name }} + SO_BRANCH_NAME: ${{ inputs.so_branch_name }} + SO_ORIGIN_SERVICE: ${{ inputs.so_origin_service }} + SO_ORIGIN_DOCKER_IMAGE_NAME_TAG: ${{ inputs.so_origin_docker_image_name_tag }} + SO_ORIGIN_ENDPOINT_URL: ${{ inputs.so_origin_endpoint_url }} + SO_SUPPRESS_LICENSES: ${{ inputs.so_suppress_licenses }} diff --git a/actions/importer/action.yaml b/actions/importer/action.yaml index 8f04aaa..1030da1 100644 --- a/actions/importer/action.yaml +++ b/actions/importer/action.yaml @@ -35,9 +35,9 @@ inputs: description: 'URL of endpoint to be set for all imported observations.' required: false so_suppress_licenses: - description: 'Suppress importing license information if value is "true", default is "true".' + description: 'Suppress importing license information if value is "true", default is "false".' required: false - default: 'true' + default: 'false' runs: using: 'docker' diff --git a/dev/actions/SCA/grype_image/action.yaml b/dev/actions/SCA/grype_image/action.yaml index 0dec375..c3a3949 100644 --- a/dev/actions/SCA/grype_image/action.yaml +++ b/dev/actions/SCA/grype_image/action.yaml @@ -6,7 +6,6 @@ inputs: target: description: 'The target to be scanned, here the name of the docker image.' required: true - default: '.' report_name: description: 'The name of the report to be written.' required: true diff --git a/dev/actions/SCA/grype_sbom/action.yaml b/dev/actions/SCA/grype_sbom/action.yaml new file mode 100644 index 0000000..5c48d6d --- /dev/null +++ b/dev/actions/SCA/grype_sbom/action.yaml @@ -0,0 +1,62 @@ +name: 'SecObserve Grype SBOM' +description: 'Scans CycloneDX SBOMs for vulnerabilities with Grype' +author: 'MaibornWolff' + +inputs: + target: + description: 'The target to be scanned, here the name of a CycloneDX SBOM.' + required: true + report_name: + description: 'The name of the report to be written.' + required: true + further_parameters: + description: 'Further parameters to be given to the scanner.' + required: false + default: '' + so_upload: + description: 'No upload of observations into SecObserve if value is not "true", default is "true".' + required: false + default: 'true' + so_api_base_url: + description: 'Base URL of the SecObserve backend' + required: true + so_api_token: + description: 'API token of the user to be used for the import.' + required: true + so_product_name: + description: 'Name of the product which observations are imported. The product has to exist before starting the import.' + required: true + so_branch_name: + description: 'Name of the product branch which observations are imported. If the branch does not exist yet, it is automatically created.' + required: false + so_origin_service: + description: 'Service name to be set for all imported observations.' + required: false + so_origin_docker_image_name_tag: + description: 'Name:Tag of Docker image to be set for all imported observations.' + required: false + so_origin_endpoint_url: + description: 'URL of endpoint to be set for all imported observations.' + required: false + so_suppress_licenses: + description: 'Suppress importing license information if value is "true", default is "true".' + required: false + default: 'true' + +runs: + using: 'docker' + image: 'docker://maibornwolff/secobserve-scanners:dev' + entrypoint: '/entrypoints/entrypoint_grype_sbom.sh' + env: + TARGET: ${{ inputs.target }} + REPORT_NAME: ${{ inputs.report_name }} + FURTHER_PARAMETERS: ${{ inputs.further_parameters }} + SO_UPLOAD: ${{ inputs.so_upload }} + SO_API_BASE_URL: ${{ inputs.so_api_base_url }} + SO_API_TOKEN: ${{ inputs.so_api_token }} + SO_PRODUCT_NAME: ${{ inputs.so_product_name }} + SO_BRANCH_NAME: ${{ inputs.so_branch_name }} + SO_ORIGIN_SERVICE: ${{ inputs.so_origin_service }} + SO_ORIGIN_DOCKER_IMAGE_NAME_TAG: ${{ inputs.so_origin_docker_image_name_tag }} + SO_ORIGIN_ENDPOINT_URL: ${{ inputs.so_origin_endpoint_url }} + SO_SUPPRESS_LICENSES: ${{ inputs.so_suppress_licenses }} diff --git a/dev/templates/SCA/grype_sbom.yml b/dev/templates/SCA/grype_sbom.yml new file mode 100644 index 0000000..0f4248e --- /dev/null +++ b/dev/templates/SCA/grype_sbom.yml @@ -0,0 +1,15 @@ +.grype_image: + image: + name: maibornwolff/secobserve-scanners:dev + stage: test + variables: + FURTHER_PARAMETERS: "" + SO_UPLOAD: "true" + script: + - /entrypoints/entrypoint_grype_sbom.sh + interruptible: true + allow_failure: true + artifacts: + when: always + paths: + - "$REPORT_NAME" diff --git a/docker/Dockerfile b/docker/Dockerfile index 48e99b5..c7ff5ad 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -1,5 +1,5 @@ # Python build stage -FROM python:3.12.6-alpine AS python-build-stage +FROM python:3.12.7-alpine AS python-build-stage # Install gcc to be able to compile wheels for python packages RUN apk add --no-cache gcc musl-dev python3-dev diff --git a/docker/entrypoints/entrypoint_grype_image.sh b/docker/entrypoints/entrypoint_grype_image.sh index 4b9d9c3..a64272f 100755 --- a/docker/entrypoints/entrypoint_grype_image.sh +++ b/docker/entrypoints/entrypoint_grype_image.sh @@ -27,8 +27,7 @@ if [[ -n "$FURTHER_PARAMETERS" ]]; then fi cd "$WORKSPACE" -docker pull --quiet "$TARGET" -grype docker:"$TARGET" $FURTHER_PARAMETERS --quiet --output cyclonedx-json --file "$REPORT_NAME" +grype docker:"$TARGET" $FURTHER_PARAMETERS --by-cve --quiet --output cyclonedx-json --file "$REPORT_NAME" if [ "$SO_UPLOAD" == "true" ]; then source file_upload_observations.sh diff --git a/docker/entrypoints/entrypoint_grype_sbom.sh b/docker/entrypoints/entrypoint_grype_sbom.sh new file mode 100755 index 0000000..8dd9b3c --- /dev/null +++ b/docker/entrypoints/entrypoint_grype_sbom.sh @@ -0,0 +1,36 @@ +#!/bin/sh +set -e + +if [[ -z "${GITHUB_WORKSPACE}" ]]; then + if [[ -z "${CI_PROJECT_DIR}" ]]; then + WORKSPACE=. + else + WORKSPACE="${CI_PROJECT_DIR}" + fi +else + WORKSPACE="${GITHUB_WORKSPACE}" +fi + +export SO_FILE_NAME="${REPORT_NAME}" +export SO_PARSER_NAME="CycloneDX" + +if [[ -z "${SO_SUPPRESS_LICENSES}" ]]; then + export SO_SUPPRESS_LICENSES=true +fi + +echo ---------------------------------------- +echo Grype SBOM +echo - TARGET: "$TARGET" +echo - REPORT_NAME: "$REPORT_NAME" +if [[ -n "$FURTHER_PARAMETERS" ]]; then + echo - FURTHER_PARAMETERS: "$FURTHER_PARAMETERS" +fi + +cd "$WORKSPACE" +grype sbom:"$TARGET" $FURTHER_PARAMETERS --by-cve --quiet --output cyclonedx-json --file "$REPORT_NAME" + +if [ "$SO_UPLOAD" == "true" ]; then + source file_upload_observations.sh +fi + +exit 0 diff --git a/templates/SCA/grype_sbom.yml b/templates/SCA/grype_sbom.yml new file mode 100644 index 0000000..68d9d12 --- /dev/null +++ b/templates/SCA/grype_sbom.yml @@ -0,0 +1,15 @@ +.grype_image: + image: + name: maibornwolff/secobserve-scanners:latest + stage: test + variables: + FURTHER_PARAMETERS: "" + SO_UPLOAD: "true" + script: + - /entrypoints/entrypoint_grype_sbom.sh + interruptible: true + allow_failure: true + artifacts: + when: always + paths: + - "$REPORT_NAME" diff --git a/vulnerability_scanner/vulnerability_scanner/scan_vulnerabilities.py b/vulnerability_scanner/vulnerability_scanner/scan_vulnerabilities.py index f1bbf1d..46aa3a5 100644 --- a/vulnerability_scanner/vulnerability_scanner/scan_vulnerabilities.py +++ b/vulnerability_scanner/vulnerability_scanner/scan_vulnerabilities.py @@ -14,6 +14,7 @@ "eslint", "gitleaks", "grype_image", + "grype_sbom", "kics", "semgrep", "trivy_config",