From 0b3916afe40df51f8c3a0e994c6a5ea1fafb46c5 Mon Sep 17 00:00:00 2001 From: Cosimo Commisso Date: Mon, 13 Nov 2023 11:24:24 +0000 Subject: [PATCH 1/8] Merged in PIPES-11_FixGitHubActions (pull request #19) PIPES-11: fix docker build action * PIPES-11: fix docker build action --- .github/workflows/docker-image.yml | 2 +- .gitignore | 3 +++ build_docker.sh | 1 + 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml index 9d207b0..2141495 100644 --- a/.github/workflows/docker-image.yml +++ b/.github/workflows/docker-image.yml @@ -15,4 +15,4 @@ jobs: steps: - uses: actions/checkout@v3 - name: Build the Docker image - run: docker build . --file Dockerfile --tag cyclonedc-npm-pipe:$(date +%s) + run: docker build --build-arg ARCH=amd64 --tag cyclonedc-npm-pipe:$(date +%s) . diff --git a/.gitignore b/.gitignore index aa083e2..6823c4b 100644 --- a/.gitignore +++ b/.gitignore @@ -164,3 +164,6 @@ output/ # ide .idea/ + +# push_to_github +push_to_github.sh \ No newline at end of file diff --git a/build_docker.sh b/build_docker.sh index 0dc2f06..b59d575 100755 --- a/build_docker.sh +++ b/build_docker.sh @@ -3,6 +3,7 @@ echo "building docker image locally..." docker build \ + --no-cache \ --build-arg ARCH=arm64 \ --tag cyclonedx-npm-pipe:dev \ . From 82d495edd54392f8bf4651293612f917a6e539a1 Mon Sep 17 00:00:00 2001 From: Cosimo Commisso Date: Sun, 18 Feb 2024 12:18:53 +0000 Subject: [PATCH 2/8] Merged in feb_2024_updates (pull request #20) Feb 2024 updates * Feb 2024 updates * Feb 2024 updates * Feb 2024 updates --- .gitignore | 7 +- Dockerfile | 12 +--- Makefile | 81 ++++++++++++++++++++++ README.md | 20 +----- bitbucket-pipelines.yml | 96 +++++++++++++++++--------- build_docker.sh | 11 --- gen_bomber.sh | 61 ----------------- gen_sbom.sh | 11 --- pipe.yml | 2 +- run_cyclonedx_npm_pipe.sh | 26 -------- run_docker_lint.sh | 10 --- run_shell_lint.sh | 10 --- run_tests.sh | 10 --- sample.json | 6 ++ test/gen_bomber.bats | 137 -------------------------------------- variables.list | 8 +++ 16 files changed, 171 insertions(+), 337 deletions(-) create mode 100644 Makefile delete mode 100755 build_docker.sh delete mode 100755 gen_bomber.sh delete mode 100755 run_cyclonedx_npm_pipe.sh delete mode 100755 run_docker_lint.sh delete mode 100755 run_shell_lint.sh delete mode 100755 run_tests.sh create mode 100644 sample.json delete mode 100644 test/gen_bomber.bats create mode 100755 variables.list diff --git a/.gitignore b/.gitignore index 6823c4b..7b9a42f 100644 --- a/.gitignore +++ b/.gitignore @@ -166,4 +166,9 @@ output/ .idea/ # push_to_github -push_to_github.sh \ No newline at end of file +push_to_github.sh + +# node +package.json +package-lock.json +node_modules/ \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 107a4f7..040cefa 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,28 +1,20 @@ -FROM node:18.12.1-bullseye-slim +FROM node:18-bullseye-slim ARG ARCH RUN apt-get update \ && DEBIAN_FRONTEND=noninteractive apt-get -y upgrade \ - && apt-get install --no-install-recommends -y curl=7.74.0-1.3+deb11u10 \ - && apt-get install --no-install-recommends -y ca-certificates=20210119 \ && apt-get autoremove -y \ && rm -rf /var/lib/apt/lists/* -ENV BOMBER_VERSION="0.4.5" \ - CYCLONEDX_NPM_VERSION="1.14.1" \ +ENV CYCLONEDX_NPM_VERSION="1.16.1" \ GEN_SBOM_SCRIPT_LOCATION="/opt" ENV PATH="${GEN_SBOM_SCRIPT_LOCATION}:${PATH}" -ARG BOMBER_URL="https://github.com/devops-kung-fu/bomber/releases/download/v${BOMBER_VERSION}/bomber_${BOMBER_VERSION}_linux_${ARCH}.deb" -ARG BOMBER_FILENAME="bomber_${BOMBER_VERSION}_linux_${ARCH}.deb" - COPY gen_*.sh $GEN_SBOM_SCRIPT_LOCATION/ # install dependencies RUN npm install --global @cyclonedx/cyclonedx-npm@${CYCLONEDX_NPM_VERSION} \ - && curl -L -o $BOMBER_FILENAME $BOMBER_URL \ - && dpkg -i $BOMBER_FILENAME \ && rm -rf /root/.npm # Create a non-root user and group diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..ff8f596 --- /dev/null +++ b/Makefile @@ -0,0 +1,81 @@ +DOCKER ?= docker +PWD ?= pwd +GEN_SBOM ?= ./gen_sbom.sh +NPM ?= npm +SAMPLE_JSON ?= sample.json + +.PHONY: test +test: + $(DOCKER) run --rm -it \ + -v $(PWD):/build \ + --workdir /build \ + bats/bats:1.9.0 test/**.bats --timing --show-output-of-passing-tests --verbose-run + +.PHONY: shellcheck +shellcheck: + $(DOCKER) run --rm -it \ + -v $(PWD):/build \ + --workdir /build \ + koalaman/shellcheck-alpine:v0.9.0 shellcheck -x ./*.sh ./**/*.bats + +.PHONY: clean +clean: + rm -rf sbom_output + rm -rf output + rm -rf build + rm -rf node_modules + rm package.json package-lock.json || echo "not found" + +.PHONY: docker +docker: + $(DOCKER) build --build-arg ARCH=arm64 --tag cyclonedx-bitbucket-npm-pipe:dev . + +.PHONY: docker-amd64 +docker-amd64: + $(DOCKER) buildx build --platform linux/amd64 --build-arg ARCH=amd64 --tag cyclonedx-bitbucket-npm-pipe:dev . + +.PHONY: docker-lint +docker-lint: + $(DOCKER) run --rm -it \ + -v "$(shell pwd)":/build \ + --workdir /build \ + hadolint/hadolint:v2.12.0-alpine hadolint Dockerfile* + +.PHONY: markdown-lint +markdown-lint: + $(DOCKER) run --rm -it \ + -v "$(shell pwd)":/build \ + --workdir /build \ + markdownlint/markdownlint:0.13.0 *.md + +.PHONY: scan-project +scan-project: + export NPM_PACKAGE_LOCK_ONLY=false && \ + export IGNORE_NPM_ERRORS=true && \ + export NPM_FLATTEN_COMPONENTS=false && \ + export NPM_SHORT_PURLS=false && \ + export NPM_OUTPUT_REPRODUCIBLE=false && \ + export NPM_SPEC_VERSION=1.4 && \ + export NPM_OUTPUT_FORMAT=json && \ + $(GEN_SBOM) + +.PHONY: scan-project-docker +scan-project-docker: + $(DOCKER) run --rm -it \ + -v $(PWD):/tmp \ + --workdir /tmp \ + --env-file variables.list \ + cyclonedx-bitbucket-npm-pipe:dev + +.PHONY: docker-debug +docker-debug: + $(DOCKER) run --rm -it \ + -v $(PWD)/samples:/tmp/samples \ + --workdir /tmp \ + --env-file variables.list \ + --entrypoint bash \ + cyclonedx-bitbucket-npm-pipe:dev + +sample: + @cp ${SAMPLE_JSON} package.json + $(NPM) install diff --git a/README.md b/README.md index bb0adb8..b81a017 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,7 @@ # Bitbucket Pipelines Pipe: CycloneDX npm/node sBOM Generator A Bitbucket Pipe which generates a CycloneDX compliant Software Bill of Materials -for a node/npm project. Optionally this pipe has the ability to scan the generated -CycloneDX sBOM for OSS security vulnerabilities using various tools such as -[bomber](https://github.com/devops-kung-fu/bomber). +for a node/npm project. For obvious reason the official copy this project is hosted on [Bitbucket](https://bitbucket.org/ccideas1/cyclonedx-npm-pipe/src/main/). In order to reach a diverse audience a copy of the repo also exists in [GitHub](https://github.com/ccideas/cyclonedx-npm-pipe). @@ -31,15 +29,12 @@ pipelines: caches: - node script: - - pipe: docker://ccideas/cyclonedx-npm-pipe:1.2.1 + - pipe: docker://ccideas/cyclonedx-npm-pipe:1.3.0 variables: IGNORE_NPM_ERRORS: 'true' # optional NPM_SHORT_PURLS: 'true' # optional NPM_OUTPUT_FORMAT: 'json' # optional NPM_PACKAGE_LOCK_ONLY: 'false' # optional - SCAN_SBOM_WITH_BOMBER: 'true' # optional - BOMBER_OUTPUT_FORMAT: 'html' # optional - BOMBER_DEBUG: 'true' # optional OUTPUT_DIRECTORY: 'build' # optional # this dir should be archived by the pipeline artifacts: - build/* @@ -52,20 +47,12 @@ pipelines: | NPM_FLATTEN_COMPONENTS | Used to specify if the components should be flattened | true, false | false | | NPM_SHORT_PURLS | Used to specify if qualifiers from PackageURLs should be shortened | true, false | false | | NPM_OUTPUT_REPRODUCIBLE | Used to specify if the output should be reproducible | true, false | false | -| NPM_SPEC_VERSION | Used to specify the version of the CycloneDX spec | 1.2, 1.3, 1.4 | 1.4 | +| NPM_SPEC_VERSION | Used to specify the version of the CycloneDX spec | 1.2, 1.3, 1.4, 1.5 | 1.4 | | NPM_MC_TYPE | Used to specify the type of main component | application, firmware, library | application | | NPM_OMIT | Used to omit specific dependency types | dev, optional, peer | none | | NPM_OUTPUT_FORMAT | Used to specify output format of the sBOM | json, xml | json | | NPM_PACKAGE_LOCK_ONLY | Used to use only the package-lock.json file to find dependencies | true, false | false | -| SCAN_SBOM_WITH_BOMBER | Used to scan the sBOM for vulnerabilities using bomber | true, false | false | -| BOMBER_DEBUG | Used to enable debug mode during bomber scan | true, false | false | -| BOMBER_IGNORE_FILE | Used to tell bomber what CVEs to ignore | | none | -| BOMBER_PROVIDER | Used to specify what vulnerability provider bomber will use | osv, ossindex | osv | -| BOMBER_PROVIDER_TOKEN | Used to specify an API token for the selected provider | | none | -| BOMBER_PROVIDER_USERNAME | Used to specify an username for the selected provider | | none | -| BOMBER_OUTPUT_FORMAT | Used to specify the output format of the bomber scan | json, html, stdout | stdout | | OUTPUT_DIRECTORY | Used to specify the directory to place all output im | | sbom_output | -| SBOM_FILENAME | Used to specify the name of the sbom file | | ${bitbucket-repo-name}-sbom | ## Details @@ -105,6 +92,5 @@ steps to reproduce This Bitbucket pipe is a collection and integration of the following open source tools * [cyclonedx-npm](https://github.com/CycloneDX/cyclonedx-node-npm) -* [bomber](https://github.com/devops-kung-fu/bomber) A big thank-you to the teams and volunteers who make these amazing tools available diff --git a/bitbucket-pipelines.yml b/bitbucket-pipelines.yml index f4337de..474136c 100644 --- a/bitbucket-pipelines.yml +++ b/bitbucket-pipelines.yml @@ -3,53 +3,85 @@ definitions: - step: &build-docker-image name: 'Build Docker Image' script: - - IMAGE_NAME=${BITBUCKET_REPO_SLUG} - - echo "IMAGE_NAME is set to:\ ${IMAGE_NAME}" - - docker build --build-arg ARCH=amd64 --tag ${IMAGE_NAME} . - - docker save ${IMAGE_NAME} --output "${IMAGE_NAME}.tar" + - IMAGE_NAME=cyclonedx-npm-pipe + - docker build --build-arg ARCH=amd64 --tag "${IMAGE_NAME}:local" . + - docker save "${IMAGE_NAME}:local" --output "${IMAGE_NAME}.tar" services: - docker caches: - docker artifacts: - "*.tar" + - step: &build-and-test + name: 'Build and Test' + image: bats/bats:1.9.0 + script: + - echo "Running tests...." + - test/gen_sbom.bats --timing --show-output-of-passing-tests --verbose-run + - step: &shell-check + name: 'Shell Lint' + image: koalaman/shellcheck-alpine:v0.9.0 + script: + - echo "Linting shell scripts" + - shellcheck -x *.sh **/*.bats + - step: &docker-lint + name: 'Docker Lint' + image: hadolint/hadolint:v2.12.0-alpine + script: + - echo "Linting Dockerfile(s)" + - hadolint Dockerfile + - step: &markdown-lint + name: 'Markdown Lint' + image: markdownlint/markdownlint:0.13.0 + script: + - echo "Linting Markdown Files" + - mdl *.md || echo "Potential mdlint issues found..." pipelines: default: - parallel: - - step: - image: bats/bats:1.9.0 - name: 'Build and Test' - script: - - echo "Running tests...." - - test/gen_sbom.bats --timing - - step: - image: koalaman/shellcheck-alpine:v0.9.0 - name: 'Shell Lint' - script: - - echo "Linting shell scripts" - - shellcheck -x *.sh **/*.bats - - step: - image: hadolint/hadolint:v2.12.0-alpine - name: 'Docker Lint' - script: - - echo "Linting Dockerfile(s)" - - hadolint Dockerfile + - step: *build-and-test + - step: *shell-check + - step: *docker-lint + - step: *markdown-lint - step: *build-docker-image - branches: - main: + custom: + push to Dockerhub (dev): - step: *build-docker-image - step: - name: 'Publish Docker Image' - deployment: Production - trigger: manual + name: 'Publish Dev Docker Image' + deployment: Development script: - echo ${DOCKERHUB_PASSWORD} | docker login --username "${DOCKERHUB_USERNAME}" --password-stdin - - IMAGE_NAME=$BITBUCKET_REPO_SLUG + - IMAGE_NAME=cyclonedx-npm-pipe - docker load --input "${IMAGE_NAME}.tar" - - VERSION="${PROD_VERSION}" - - IMAGE=${DOCKERHUB_NAMESPACE}/${IMAGE_NAME} - - docker tag "${IMAGE_NAME}" "${IMAGE}:${VERSION}" - - docker push "${IMAGE}:${VERSION}" + - docker tag "${IMAGE_NAME}:local" "${DOCKERHUB_NAMESPACE}/${IMAGE_NAME}:${DEV_VERSION}-${BITBUCKET_BUILD_NUMBER}" + - docker push "${DOCKERHUB_NAMESPACE}/${IMAGE_NAME}:${DEV_VERSION}-${BITBUCKET_BUILD_NUMBER}" services: - docker + Prod Release: + - variables: + - name: PRODUCTION_VERSION + - step: *build-docker-image + - stage: + name: Deploy to Prod + deployment: Production + steps: + - step: + name: 'Publish Prod Docker Image' + script: + - IMAGE_NAME=cyclonedx-npm-pipe + - echo ${DOCKERHUB_PASSWORD} | docker login --username "${DOCKERHUB_USERNAME}" --password-stdin + - docker load --input "${IMAGE_NAME}.tar" + - docker tag "${IMAGE_NAME}:local" "${DOCKERHUB_NAMESPACE}/${IMAGE_NAME}:${PRODUCTION_VERSION}" + - docker push "${DOCKERHUB_NAMESPACE}/${IMAGE_NAME}:${PRODUCTION_VERSION}" + services: + - docker + caches: + - docker + - step: + name: tag branch + image: alpine/git:1.0.26 + script: + - git tag -a "v${PRODUCTION_VERSION}" -m "release version ${PRODUCTION_VERSION}" + - git push origin "v${PRODUCTION_VERSION}" diff --git a/build_docker.sh b/build_docker.sh deleted file mode 100755 index b59d575..0000000 --- a/build_docker.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/usr/bin/env bash - -echo "building docker image locally..." - -docker build \ - --no-cache \ - --build-arg ARCH=arm64 \ - --tag cyclonedx-npm-pipe:dev \ - . - -echo "finished building docker image..." \ No newline at end of file diff --git a/gen_bomber.sh b/gen_bomber.sh deleted file mode 100755 index c9c4af8..0000000 --- a/gen_bomber.sh +++ /dev/null @@ -1,61 +0,0 @@ -#!/usr/bin/env bash -set -e - -# Statics -BOMBER_SWITCHES=() - -## purpose: scans generated sbom with bomber to report vulnerabilities - -verify_bomber() { - echo "verifying bomber is installed" - - if [[ "${BOMBER_VERSION}" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then - echo "version ${BOMBER_VERSION} of bomber is installed" - else - echo "ERROR: cannot validate version of bomber. Verify package is installed" - exit 1 - fi -} - -check_sbom() { - echo "checking if sbom file exists" - - if [[ ! -e "${OUTPUT_FILENAME}" ]]; then - echo "ERROR: cannot find sbom file to scan. Verify file was generated successfully" - echo 1 - fi -} - -generate_bomber_switches() { - if [ "${BOMBER_DEBUG}" = "true" ]; then - BOMBER_SWITCHES+=('--debug') - fi - - if [ -n "${BOMBER_IGNORE_FILE}" ]; then - BOMBER_SWITCHES+=("--ignore-file" "${BOMBER_IGNORE_FILE}") - fi - - if [ -n "${BOMBER_PROVIDER}" ]; then - BOMBER_SWITCHES+=("--provider" "${BOMBER_PROVIDER}") - fi - - if [ -n "${BOMBER_PROVIDER_TOKEN}" ]; then - BOMBER_SWITCHES+=("--token" "${BOMBER_PROVIDER_TOKEN}") - fi - - if [ -n "${BOMBER_PROVIDER_USERNAME}" ]; then - BOMBER_SWITCHES+=("--username" "${BOMBER_PROVIDER_USERNAME}") - fi - - if [ -n "${BOMBER_OUTPUT_FORMAT}" ]; then - BOMBER_SWITCHES+=("--output" "${BOMBER_OUTPUT_FORMAT}") - fi - - echo "the following bomber switches will be used" - echo "${BOMBER_SWITCHES[@]}" -} - -run_bomber_scan() { - bomber scan "${BOMBER_SWITCHES[@]}" "${OUTPUT_FILENAME}" - mv ./*-bomber-results.* "${OUTPUT_DIR}" -} diff --git a/gen_sbom.sh b/gen_sbom.sh index 08b9bda..f27e53b 100755 --- a/gen_sbom.sh +++ b/gen_sbom.sh @@ -3,10 +3,8 @@ set -e if [ -z "${GEN_SBOM_SCRIPT_LOCATION}" ]; then source "./gen_sbom_functions.sh" - source "./gen_bomber.sh" else source "${GEN_SBOM_SCRIPT_LOCATION}/gen_sbom_functions.sh" - source "${GEN_SBOM_SCRIPT_LOCATION}/gen_bomber.sh" fi #-------------------------------------------------------------------------------- @@ -20,12 +18,3 @@ fi set_sbom_filename generate_cyclonedx_sbom - -if [ "${SCAN_SBOM_WITH_BOMBER}" == "true" ]; then - echo "scanning sbom via bomber" - BOMBER_VERSION=$(bomber --version | sed 's/^bomber version //') - verify_bomber - check_sbom - generate_bomber_switches - run_bomber_scan -fi diff --git a/pipe.yml b/pipe.yml index c81913b..5ce124d 100644 --- a/pipe.yml +++ b/pipe.yml @@ -1,5 +1,5 @@ name: CycloneDX node/npm sBOM Generator -image: ccideas/cyclonedx-npm-pipe:1.1.0 +image: ccideas/cyclonedx-npm-pipe:1.3.0 category: Security description: Generates a CycloneDX compliant Software Bill of Materials for a node/npm project repository: https://bitbucket.org/ccideas1/cyclonedx-npm-pipe/src/main/ diff --git a/run_cyclonedx_npm_pipe.sh b/run_cyclonedx_npm_pipe.sh deleted file mode 100755 index 3879635..0000000 --- a/run_cyclonedx_npm_pipe.sh +++ /dev/null @@ -1,26 +0,0 @@ -#!/usr/bin/env bash - -echo "running cyclonedx-npm-pipe locally..." - -docker run --rm -it \ - -v "$(pwd)":/build \ - --workdir /build \ - --env NPM_PACKAGE_LOCK_ONLY=true \ - --env NPM_FLATTEN_COMPONENTS=true \ - --env NPM_SHORT_PURLS=true \ - --env NPM_OUTPUT_REPRODUCIBLE=false \ - --env NPM_MC_TYPE=application \ - --env IGNORE_NPM_ERRORS=true \ - --env SCAN_SBOM_WITH_BOMBER=true \ - --env BOMBER_OUTPUT_FORMAT="html" \ - --env BOMBER_DEBUG=true \ - --env OUTPUT_DIRECTORY="build" \ - --env SBOM_FILENAME="auditjs_sbom" \ - cyclonedx-npm-pipe:dev - -echo "successfully ran cyclonedx-npm-pipe locally..." - -# removes --env switches -#--env NPM_OUTPUT_FORMAT=xml \ -#--env NPM_SPEC_VERSION=1.3 \ -#--env NPM_OMIT=dev \ \ No newline at end of file diff --git a/run_docker_lint.sh b/run_docker_lint.sh deleted file mode 100755 index a237f5a..0000000 --- a/run_docker_lint.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/usr/bin/env bash - -echo "running Dockerfile lint locally..." - -docker run --rm -it \ - -v "$(pwd)":/build \ - --workdir /build \ - hadolint/hadolint:v2.12.0-alpine hadolint Dockerfile - -echo "successfully ran Dockerfile lint..." diff --git a/run_shell_lint.sh b/run_shell_lint.sh deleted file mode 100755 index a176e15..0000000 --- a/run_shell_lint.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/usr/bin/env bash - -echo "running shellcheck locally..." - -docker run --rm -it \ - -v "$(pwd)":/build \ - --workdir /build \ - koalaman/shellcheck-alpine:v0.9.0 shellcheck -x ./*.sh ./**/*.bats - -echo "shellcheck complete..." \ No newline at end of file diff --git a/run_tests.sh b/run_tests.sh deleted file mode 100755 index b7f5220..0000000 --- a/run_tests.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/usr/bin/env bash - -echo "running unit tests locally..." - -docker run --rm -it \ - -v "$(pwd)":/build \ - --workdir /build \ - bats/bats:1.9.0 test/**.bats --timing --show-output-of-passing-tests --verbose-run - -echo "unit test run complete..." \ No newline at end of file diff --git a/sample.json b/sample.json new file mode 100644 index 0000000..a812b43 --- /dev/null +++ b/sample.json @@ -0,0 +1,6 @@ +{ + "dependencies": { + "axios": "^1.6.5" + } + } + \ No newline at end of file diff --git a/test/gen_bomber.bats b/test/gen_bomber.bats deleted file mode 100644 index c4507b2..0000000 --- a/test/gen_bomber.bats +++ /dev/null @@ -1,137 +0,0 @@ -#!/usr/bin/env bats - -# shellcheck disable=SC2030,SC2031,SC2317 -# SC2030 (info): Modification of is local (to subshell caused by @bats test) -# SC2031 (info): was modified in a subshell. That change might be lost. -# SC2317 (info): Command appears to be unreachable. Check usage (or ignore if invoked indirectly). -# None of the above checks are suitable for the bats framework - -# file under test -load '../gen_bomber.sh' - -#-------------------------------------------------------------------------------- -#---------------------------------Function Mocks--------------------------------- -#-------------------------------------------------------------------------------- - -#-------------------------------------------------------------------------------- -#---------------------------------------Tests------------------------------------ -#-------------------------------------------------------------------------------- - -@test "Verify bomber is installed" { - # this is just a fake version. Its only used to verify the semver parsing logic - export BOMBER_VERSION="0.2.4" - run verify_bomber - - [ "${lines[1]}" = "version 0.2.4 of bomber is installed" ] -} - -@test "Verify bomber is installed - invalid version" { - unset BOMBER_VERSION - run verify_bomber - - [ "$status" -eq 1 ] -} - -@test "Verify bomber is installed - not installed" { - BOMBER_VERSION="zsh: command not found: bomber" - run verify_bomber - - [ "$status" -eq 1 ] -} - -@test "Verify sbom exists - sbom does exist" { - mkdir "sbom_output" - OUTPUT_FILENAME="sbom_output/testsbom.json" - touch "${OUTPUT_FILENAME}" - - run check_sbom - - [ "$status" -eq 0 ] -} - -@test "Verify switches with params" { - export BOMBER_IGNORE_FILE=".bomberignore" - export BOMBER_PROVIDER="ossindex" - export BOMBER_PROVIDER_TOKEN="1234567890" - export BOMBER_PROVIDER_USERNAME="ossindexusername" - export BOMBER_OUTPUT_FORMAT="html" - - output=$(generate_bomber_switches) - echo "${output}" - - FAILURE_DETECTED=0 - - if [[ ${output} != *"--ignore-file .bomberignore"* ]]; then - FAILURE_DETECTED=$((FAILURE_DETECTED + 1)) - echo "error: --ignore-file was not properly set" - fi - - if [[ ${output} != *"--provider ossindex"* ]]; then - FAILURE_DETECTED=$((FAILURE_DETECTED + 1)) - echo "error: --provider was not properly set" - fi - - if [[ ${output} != *"--token 1234567890"* ]]; then - FAILURE_DETECTED=$((FAILURE_DETECTED + 1)) - echo "error: --token was not successfully set" - fi - - if [[ ${output} != *"--username ossindexusername"* ]]; then - FAILURE_DETECTED=$((FAILURE_DETECTED + 1)) - echo "error: --username was not successfully set" - fi - - if [[ ${output} != *"--output html"* ]]; then - FAILURE_DETECTED=$((FAILURE_DETECTED + 1)) - echo "error: --output was not successfully set" - fi - - return "${FAILURE_DETECTED}" -} - -@test "Verify boolean cmd switches - true" { - export BOMBER_DEBUG="true" - - output=$(generate_bomber_switches) - echo "${output}" - - FAILURE_DETECTED=0 - - if [[ ${output} != *"--debug"* ]]; then - FAILURE_DETECTED=$((FAILURE_DETECTED + 1)) - echo "error: did not find --debug switch" - fi - - return "${FAILURE_DETECTED}" -} - -@test "Verify boolean cmd switches - false" { - export BOMBER_DEBUG="false" - - output=$(generate_bomber_switches) - echo "${output}" - - FAILURE_DETECTED=0 - - if [[ ${output} == *"--debug"* ]]; then - FAILURE_DETECTED=$((FAILURE_DETECTED + 1)) - echo "error: found --debug switch when it was set to false" - fi - - return "${FAILURE_DETECTED}" -} - -#-------------------------------------------------------------------------------- -#--------------------------Setup and Teardown functions-------------------------- -#-------------------------------------------------------------------------------- - -# Custom teardown function -teardown() { - echo "running test cleanup" - - # remove sbom_output if it exists - if [ -d "sbom_output" ]; then - echo "removing sbom_output directory" - rm -rf sbom_output - fi -} diff --git a/variables.list b/variables.list new file mode 100755 index 0000000..8a1db5a --- /dev/null +++ b/variables.list @@ -0,0 +1,8 @@ +NPM_PACKAGE_LOCK_ONLY=false +IGNORE_NPM_ERRORS=true +NPM_FLATTEN_COMPONENTS=false +NPM_SHORT_PURLS=false +NPM_OUTPUT_REPRODUCIBLE=false +NPM_SPEC_VERSION=1.4 +NPM_OUTPUT_FORMAT=json +OUTPUT_DIRECTORY=build From 0b6ca53747cd74bb8324a8473688716bd0ce6df2 Mon Sep 17 00:00:00 2001 From: Cosimo Commisso Date: Sun, 18 Feb 2024 22:59:19 -0500 Subject: [PATCH 3/8] merge with github --- build_docker.sh | 11 ----------- 1 file changed, 11 deletions(-) delete mode 100755 build_docker.sh diff --git a/build_docker.sh b/build_docker.sh deleted file mode 100755 index b59d575..0000000 --- a/build_docker.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/usr/bin/env bash - -echo "building docker image locally..." - -docker build \ - --no-cache \ - --build-arg ARCH=arm64 \ - --tag cyclonedx-npm-pipe:dev \ - . - -echo "finished building docker image..." \ No newline at end of file From 32333bdaec5da76e10cf8cdaa7ada3c14f8e7418 Mon Sep 17 00:00:00 2001 From: Cosimo Commisso Date: Wed, 20 Mar 2024 11:09:29 +0000 Subject: [PATCH 4/8] Merged in optimizeDockerImage (pull request #22) OptimizeDockerImage * optimize Dockerfile * optimize Dockerfile & pipeline --- Dockerfile | 15 ++++++---- bitbucket-pipelines.yml | 63 ++++++++++++++++++++++++++++++++++++----- 2 files changed, 65 insertions(+), 13 deletions(-) diff --git a/Dockerfile b/Dockerfile index 040cefa..50d6469 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,13 +1,16 @@ -FROM node:18-bullseye-slim +FROM node:18-alpine3.19 ARG ARCH -RUN apt-get update \ - && DEBIAN_FRONTEND=noninteractive apt-get -y upgrade \ - && apt-get autoremove -y \ - && rm -rf /var/lib/apt/lists/* +ENV BASH_VERSION="5.2.21-r0" -ENV CYCLONEDX_NPM_VERSION="1.16.1" \ +RUN apk update \ + && apk upgrade \ + && apk --no-cache add bash=${BASH_VERSION} + +SHELL ["/bin/bash", "-c"] + +ENV CYCLONEDX_NPM_VERSION="1.16.2" \ GEN_SBOM_SCRIPT_LOCATION="/opt" ENV PATH="${GEN_SBOM_SCRIPT_LOCATION}:${PATH}" diff --git a/bitbucket-pipelines.yml b/bitbucket-pipelines.yml index 474136c..4267ae8 100644 --- a/bitbucket-pipelines.yml +++ b/bitbucket-pipelines.yml @@ -36,15 +36,43 @@ definitions: script: - echo "Linting Markdown Files" - mdl *.md || echo "Potential mdlint issues found..." + - step: &gen-sbom-for-project + name: gen sbom + image: debian:bookworm-slim + services: + - docker + caches: + - docker + script: + - apt-get update + - DEBIAN_FRONTEND=noninteractive apt-get -y upgrade + - apt-get install -y curl + - curl -sSfL https://raw.githubusercontent.com/anchore/syft/main/install.sh | sh -s -- -b /usr/local/bin v1.0.1 + - docker load --input "${BITBUCKET_REPO_SLUG}.tar" + - mkdir sbom_output + - syft "${BITBUCKET_REPO_SLUG}:local" --output cyclonedx-json@1.4 >> sbom_output/${BITBUCKET_REPO_SLUG}_cyclonedx-sbom.json + artifacts: + - sbom_output/* pipelines: - default: - - parallel: - - step: *build-and-test - - step: *shell-check - - step: *docker-lint - - step: *markdown-lint - - step: *build-docker-image + pull-requests: + '**': + - parallel: + - step: *build-and-test + - step: *shell-check + - step: *docker-lint + - step: *markdown-lint + - step: *build-docker-image + - step: *gen-sbom-for-project + branches: + main: + - parallel: + - step: *build-and-test + - step: *shell-check + - step: *docker-lint + - step: *markdown-lint + - step: *build-docker-image + - step: *gen-sbom-for-project custom: push to Dockerhub (dev): - step: *build-docker-image @@ -63,6 +91,27 @@ pipelines: - variables: - name: PRODUCTION_VERSION - step: *build-docker-image + - stage: + name: OSS Scan + steps: + - step: *gen-sbom-for-project + - step: + name: Scan SBOM + script: + - chmod 777 sbom_output + - pipe: docker://ccideas/sbom-utilities-pipe:1.2.0 + variables: + PATH_TO_SBOM: 'sbom_output/${BITBUCKET_REPO_SLUG}_cyclonedx-sbom.json' + SCAN_SBOM_WITH_BOMBER: 'true' + BOMBER_OUTPUT_FORMAT: 'html' + BOMBER_DEBUG: 'true' + OUTPUT_DIRECTORY: 'sbom_output' + SCAN_SBOM_WITH_SBOMQS: 'true' + SBOMQS_OUTPUT_FORMAT: 'table' + SCAN_SBOM_WITH_OSV: 'true' + OSV_OUTPUT_FORMAT: 'table' + artifacts: + - sbom_output/* - stage: name: Deploy to Prod deployment: Production From 57c8ab3d7057c206251c970f5a0f9420632c30a6 Mon Sep 17 00:00:00 2001 From: Cosimo Commisso Date: Wed, 19 Jun 2024 10:24:56 +0000 Subject: [PATCH 5/8] Merged in May2024_Updates (pull request #23) June 2024 Updates * fix code coverage * fix code coverage --- .gitignore | 3 +++ Dockerfile | 6 +++--- bitbucket-pipelines.yml | 1 + 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index 3eb4afb..baa5ef1 100644 --- a/.gitignore +++ b/.gitignore @@ -169,3 +169,6 @@ output/ package.json package-lock.json node_modules/ + +# tests +sbom_output/ diff --git a/Dockerfile b/Dockerfile index 50d6469..3d8cbd7 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,8 +1,8 @@ -FROM node:18-alpine3.19 +FROM node:18-alpine3.20 ARG ARCH -ENV BASH_VERSION="5.2.21-r0" +ENV BASH_VERSION="5.2.26-r0" RUN apk update \ && apk upgrade \ @@ -10,7 +10,7 @@ RUN apk update \ SHELL ["/bin/bash", "-c"] -ENV CYCLONEDX_NPM_VERSION="1.16.2" \ +ENV CYCLONEDX_NPM_VERSION="1.19.0" \ GEN_SBOM_SCRIPT_LOCATION="/opt" ENV PATH="${GEN_SBOM_SCRIPT_LOCATION}:${PATH}" diff --git a/bitbucket-pipelines.yml b/bitbucket-pipelines.yml index 4267ae8..739497f 100644 --- a/bitbucket-pipelines.yml +++ b/bitbucket-pipelines.yml @@ -2,6 +2,7 @@ definitions: steps: - step: &build-docker-image name: 'Build Docker Image' + size: 2x script: - IMAGE_NAME=cyclonedx-npm-pipe - docker build --build-arg ARCH=amd64 --tag "${IMAGE_NAME}:local" . From 9e768a971f1ed4b2498bb80fa81b6fb153aa4869 Mon Sep 17 00:00:00 2001 From: Cosimo Commisso Date: Wed, 19 Jun 2024 06:30:15 -0400 Subject: [PATCH 6/8] update version in README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b81a017..0b8ad9b 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ pipelines: caches: - node script: - - pipe: docker://ccideas/cyclonedx-npm-pipe:1.3.0 + - pipe: docker://ccideas/cyclonedx-npm-pipe:1.5.0 variables: IGNORE_NPM_ERRORS: 'true' # optional NPM_SHORT_PURLS: 'true' # optional From 6997b4e3286a31b8a45c1969350884e978f4aad0 Mon Sep 17 00:00:00 2001 From: Cosimo Commisso Date: Fri, 13 Dec 2024 11:49:31 +0000 Subject: [PATCH 7/8] Merged in dec_2024_updates (pull request #24) Update @cyclonedx/cyclonedx-npm to 1.19.3 * Update @cyclonedx/cyclonedx-npm to 1.19.3 * Update sbom gen pipeline --- Dockerfile | 9 ++++----- Makefile | 2 +- bitbucket-pipelines.yml | 4 ++-- variables.list | 2 +- 4 files changed, 8 insertions(+), 9 deletions(-) diff --git a/Dockerfile b/Dockerfile index 3d8cbd7..6fa95b2 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,16 +1,15 @@ -FROM node:18-alpine3.20 +FROM node:22-alpine3.20 ARG ARCH -ENV BASH_VERSION="5.2.26-r0" - +# hadolint ignore=DL3018 RUN apk update \ && apk upgrade \ - && apk --no-cache add bash=${BASH_VERSION} + && apk --no-cache add bash SHELL ["/bin/bash", "-c"] -ENV CYCLONEDX_NPM_VERSION="1.19.0" \ +ENV CYCLONEDX_NPM_VERSION="1.19.3" \ GEN_SBOM_SCRIPT_LOCATION="/opt" ENV PATH="${GEN_SBOM_SCRIPT_LOCATION}:${PATH}" diff --git a/Makefile b/Makefile index ff8f596..a458aa0 100644 --- a/Makefile +++ b/Makefile @@ -55,7 +55,7 @@ scan-project: export NPM_FLATTEN_COMPONENTS=false && \ export NPM_SHORT_PURLS=false && \ export NPM_OUTPUT_REPRODUCIBLE=false && \ - export NPM_SPEC_VERSION=1.4 && \ + export NPM_SPEC_VERSION=1.6 && \ export NPM_OUTPUT_FORMAT=json && \ $(GEN_SBOM) diff --git a/bitbucket-pipelines.yml b/bitbucket-pipelines.yml index 739497f..2eae322 100644 --- a/bitbucket-pipelines.yml +++ b/bitbucket-pipelines.yml @@ -48,10 +48,10 @@ definitions: - apt-get update - DEBIAN_FRONTEND=noninteractive apt-get -y upgrade - apt-get install -y curl - - curl -sSfL https://raw.githubusercontent.com/anchore/syft/main/install.sh | sh -s -- -b /usr/local/bin v1.0.1 + - curl -sSfL https://raw.githubusercontent.com/anchore/syft/main/install.sh | sh -s -- -b /usr/local/bin v1.18.0 - docker load --input "${BITBUCKET_REPO_SLUG}.tar" - mkdir sbom_output - - syft "${BITBUCKET_REPO_SLUG}:local" --output cyclonedx-json@1.4 >> sbom_output/${BITBUCKET_REPO_SLUG}_cyclonedx-sbom.json + - syft "${BITBUCKET_REPO_SLUG}:local" --output cyclonedx-json@1.6 >> sbom_output/${BITBUCKET_REPO_SLUG}_cyclonedx-sbom.json artifacts: - sbom_output/* diff --git a/variables.list b/variables.list index 8a1db5a..1e62a80 100755 --- a/variables.list +++ b/variables.list @@ -3,6 +3,6 @@ IGNORE_NPM_ERRORS=true NPM_FLATTEN_COMPONENTS=false NPM_SHORT_PURLS=false NPM_OUTPUT_REPRODUCIBLE=false -NPM_SPEC_VERSION=1.4 +NPM_SPEC_VERSION=1.6 NPM_OUTPUT_FORMAT=json OUTPUT_DIRECTORY=build From f96caef7f84aa5a5ea03c1f56d1245e8dc599a89 Mon Sep 17 00:00:00 2001 From: Cosimo Commisso Date: Sat, 14 Dec 2024 17:38:44 -0500 Subject: [PATCH 8/8] v1.6.0 release --- README.md | 2 +- pipe.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 0b8ad9b..48b9a61 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ pipelines: caches: - node script: - - pipe: docker://ccideas/cyclonedx-npm-pipe:1.5.0 + - pipe: docker://ccideas/cyclonedx-npm-pipe:1.6.0 variables: IGNORE_NPM_ERRORS: 'true' # optional NPM_SHORT_PURLS: 'true' # optional diff --git a/pipe.yml b/pipe.yml index 5ce124d..3df6069 100644 --- a/pipe.yml +++ b/pipe.yml @@ -1,5 +1,5 @@ name: CycloneDX node/npm sBOM Generator -image: ccideas/cyclonedx-npm-pipe:1.3.0 +image: shiftleftcyber/cyclonedx-npm-pipe:1.6.0 category: Security description: Generates a CycloneDX compliant Software Bill of Materials for a node/npm project repository: https://bitbucket.org/ccideas1/cyclonedx-npm-pipe/src/main/