Securing NodeJs Components with RetireJs

Sang DavidSang David
13 min read

Project Description

Implement RetireJs in a GitLab CI/CD Pipeline for a NodeJS project. Follow the following steps detailed below:

  1. Create a new repository on your GitLab.

  2. Define stages in your YAML file.

  3. Create a job under the build stage to set up RetireJS.

  4. Scan the NodeJs project with RetireJs.

  5. The job must fail the build stage if issues are found.

  6. The job must save the artifact on the CI server for further processing in a machine-readable format such as JSON.

  7. Ensure you do not just use exit 1 to achieve job failure. Let the Job fail as a result of vulnerabilities discovered.

Summary of Project

The project achieves the goal of automating dependency security scanning in a NodeJS project within a GitLab CI/CD pipeline. It ensures build failures upon detection of vulnerabilities and provides machine-readable results for further action.

Target Audience

This document is for the following audiences:

  • DevOps/DevSecOps Engineers: Senior and Junior DevSecOps Professionals are responsible for setting up and maintaining CI/CD pipelines and ensuring the security and reliability of software deployments.

  • Software Developers: NodeJs Developers who are proactive about security and want to automate vulnerability detection in their projects. Since the methods are transferable, other Developers can also use this resource to deploy in their chosen stack.

  • Technical Leads and Engineering Managers: Individuals responsible for the technical direction of their teams and ensuring security best practices are followed.

  • Technical Writers and Bloggers: Individuals looking for content ideas related to DevSecOps, SCA, Security, and CI/CD.

  • Project Managers: Those who want to understand the security measures being implemented in their projects.

  • Individuals Evaluating Security Tools

This document assumes that you have an understanding of the following;

  • Basic Linux Commands.

  • Basic Software Development concepts.

  • Basic Application security concepts.

  • NodeJs fundamentals.

  • Version control with Git.

  • A general understanding of CI/CD Pipelines.

Scope of this Document

This document covers the following points:

  • Introduction to SCA.

  • Importance of SCA.

  • Implementation of RetireJs to scan a NodeJs Project.

  • Saving Artifacts on the CI Server

  • Interpretation of Artifacts for Audit and Vulnerability Management.

Non-Scope Points

This document doesn’t cover the following points:

  • In-depth study of SCA.

  • In-depth Study of RetireJs.

  • Implementation of other SCA Tools outside RetireJs.

  • In-depth study of NodeJs.

  • In-depth study of YAML.

  • Other CI/CD Tools outside GitLab.

The objective of this Project

The major objectives of this project are to achieve the following:

  • Understand the concept of SCA.

  • Understand how CI/CD Pipelines work in GitLab.

  • Scan a NodeJs Application with RetireJs.

  • Learn to save Artifacts on the CI Server.

  • Interpret artifacts stored in the CI server.

  • Get conversant with YAML syntax.

Definition of Terms

  • NodeJs: An open-source and cross-platform JavaScript runtime environment. It makes it possible to run Web Applications outside the Browser.

  • Open-source components: Libraries and Dependencies that make it possible for a web application to run successfully.

  • CI Server: The CI server or continous integration Server is responsible for automating the build, integration, and testing of code changes. It allows developers to catch issues early and handle them quickly.

  • Artifact: An Artifact in software development is any deliverable associated with a project and is usually stored in the form of a large binary package. Artifacts are large binary packages that are created throughout the development and release process (Mistazidane, 2023).

    Examples can be compiled code, container images, or documentation, that is stored, retrieved, and managed in the artifact repository for use in subsequent stages of the software lifecycle.

  • YAML: YAML is a human-readable data serialization language that is often used for writing configuration files. Depending on whom you ask, YAML stands for yet another markup language or YAML ain’t markup language (a recursive acronym), which emphasizes that YAML is for data, not documents. (What is YAML?, 2023)

Tools and Concepts used

The following tools and concepts were used in the implementation of this project:

  • OWASP Juice-Shop (Juice-Shop): A Vulnerable NodeJs Web Application

  • Git

  • GitLab CI/CD

  • Visual Studio Code (VSCode)

  • Ubuntu Terminal

  • RetireJs

  • YAML

What is SCA?

Software Composition Analysis (SCA) is an application security methodology that examines the open-source and third-party components used in a software project to identify and manage security vulnerabilities, license compliance issues, and code quality concerns. (McGuire, n.d.)

Most modern applications rely on third-party components and dependencies to function. While this open-source code has its benefits, it can also introduce vulnerabilities, malicious code, and other security risks into an application. Software composition analysis (SCA) is a DevSecOps tool for identifying these pieces of external code. SCA can be used to track open-source components, find vulnerabilities, and manage software licenses. (What is Software Composition Analysis (SCA)?, 2023)

How SCA Solutions Work

SCA solutions work in the following thread:

  1. Scan a codebase to identify open-source components.

  2. Document details about each open-source component identified.

  3. Detect vulnerabilities in the versions and licenses of stored open-source components using known CVEs.

  4. Generate a report that contains information on the open-source dependencies used by an application and vulnerabilities found.

  5. This report is used for analysis and auditing by the DevSecOps team.

Why is SCA Important?

By integrating SCA into CI/CD pipelines, developer teams can reduce the rate of exploitable vulnerabilities reaching production systems. Some importance of SCA includes the following:

  • Identifies Security Flaws: SCA identifies known vulnerabilities in the open-source code your project uses, giving you tips on how to fix them before they're exploited.

  • License Compliance: It helps ensure you comply with the licenses of the open-source software you use, avoiding potential legal issues.

  • Enhances Supply Chain Security: SCA gives you visibility into the security of the third-party components your software relies on.

  • Automates Security Checks: SCA automates the process of tracking and analyzing open-source components, saving time and effort.

  • Improves Software Trust: By addressing vulnerabilities and license issues, SCA helps you build more secure and reliable software for your users.

RetireJs (retire) as an SCA Tool

Retire is a scanner engine that scans JavaScript codebase to identify vulnerable open-source code.

Retire is a command line scanner looking for use of known vulnerable js files and node modules in web projects and/or node projects (Npm: Retire, 2024).

After Retire is installed on a system, it is executed to scan the package.json file of NodeJs applications. The Package.json file is a file that contains all installed open-source components used in building a NodeJs application.

Integration of Retire into GitLab CI/CD Pipeline

Integrating security checks early and often in the software development lifecycle (SDLC) is crucial because it allows for the proactive identification and mitigation of vulnerabilities, reducing the cost of fixing issues later and minimizing the risk of security breaches. By incorporating security measures throughout the SDLC, development teams can ensure that security considerations are integral to every stage, from design to deployment.

Integrating security into the SDLC fosters a DevSecOps culture where security is considered a shared responsibility between development and operations teams.

The steps below outline the processes implemented when integrating Retire into the CI/CD Pipeline to scan Open-source components for Juice-shop:

Step 1: Clone Juice-Shop

Clone Juice-shop from GitHub or GitLab using the command below:

git clone git@github.com:juice-shop/juice-shop.git

Step 2: Navigate to Juice-Shop Directory

Navigate to the Juice-Shop directory on your system with the command below:

cd Juice-shop

Step 3: Open Juice-Shop on VSCode

Open Juice-shop on VSCode with the command below:

code .

Step 4: Create the .gitlab-ci.yml Workflow file

Create a new file called .gitlab-ci.yml in the root directory of Juice-shop. This file is used to configure the CI/CD pipeline on GitLab by default. All configuratons for the CI/CD Pipeline are configured in this document. You can use any file creation command you feel comfortable using or use the command below to create the .gitlab-ci.yml file:

touch .gitlab-ci.yml

Step 5: Create a new Code Repository

  1. Create a new GitLab account.

  2. Navigate to repositories and create a new Repository.

  3. Give the repository a name that best suits this project.

  4. Push project to the newly created Repository.

Step 6: Install Retire Js Locally

  1. Install Retire using the command below;
sudo apt update && sudo apt upgrade
sudo apt install retire -g
  1. Verify installation with the command below;
retire -h
  1. After installation is successful, scan with retire in the directory where the package.json file is located. Here are two possible ways to conduct the scan:
retire ./package.json

OR

retire

After either of the commands above is executed, retire automatically downloads CVE database for known vulnerabilities to its cache. It compares identified versions and licenses of open-source components identified in the package.json againsts the database of known vulnerabilties to find issues and vulnerabilities in the NodeJs Application.

It is important to test tools on web applications locally before integrating them into the CI/CD pipeline. This best practice ensures that the tool functions as expected, preventing any issues in the pipeline.

A local test of Juice-shop with retire was successful.

Step 7: Configure the .gitlab-ci.yml file for CI/CD

The .gitlab-ci.yml file specifies the scripts to be executed during the CI/CD pipeline and outlines their scheduling. It also includes additional configuration files and templates, dependencies, caches, and commands.

The Script below is configured to execute and integrate retire into the CI/CD:

stages:
  - build

sca:
  stage: build
  image: node:18
  script:
    - npm install
    - npm install -g retire  # Install Retire

    # Check if Retire is installed
    - retire --help 

    # Run the scan and save results
    - retire --outputformat json --severity high | tee retirejs-results.json || true

    # Check if vulnerabilities exist
    - if grep -q '"results":\[\]' retirejs-results.json; then 
        echo "No vulnerabilities found"; 
      else 
        echo "Vulnerabilities detected"; 
      fi

  artifacts:
    paths:
      - retirejs-results.json
    expire_in: "30 days"

  allow_failure: false

Step 8: Understanding the content of the .gitlab-ci.yml file

It is paramount to understand the content of the .gitlab-ci.yml file. Follow the different sections below for better understanding:

  1. This piece of code defines the different stages to be executed in the CI/CD Pipeline workflow:
stages:
  - build
  1. This piece of code assigns the name sca to the build job. It also defines a context where processes in the build job are defined.
sca:
  stage: build
  ...
  allow_failure: false
  1. This piece of code defines a specific version of the official Node.js Docker image, specifically version 18, which is used as a base for building containers that run Node.js applications:
image: node:18
  1. This section of code defines the contents of the build stage. Each section is explained below:

Install open-source components using npm:

script:
    - npm install

Install retire:

script:
    - npm install #Install all dependencies
    - npm install -g retire  # Install Retire

Check for a succesful retire installation:

script:
    - npm install #Install all dependencies
    - npm install -g retire  # Install Retire

    # Check if Retire is installed
    - retire --help

Scan Juice-shop open-source components against a high severity vulnerabilities and savie the output of the scan in a .json file:

script:
    - npm install #Install all dependencies
    - npm install -g retire  # Install Retire

    # Check if Retire is installed
    - retire --help 

    # Run the scan and save results
    - retire --outputformat json --severity high | tee retirejs-results.json || true

Utilize if statements to verify if the results":[] array is empty, thereby determining whether the open-source components in the package.json file are vulnerable:

script:
    - npm install #Install all dependencies
    - npm install -g retire  # Install Retire

    # Check if Retire is installed
    - retire --help 

    # Run the scan and save results
    - retire --outputformat json --severity high | tee retirejs-results.json || true

    # Check if vulnerabilities exist
    - if grep -q '"results":\[\]' retirejs-results.json; then 
        echo "No vulnerabilities found"; 
      else 
        echo "Vulnerabilities detected"; 
      fi

Step 9: Creating and Storing Artifacts

The piece of code below creates and saves artifacts of the build stage on the GitLab CI:

artifacts:
    paths:
      - retirejs-results.json #Save artifact on the root
    cache:
      - node_modules/ #Cache node_modules folder to avoid re-installation
    expire_in: "30 days" #Artifact expires in 30days
  • The artifact created is called retirejs-results.json.

  • The artifact is saved in the root directory as signified in paths:.

  • Cache the node_modules folder to avoid constant installations in every job.

  • The artifact is set to expire in 30 days as signified in expire_in:.

Step 10: allow_failure: true

The following piece of code indicates that if the build job fails, the entire pipeline fails.

 allow_failure: false

Step 11: Push Juice-shop to GitLab

After all modifications are implemented successfully, push Juice-shop to your GitLab to start monitoring the efficiency of the CI/CD Pipeline. Use git commands below for the push process:

git commit -am "Your Commit message"
git push origin the-name-of-your-branch

Step 12: Monitor CI/CD Pipeline logs

  • Inspect Pipeline for errors and failed jobs.

  • Inspect Logs to ensure all scripts and processes in the build job are successfully executed.

  • Verify that artifacts are saved on the CI server without any errors.

The Screenshots below describe a successful Job with an artifact stored in the CI server:

Here is a screenshot describing the CI/CD Pipeline executed step by step:

Interpreting the Artifact for Security Actions

Updating open-source components in DevSecOps and DevOps is crucial for several reasons, primarily to address security vulnerabilities, prevent exploitation by malicious actors, improve software stability, and enhance functionality. Outdated dependencies can expose applications to known security flaws.

Automated dependency updates, while beneficial, should be approached with caution due to potential breaking changes. Thus to avoid that, we employ the SCA tools like retire to give us a breakdown of identified vulnerabilities and howto effectively resolve them through Artifacts.

The Artifact from this project contains all identified vulnerabilties after the scan. It is important to learn to interpret Artifacts fotten from scanning application components.

Key contents in the artifact file from the screenshot above are described below.:

  • Version: This is used to track how far back the version of the component is dated to. Also, to clarify the best version of component to use in securing Juice-shop.

  • Component: This is the name of the component.

  • Vulnerabilities: This captures all identified vulnerabilities identified after the scan. Each Identified vulnerability is described with information to qualify its severity.

  • Severity: This describes the level of impact an identified vulnerability can have on the application if exploited by malicious actors.

  • CVE: Common Vulnerability Exposure or CVE captures the category the identified vulnerability falls into. It assigns identifiers to each vulnerability by identifying it with iits industry standard ID.

  • License: A legal agreement that specifies the terms under which the component can be used, ensuring compliance with the author’s wish.

The information obtained from the artifact is used to make and implement actionable points to secure Juice-shop.

Conclusion

Integrating Software Composition Analysis (SCA) into the CI/CD pipeline is a crucial step towards building secure and reliable applications. This project successfully demonstrated how to implement RetireJS within a GitLab CI/CD workflow to automatically scan project dependencies for known vulnerabilities. By configuring the pipeline to fail upon detection of high-severity issues and saving the scan results as a JSON artifact, development and security teams gain immediate feedback on potential risks. This automated process empowers proactive vulnerability management, enhances supply chain security, and ultimately contributes to a more robust and trustworthy software product. The machine-readable artifact provides valuable data for further analysis, auditing, and the implementation of targeted remediation strategies.

Connect with me on X

Connect with me on GitHub

Access the Project Repo on GitLab

Refrences

References

(McGuire, n.d.)
McGuire, M. (n.d.). What is Software Composition Analysis (SCA)? Blackduck.com. Retrieved April 6, 2025, from https://www.blackduck.com/glossary/what-is-software-composition-analysis.html

(Mistazidane, 2023)
Mistazidane. (2023, September 7). Artifact management - mistazidane. Medium. https://medium.com/@mistazidane/artifact-management-ad7768c3ca00

(Npm: Retire, n.d.)
Npm: Retire. (n.d.). Npm. Retrieved April 6, 2025, from https://www.npmjs.com/package/retire

(What is Software Composition Analysis (SCA)?, 2023)
What is Software Composition Analysis (SCA)? (2023, January 26). Check Point Software. https://www.checkpoint.com/cyber-hub/cloud-security/what-is-software-composition-analysis-sca/

(What is YAML?, n.d.)
What is YAML? (n.d.). Redhat.com. Retrieved April 6, 2025, from https://www.redhat.com/en/topics/automation/what-is-yaml

13
Subscribe to my newsletter

Read articles from Sang David directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Sang David
Sang David

Specialty is DevSecOps. Have a BSc. Cyber Security. Cyber Girl 4.0 DevSecOps Career Path.