Extend your scan images
Harness maintains a set of scan images for popular tools such as Semgrep, OWASP, SonarQube, Snyk, and Veracode. Harness seeks to keep these images as small and as lightweight as possible, and to minimize the number of vulnerabilities in each image. This means that you might want to extend an image with additional layers to scan a specific type of target. You can easily add packages such as Node, Ruby, and Maven to a scanner image and then run the image in STO.
Important notes
-
This topic assumes that you are familiar with containerization, Dockerfiles, and best practices for building container images.
-
Harness supports the CI and STO images in the Harness project on GCR. You can extend these images to support your own uses cases, but custom images are not supported by Harness.
-
Harness recommends that you add the only the package and files required for your specific use case, and that you thoroughly test and scan your custom images for vulnerabilities and other issues before you deploy them in your production environment.
Workflow description
The following steps describe the general workflow.
-
Create a Dockerfile that specifies the base Harness image and the packages and files that you want to.
-
Build your custom image and push it to your image registry.
-
In your pipeline, add a Run step that uses your customized image to scan the target and save the results in a shared folder.
-
Add a Security or Security Test step to ingest the results.
Hands-on example: add yarn and pnpm to an OWASP image
Suppose you're a security engineer and you want to start using STO and OWASP Dependency Check to scan and validate the code repositories maintained by your organization. One development team uses Yarn and another team uses PNPM. Your initial scans are failing because the base image doesn't include these packages.
Extend the base image with the required packages
The first step is to create a Dockerfile that adds these packages to the OWASP base image.
Dockerfile example
# STEP 1
# Specify the STO scanner image where you want to add your certificates
# For a list of all images in the Harness Container Registry, run the following:
# curl -X GET https://app.harness.io/registry/_catalog
FROM harness/owasp-dependency-check-job-runner:latest as scanner
RUN apt-get update && apt-get install -y \
ca-certificates \
curl
# STEP 2
# Add the packages and files you need to the image
# Install sudo
RUN apt install sudo
# Install npm
# https://askubuntu.com/questions/720784/how-to-install-latest-node-inside-a-docker-container
RUN apt update
RUN printf 'y\n1\n\1n' | apt install nodejs
RUN apt install -y npm
# Make sure Node is up-to-date
# https://askubuntu.com/questions/426750/how-can-i-update-my-nodejs-to-the-latest-version
RUN sudo npm cache clean -f
RUN sudo npm install -y -g n
RUN sudo n stable
# Install yarn
# https://linuxize.com/post/how-to-install-yarn-on-ubuntu-20-04/
RUN curl -o- -L https://yarnpkg.com/install.sh | bash
RUN sudo apt install yarn -y
ENV PATH="/root/.yarn/bin:$PATH"
# Install pnpm
# https://vsys.host/how-to/how-to-install-pnpm-on-ubuntu-22-04
# https://github.com/pnpm/pnpm/issues/5103
RUN SHELL="bash:$SHELL"
RUN wget -qO- https://get.pnpm.io/install.sh | ENV="$HOME/.bashrc" SHELL="$(which bash)" bash -
RUN npm install -g pnpm
ENV PATH="~/.local/share/pnpm:$PATH"
Build and push the customized image
Once you're satisfied with the customized image, you can push it to your image registry.
Add a shared folder to the pipeline stage
Now you're ready to set up your pipeline. First, you add a shared path for the scan results. This is a standard good practice for ingestion workflows.
- Visual
- YAML
-
In your Harness pipeline, go to the stage where you want to run the scan and select Overview.
-
Add a shared path such as
/shared/scan_results
.
Add a shared path for the stage as shown in the following YAML.
- stage:
name: owasp-scan
identifier: owaspscanwithbinaries
description: ""
type: SecurityTests
spec:
sharedPaths:
- /shared/scan_results
Add a Run step to scan the target with the custom image
Now add a Run step that pulls your custom image, runs the dependency-check
binary on the specified target, and saves the scan results to the shared folder you created.
- Visual
- YAML
Add a Run that pulls your custom image, runs the dependency-check
binary on the specified target, and saves the scan results to the shared folder you created.
Configure the step as follows:
-
Optional Configuration > Container Registry: A connector to the registry where you stored your custom OWASP image.
-
Optional Configuration > Image: Your custom image name and tag, such as
myimageregistry/owaspcustom:latest
-
Command: The
dependency-check
CLI command and arguments, as well as any other commands you want to run.The following
dependency-check
arguments are required in this case:--scan /harness
--format JSON
--out <scan_results_output_path_and_filename>
--yarn <path_to_yarn>
--pnpm <path_to_pnpm>
Here's an example:
command: |-
yarn --version
pnpm --version
/app/dependency-check/bin/dependency-check.sh \
--scan /harness \
--format JSON \
--out /shared/scan_results/owasp.json \
--yarn /root/.yarn/bin/yarn \
--pnpm /usr/local/bin/pnpm \
Add a Run
step that pulls your custom image, runs the dependency-check
binary on the specified target, and saves the scan results to the shared folder you created.
Configure the step as follows:
-
connectorRef:
A connector to the registry where you stored your custom OWASP image. -
image:
Your custom image name and tag, such asmyimageregistry/owaspcustom:latest
. -
command:
Thedependency-check
CLI command and arguments, as well as any other commands you want to run.The following
dependency-check
arguments are required in this case:--scan /harness
--format JSON
--out <scan_results_output_path_and_filename>
--yarn <path_to_yarn>
--pnpm <path_to_pnpm>
Here's an example:
- step:
type: Run
name: owasp-scan-with-binaries
identifier: owasp-scan-with-binaries
spec:
connectorRef: YOUR_IMAGE_REGISTRY_CONNECTOR_ID
image: YOUR_IMAGE_REGISTRY_NAME/owaspandnpmandyarn:latest
shell: Sh
command: |-
yarn --version
pnpm --version
/app/dependency-check/bin/dependency-check.sh \
--yarn /root/.yarn/bin/yarn \
--pnpm /usr/local/bin/pnpm \
--scan /harness \
--prettyPrint \
--format JSON \
--out /shared/scan_results/output.json
# --project owasp_scan_with_yarn_and_pnpm
# --disableNodeAudit \
# --enableExperimental \
# --noupdate\
# echo "SCAN RESULTS FILE ============================"
# cat /shared/scan_results/output.json
imagePullPolicy: Always
Add an OWASP ingest step
Finally, she adds an OWASP step to ingest the results from the shared folder.
- Visual
- YAML

- step:
type: Owasp
name: owasp_ingest_results
identifier: Owasp_2
spec:
mode: ingestion
config: default
target:
type: repository
detection: auto
advanced:
log:
level: info
ingestion:
file: /shared/scan_results/output.json