Skip to main content

Scan a NodeJS App for security vulnerabilities

DevSecOps Background

The DevSecOps movement is all about shifting left; empowering the development teams to make more hygienic decisions. With the pace and velocity that engineering teams are creating changes/features, in days gone by, security could be seen as an afterthought in the SDLC. Today, modern teams and organizations try to disseminate application security expertise throughout the development pipeline and security decisions and posture are being educated upfront during development.

There are a few categories of application centric security tools out there. The first is SAST or Static Application Security Testing. SAST tools typically inspect application code and configuration for known good and bad patterns. The second type, DAST or Dynamic Application Security Testing, tool will try to perform an exploit on your behalf. DAST tools typically run against running applications, having the ability to take into compensating controls of the infrastructure. Third are RASPs or Runtime Application Self Protection Platforms are dependencies deployed with your application which will analyze calls in and out of the application e.g method calls.

Setting Up Your First Automatable Security Scan

In this example, we will be using OWASP Dependency Check (SAST tool) which will match project dependencies against vulnerability databases such as the National Vulnerability Database (NVD). We will be scanning against OWASP’s own NodeGoat project, which is a purpose-built vulnerable Node application to teach security concepts. You can replace NodeGoat with an application of your choice.


Install Delegate

Harness will facilitate the running of the security scan against your codebase. A workload runner, e.g. a Harness Delegate will need to be installed into a Kubernetes cluster of your choice. The first step is to request a Harness Security Test Orchestration Account and install a Harness Delegate.

Install Delegate

Install Harness Delegate on Kubernetes or Docker

What is Harness Delegate?

Harness Delegate is a lightweight worker process that is installed on your infrastructure and communicates only via outbound HTTP/HTTPS to the Harness Platform. This enables the Harness Platform to leverage the delegate to execute the CI/CD and other tasks on your behalf, without any of your secrets leaving your network.

You can install the Harness Delegate on either Docker or Kubernetes.

Install Harness Delegate

Create a new delegate token

Log in to the Harness Platform and go to Account Settings -> Account Resources -> Delegates. Select the Tokens tab. Select +New Token, and enter a token name, for example firstdeltoken. Select Apply. Harness Platform generates a new token for you. Select Copy to copy and store the token in a temporary file. You will provide this token as an input parameter in the next installation step. The delegate will use this token to authenticate with the Harness Platform.

Get your Harness account ID

Along with the delegate token, you will also need to provide your Harness accountId as an input parameter during delegate installation. This accountId is present in every Harness URL. For example, in the following URL:

6_vVHzo9Qeu9fXvj-AcQCb is the accountId.

Now you are ready to install the delegate on either Docker or Kubernetes.


Ensure that you have access to a Kubernetes cluster. For the purposes of this tutorial, we will use minikube.

Install minikube

  • On Windows:
choco install minikube
  • On macOS:
brew install minikube

Now start minikube with the following config.

minikube start --memory 4g --cpus 4

Validate that you have kubectl access to your cluster.

kubectl get pods -A

Now that you have access to a Kubernetes cluster, you can install the delegate using any of the options below.

Install the Helm chart

As a prerequisite, you must have Helm v3 installed on the machine from which you connect to your Kubernetes cluster.

You can now install the delegate using the delegate Helm chart. First, add the harness-delegate Helm chart repo to your local Helm registry.

helm repo add harness-delegate
helm repo update
helm search repo harness-delegate

You can see that there are two Helm charts available. We will use the harness-delegate/harness-delegate-ng chart in this tutorial.

NAME                                    CHART VERSION   APP VERSION DESCRIPTION                                
harness-delegate/harness-delegate-ng 1.0.8 1.16.0 A Helm chart for deploying harness-delegate

Now we are ready to install the delegate. The following command installs/upgrades firstk8sdel delegate (which is a Kubernetes workload) in the harness-delegate-ng namespace using the harness-delegate/harness-delegate-ng Helm chart.

helm upgrade -i firstk8sdel --namespace harness-delegate-ng --create-namespace \
harness-delegate/harness-delegate-ng \
--set delegateName=firstk8sdel \
--set delegateToken=PUT_YOUR_DELEGATE_TOKEN_HERE \
--set delegateDockerImage=harness/delegate:23.02.78306 \
--set replicas=1 --set upgrader.enabled=false

The above command uses the default values.yaml located in the delegate-helm-chart GitHub repo. If you want change one or more values in a persistent manner instead of the command line, you can download and update the values.yaml file as per your need. You can use the updated values.yaml file as shown below.

helm upgrade -i firstk8sdel --namespace harness-delegate-ng --create-namespace \
harness-delegate/harness-delegate-ng \
-f values.yaml \
--set delegateName=firstk8sdel \
--set delegateToken=PUT_YOUR_DELEGATE_TOKEN_HERE \
--set delegateDockerImage=harness/delegate:23.02.78306 \
--set replicas=1 --set upgrader.enabled=false

Replace the PUT_YOUR_MANAGER_HOST_AND_PORT_HERE variable with the Harness Manager Endpoint noted below. For Harness SaaS accounts, you can find your Harness Cluster Location on the Account Overview page under the Account Settings section of the left navigation. For Harness CDCE, the endpoint varies based on the Docker vs. Helm installation options.

Harness Cluster LocationHarness Manager Endpoint on Harness Cluster
SaaS prod-1
SaaS prod-2
SaaS prod-3
CDCE Dockerhttp://<HARNESS_HOST> if Docker Delegate is remote to CDCE or http://host.docker.internal if Docker Delegate is on same host as CDCE
CDCE Helmhttp://<HARNESS_HOST>:7143 where HARNESS_HOST is the public IP of the Kubernetes node where CDCE Helm is running

Verify delegate connectivity

Select Continue. After the health checks pass, your delegate is available for you to use. Select Done and verify your new delegate is listed.

Helm chart & Terraform Helm provider

Delegate Available

Kubernetes manifest

Delegate Available


Delegate Available

You can now route communication to external systems in Harness connectors and pipelines by selecting this delegate via a delegate selector.


The delegate installer provides troubleshooting information for each installation process. If the delegate cannot be verified, select Troubleshoot for steps you can use to resolve the problem. This section includes the same information.

Harness asks for feedback after the troubleshooting steps. You are asked, Did the delegate come up?

If the steps did not resolve the problem, select No, and use the form to describe the issue. You'll also find links to Harness Support and to Delegate docs.

Use the following steps to troubleshoot your installation of the delegate using Helm.

  1. Verify that Helm is correctly installed:

    Check for Helm:


    And then check for the installed version of Helm:

    helm version

    If you receive the message Error: rendered manifests contain a resource that already exists..., delete the existing namespace, and retry the Helm upgrade command to deploy the delegate.

    For further instructions on troubleshooting your Helm installation, go to Helm troubleshooting guide.

  2. Check the status of the delegate on your cluster:

    kubectl describe pods -n <namespace>
  3. If the pod did not start, check the delegate logs:

    kubectl logs -f <harnessDelegateName> -n <namespace>

    If the state of the delegate pod is CrashLoopBackOff, check your allocation of compute resources (CPU and memory) to the cluster. A state of CrashLoopBackOff indicates insufficent Kubernetes cluster resources.

  4. If the delegate pod is not healthy, use the kubectl describe command to get more information:

    kubectl describe <pod_name> -n <namespace>

Security Tests Pipeline

With the Delegate installation out of the way, next is to create a Pipeline that will just run your security scan. Harness runs off the concept of Projects which are logical groupings of resources. The Default Project which is created for you upon account signup can be used for this example.

Creating Your First STO Pipeline

To get started with your security scan that can be run in a pipeline, head to the Security Tests module and then Pipelines.

Click + Create Pipeline then give a name to the new Pipeline.

  • Name: my_security_scan
  • Setup: Inline

Inline Storage

Click start and you will be brought to a canvas to start adding in steps into your Pipeline. Click + Add Stage and select Security Tests.

Add Sec Stage

In the Stage configuration, name the Security Stage and configure connectivity to OWASP’s of your repository which houses the application code base. Harness can clone and execute a scan on your code base.

  • Stage Name: owasp_scan
  • Clode Codebase: selected (true)

About Stage

In the Connector section, set up a new GitHub Connector which will allow connectivity to GitHub.

GitHub Connector Configuration

In the connector dropdown, click + New Connector and select the type as GitHub.

Name: owasp_gh

Add GitHub Connector

The repository hosting NodeGoat is located at In the details section, can wire this address in.

Add GitHub Address

Click Continue to add the credentials.

GitHub Personal Access Tokens

GitHub as of 2021 requires token authentication e.g. no more passwords for git operations. You’ll need to create a GitHub Personal Access Token to ensure that the pipeline can access the public repository.

If you have not created a Personal Access Token before. GitHub -> Settings -> Developer Settings -> Personal Access Tokens

  • Name: harness
  • Scopes: repo -> public_repo [or if you are using a private repo or want to enable Harness API Access, scope appropriately]
  • Expiration: 30 days

GitHub PAT

Make sure to copy down the token that is generated.

In the Credentials Section, enter your User Name and your Personal Access Token which will be stored as a Harness Secret.

Add GitHub Creds

Select Continue and select where you want the Git Commands to be run. Can select the Harness Delegate that you have installed to run the Git Operations. Once selected, Harness will run a quick validation.

Back in the About your Stage section, the Git Connector should be there and can provide the Repository Name, “NodeGoat”.

Complete Aboute Stage

Now click Set Up Stage and we will go through filling in the necessary pieces.

Blank Scan Template

The first step is to wire in a Docker-in-Docker [DIND] image to run the scan.

Configuring Your Security Pipeline

In the + Add Service Dependency Section, configure a Service Dependency.

  • Dependency Name: dind
  • Container Registry: Harness Docker Connector [this will be there by default, linking up to public Docker Hub]
  • Image: docker:dind
  • Privileged: True

Service Dependency

Click Apply Changes, and now can configure the Infrastructure and Execution steps.

DIND Wired

Click on Overview, then add a shared path of '/var/run` to execute the tests in.


Click Continue to wire in your Kubernetes cluster to run and execute the scan.

Adding a Kubernetes Cluster

With Harness, you can leverage the Harness Delegate that is running in Kubernetes to spin up and down workloads on your behalf.

In the Kubernetes Cluster section, add a New Connector.

Add K8s Cluster

  • Name: sto-cluster
  • Details: Use credentials of specific Harness Delegate

Use K8s Cluster

Click Continue and select the Harness Delegate that is running on your Kubernetes cluster. With that selected, connectivity validation will occur. Now specify a Kubernetes Namespace to leverage, in this case “default” is fine.

Configured K8s

Moving on to the Execution, add a Security Step from the Step Library.

Configuring Security Step

Step Library

Harness STO orchestrates multiple security scanning tools using scan steps. Setting up each scan step requires details such as the scanner name and the target to scan. You specify these requirements using key-value pairs like this:

  • policy_type: orchestratedScan
  • scan_type: repository
  • product_name: owasp
  • product_config_name: default
  • repository_project: nodegoat [or what project you have selected]
  • repository_branch: <+codebase.branch>

Scan Config

With those filled out, click Apply Changes and you are now ready to run the scan.

Complete Pipeline

Running Your Security Scan Pipeline

Click Save to save your Pipeline Configuration. In “my_security_scan”, click Run.

Security Tests -> Pipelines -> my_security_scan

Save and Run

Per the GitHub Project, the default branch is called master. Can specify master as the Git Branch.

Run Branch

Click Run Pipeline, and your security scan will be executed against the codebase. This execution and scan can take 2-3 minutes to complete.


Once executed, you can take a look at the Scan Results. Over time as you make improvements, the scan results will change. Harness STO can help prioritize the criticality of security vulnerabilities for you.

Security Tests -> Security Tests -> latest my_security_scan


Congratulations on your first security scan placement inside a Pipeline with Harness STO. Harness can help prioritize issues and provide information on how to investigate and fix specific issues.