Node.js agent with Docker

  • Updated

Agent installation guide

Overview

 

This guide offers examples for using Contrast Security’s Node.js agent with Docker. We encourage you to take this guide, make it your own, and distribute it to teams who both need to instrument Node applications and manage them through Docker. 

The main portion of the guide details the most popular methods customers use to instrument Node applications contained in Docker and see security data in Contrast.

There is also a lab section that describes how to instrument a sample Node application with known vulnerabilities called OWASP Juice Shop. It’s a good way to learn before proceeding with your own applications. You can instrument OWASP Juice Shop through Docker and see security data for this application in Contrast using the source code samples section at the end of this guide.

 

Main steps

Update the application’s Dockerfile

  1. Add the Contrast agent to the application
  2. Create an agent configuration file
  3. Update the start command to use the agent

Instrument your application

  1. Start up with Contrast enabled 

Supported technologies

Before you begin, please be sure Contrast supports your preferred tools and environments for Node.js:
Supported technologies for Node.js 

This guide assumes you have:

  • Some familiarity with DevOps practices and how Docker works
  • The information needed to connect the Contrast Node.js agent to the Contrast dashboard: Install Node.js agent with npm
  • Downloaded and started the agent before running your applications

Instructions

Begin by updating the Dockerfile for your application.

 


1. Add the Contrast Node.js agent

Here are two options to add the Contrast agent and basic configuration to a Docker image. Choose the one that works best for you.

 

Option 1: Add to the application

The preferred approach is to add the Contrast agent to your application during development. This way, the agent will be included with your app’s package.json 

  • You can use a typical “npm install” command to populate the agent into your pipelines and container images.
npm install @contrast/agent

 

Option 2: Add to a Dockerfile

If option 1 doesn’t work or you prefer to maintain separate images for the application--with and without the Contrast agent--you can add the Contrast agent at container build time. To do this:

  • Use the same npm install command to add the agent into your existing Dockerfile
  • Or add it into a new Dockerfile that uses your application’s image as a base image

 


2. Configure the agent

There are different values you can use to configure Contrast agents. This is the order of precedence. Each level overrides the next, and 1 is highest.

  1. Corporate rule (e.g., expired license overrides assess.enable)
  2. Environment variable value
  3. YAML configuration file value
  4. Contrast UI value
  5. Default value

The order of precedence is explained more here:
Order of precedence

We recommend a mixed approach:

  • Keep the common configuration in the YAML file so it can be placed in the base image
  • Use environment variables for application-specific configuration values

Common configuration

This approach keeps a core set of configurations in the YAML file. Here are a few examples of common configurations. You can modify these, as desired. 

  • Redirect logging to console output
  • Proxy configuration, if any
  • Performance tuning options to limit agent activity

To do this:

  1. Add base configuration options that will remain static.
api: 
 url: https://app.contrastsecurity.com
agent:
 service: 
grpc: true
 logger: 
   path: /proc/1/fd/1
    level: INFO
  1. Next, create and copy the YAML file into the base image. Let's assume the YAML file is saved in /app/contrast_security.yaml, which is the base directory for your app in the image.
  2. Copy the edited YAML file into the Dockerfile
COPY WORKSPACE/contrast_security.yaml /app/contrast_security.yaml

 

Application-specific configuration

This allows additional options, per application. To set an application-specific configuration, use environment variables. Note: these may be specified using ENV statements in the Dockerfile or passed to the Docker run command with the -e option as appropriate.

  • Application metadata: Specify application-specific metadata
    CONTRAST__APPLICATION__METADATA
  • Application name: Specify the application name reported to Contrast CONTRAST__APPLICATION__NAME
  • Application session metadata: Send application details like build number, version, GIT hash, etc.
    CONTRAST__APPLICATION__SESSION_METADATA

For more, see Contrast documentation: View session metadata

  • Application group: Specify the application access group for this application during onboarding. NOTE: Application access groups have to be created first in Contrast. CONTRAST__APPLICATION__GROUP
  • Server environment: specify in which environment the application is running. Valid values for this configuration are: Development, QA and Production. CONTRAST__SERVER__ENVIRONMENT

 


3. Update the start command to use the agent

To enable Contrast, you will need to preload the Contrast agent when you launch your application. Normally, you do this in the Dockerfile’s CMD statement, but you can also use an npm script defined in the package.json.

For example, if your application normally starts with...

CMD [“node”, “app”]

...you can use the following command to enable Contrast:

CMD [“node”, “-r”, “@contrast/agent”, “app”]

If the Contrast Node agent was installed via a local node-contrast-#.#.#.tgz file.  The entrypoint will need to be updated to CMD [“node”, “-r”, “node_contrast/bootstrap”, “app”]

 

 

 

 


4. Instrument your application

When the agent starts, it will try to connect to Contrast with the URL and agent credentials from step 2. To protect the agent credentials, utilize the Docker secret and pass them as environment variables during deployment time. Here is an example of the Docker run command:

docker run -e CONTRAST__API__URL=<value> -e CONTRAST__API__API_KEY=<value> -e CONTRAST__API__SERVICE_KEY=<value> -e CONTRAST__API__USER_NAME=<value> -e CONTRAST__SERVER__ENVIRONMENT=<value> -p 3000:3000 image_with_contrast

 

You can verify that Contrast is running by seeing messages in the container log, such as:

@contrast/agent 2.16.8
--------------------------------------
2020-07-20T19:05:14.407Z INFO contrast-service: BUILD {"progname": "Contrast Service", "version": "2.8.1", "buildTime": ""}
2020-07-20T19:05:14.407Z INFO Building timer for orphan request cleanup {"progname": "Contrast Service", "cleanupMs": 5000}
2020-07-20T19:05:14.408Z INFO Building timer for orphan app cleanup {"progname": "Contrast Service", "time": 5000}
2020-07-20T19:05:14.450Z INFO Creating New Application Server {"progname": "Contrast Service", "uuid": "96299b72-f867-4354-b9c9-1eb23511cb8a", "serverName": "bc1bd6e5cd3a", "clientId": "1", "pid": 1}
2020-07-20T19:05:14.450Z WARN Failed to initialize secure client, falling back to insecure client {"progname": "Contrast Service"}
2020-07-20T19:05:15.473Z INFO setting new server features for context{"progname": "Contrast Service", "uuid": "96299b72-f867-4354-b9c9-1eb23511cb8a", "serverName": "bc1bd6e5cd3a"}
2020-07-20T19:05:15.474Z ERROR Error setting up CEF syslog {"progname": "Contrast Service", "err": "open /juice-shop/security.log: permission denied"}
2020-07-20T19:05:15.475Z INFO starting event scanner {"progname": "Contrast Service", "report": {}}
2020-07-20T19:05:15.486Z INFO Creating new application {"progname": "Contrast Service", "uuid": "96299b72-f867-4354-b9c9-1eb23511cb8a", "serverName": "bc1bd6e5cd3a", "appName": "juiceshop-guide", "language": "Node", "clientId": "1", "pid": 1}
2020-07-20T19:05:15.486Z INFO AppCreate: creating and initializing new application {"progname": "Contrast Service", "uuid": "96299b72-f867-4354-b9c9-1eb23511cb8a", "server_name": "bc1bd6e5cd3a", "app_name": "juiceshop-guide", "app_lang": "Node", "client_id": "1", "pid": 1}
2020-07-20T19:05:15.921Z INFO setting new application settings {"progname": "Contrast Service", "uuid": "96299b72-f867-4354-b9c9-1eb23511cb8a", "serverName": "bc1bd6e5cd3a", "appName": "juiceshop-guide", "language": "Node"}
2020-07-20T19:05:15.922Z INFO Setting session id on app context: {"progname": "Contrast Service", "uuid": "96299b72-f867-4354-b9c9-1eb23511cb8a", "clientid": "1", "appname": "juiceshop-guide", "applang": "Node", "apppath": "/juice-shop/package.json", "sessionid": "cd0b271e66974162bf5fcca8b32e37b1"}
Entering main at /juice-shop/app
info: All dependencies in ./package.json are satisfied (OK)
...

 

Source code example: OWASP Juice Shop

Use this GitHub repository to learn how to first. It contains a lab that walks you through different ways Node.js applications delivered via Docker can be instrumented for security monitoring with Contrast.
https://github.com/Contrast-Security-OSS/contrastsecurity-node-docker-onboarding-guide-sample-project

FAQ

  1. How much will the Node.js agent affect performance for my applications? You will need to increase available CPU and memory for your applications
    System requirements for the Node.js agent
  2. Is there any impact on application startup when running with Node.js?
    Does the Node.js agent affect my application's performance?
  3. How do I handle connection errors in the Contrast log?
    Connectivity Issues with the Node Agent
  4. Will the new version of a Contrast agent work with older versions of Contrast? Or vice-versa? It may work, but it is not recommended. Always update both.
    Install an agent

Known Issues

 

 

 

Was this article helpful?

0 out of 0 found this helpful

Have more questions? Submit a request