npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@conterra/vuln-scan

v0.0.34

Published

con terra vulnerability scan process

Readme

ct-vuln-scan

The utility is a wrapper around the following tools:

  • grype - Vulnerability scanner for container images and filesystems.
  • trivy - Comprehensive and versatile security scanner
  • oss index - Free catalogue of open source components and scanning tools to help developers identify vulnerabilities

It also supports the OpenVex specification for vulnerability status and justification.

Pre-Requisites

You need to have docker and node/npm installed on your machine.

Installation

The utility is available as an npm package it can be installed globally or locally.

For global installation use:

$ npm install -g @conterra/vuln-scan

For local installation use:

$ npm install @conterra/vuln-scan

or reference it in your package.json file:

{
  "dependencies": {
    "@conterra/vuln-scan": "<current version>"
  }
}

After that you have following commands available:

  • ct-vuln-scan
    • Triggers the vulnerability scan
  • ct-vuln-add-vex
    • Triggers a process to add a new vex statement to a file
  • ct-vuln-add-project
    • Adds a new project to the configuration file based on an existing project entry and adds it to all vex statements
  • ct-vuln-remove-project
    • Removes a project from the configuration file and all vex statements related to the project.
    • Or removes a project from all vex statements matching a given vulnerability id.

Vulnerability scan

The ct-vuln-scan command can be used to scan one or many projects for vulnerabilities. It uses the configured scanners to analyze a projects sbom file and produces aggregated results. The sbom file can be provided as a local file or fetched from a maven repository.

You might for example prepare a folder structure like this:

/vuln-scan/              # root folder
├── vuln-scan-conf.json  # configuration file for projects to scan
├── input                # input to be processed by the scanners
│   └── sbom             # sbom files
│   └── vex              # vex files
│── output               # folder for aggregated scan results

Running the command ct-vuln-scan from the root folder will scan all projects defined in the vuln-scan-conf.json file. By default, output will created in the output folder per project.

In the output folder different files per project are generated, see below. There are also tow summary files directly in the output folder:

  • scan-summary.txt

    • A text file with a summary of the scan results.
    • It contains the console "scan summary" output, which is printed to the console during the scan.
  • scan-summary.json

    • A json file with a summary of the scan results.
    • This can be used to post-process the scan results or to integrate them into other tools.
    • Example:
    {
      "errors": [{
        "project": "[email protected]",
        "error": "Failed to fetch sbom file from maven repository: https://repository.conterra.de/repository/maven-mirror-ct/de/conterra/mapapps/ct-mapapps-rollout/4.18.2/ct-mapapps-rollout-4.18.2-sbom.cdx.json"
      }],
      "vulnerabilities": {
        "CVE-2025-48988": {
          "id": "CVE-2025-48988",
          "severity": "HIGH",
          "title": "tomcat: Apache Tomcat DoS in multipart upload",
          "description": "Allocation of Resources Without Limits or Throttling vulnerability in Apache Tomcat.\n\nThis issue affects Apache Tomcat: from 11.0.0-M1 through 11.0.7, from 10.1.0-M1 through 10.1.41, from 9.0.0.M1 through 9.0.105.\n\nUsers are recommended to upgrade to version 11.0.8, 10.1.42 or 9.0.106, which fix the issue.",
          "components": [
            "pkg:maven/org.apache.tomcat.embed/[email protected]"
          ],
          "refs": [
            "https://avd.aquasec.com/nvd/cve-2025-48988",
            "https://github.com/advisories/GHSA-h3gc-qfqq-6h8f"
          ]
        },
        "CVE-2025-49125": {
          "id": "CVE-2025-49125",
          "severity": "MEDIUM",
          "title": "tomcat: Apache Tomcat: Security constraint bypass for pre/post-resources",
          "description": "Authentication Bypass Using an Alternate Path or Channel vulnerability in Apache Tomcat.  When using PreResources or PostResources mounted other than at the root of the web application, it was possible to access those resources via an unexpected path. That path was likely not to be protected by the same security constraints as the expected path, allowing those security constraints to be bypassed.\n\nThis issue affects Apache Tomcat: from 11.0.0-M1 through 11.0.7, from 10.1.0-M1 through 10.1.41, from 9.0.0.M1 through 9.0.105.\n\nUsers are recommended to upgrade to version 11.0.8, 10.1.42 or 9.0.106, which fix the issue.",
          "components": [
            "pkg:maven/org.apache.tomcat.embed/[email protected]"
          ],
          "refs": [
            "https://avd.aquasec.com/nvd/cve-2025-49125",
            "https://github.com/advisories/GHSA-wc4r-xq3c-5cf3"
          ]
        }
      },
      "vulnerabilityToProject": {
        "CVE-2025-48988": [
          "[email protected]"
        ],
        "CVE-2025-49125": [
          "[email protected]"
        ]
      },
      "projectToVulnerability": {
        "[email protected]": [
          "CVE-2025-48988",
          "CVE-2025-49125"
        ]
      },
      "noLongerDetectedVulnerabilities": {
        "CVE-2023-52070": [
          "[email protected]",
          "[email protected]"
        ]
      }
    }

Configuration

You need to create a vuln-scan-conf.json file in the root of your project.

A minimal configuration file specifies only the project to scan:

{
  "$schema": "./node_modules/@conterra/vuln-scan/dist/schema/conf-schema.json",
  "projects": [
    {
        "name": "mapapps",
        "version": "4.18.2",
        "purl": "pkg:maven/de.conterra.mapapps/[email protected]",
        "sbomFile": "./input/sboms/mapapps-4.18.2.cdx.json"
    }
  ]
}

The following sample lists all available options with their default values:

{
    "$schema": "./node_modules/@conterra/vuln-scan/dist/schema/conf-schema.json",
    
    /* Defines if the process should fail or only log a warning or ignore vulnerabilities.
       If "fail" exit 1 is called.
       If "warn" the log statement "##vso[task.complete result=SucceededWithIssues;] is issued.
       If "ignore" nothing happens.
    */
    "onNewVulnerabilities": "fail",
    /* Defines if the process should fail or only log a warning or ignore no longer detected vulnerabilities.
       If "fail" exit 1 is called.
       If "warn" the log statement "##vso[task.complete result=SucceededWithIssues;] is issued.
       If "ignore" nothing happens.
    */
    "onNoLongerDetectedVulnerabilities": "ignore", 
    /* The maven repository to fetch sboms from.
       If the maven repository requires authentication, the environment variables MAVEN_REPO_USER and MAVEN_REPO_PW must be set.
    */
    "mavenRepo": "https://repository.conterra.de/repository/maven-mirror-ct",
    /* The list of scanners to use. Possible values are "grype", "trivy" and "ossindex". */
    "scanners": ["grype", "trivy", "ossindex"],
    /* (optional) The list of vex files to download. Default is empty array. */
    "vexUrls": [
        "https://example.com/my-vex.json"
    ],
    /* The directory where the vex files are stored. */
    "vexDir": "./input/vex",
    /* The directory where the scan results are written to. */
    "outDir": "./output",
    /* The directory where the cache of the grype and trivy is stored. Both tools maintain databases, which are downloaded and stored in the cache directory. */
    "cacheDir": "./cache",
    /* Flag if true then for each project a sub  directory is created in the output directory. 
       If false all files are directly stored in the output dir without a subfolder structure.
    */
    "createSubDirsForProject": true,
    /* (optional) Defines how the console output is reported.
       Possible values are:
       - "BY_PROJECT_DETAILED" (default): order by project and print cve details
       - "BY_PROJECT" : order by project but do not print cve details
       - "BY_CVE" : order by cve and print cve details
       - "BY_CVE_DETAILED": order by cve but do not print cve details
     */
    "consoleReport": "BY_PROJECT_DETAILED",
    /* The list of projects to scan. */
    "projects": [
        {
            "name": "mapapps",
            "version": "4.18.3",
            /* identifier of the project in the vex files, used to filter the vex statements. */
            "purl": "pkg:maven/de.conterra.mapapps/[email protected]",
            /* The maven coordinates of the sbom file, used to download the file from the maven remote repository. */
            "sbomMavenCoordinates": "de.conterra.mapapps:ct-mapapps-rollout:4.18.3:sbom"
        },
        {
            "name": "mapapps",
            "version": "4.18.2",
            "purl": "pkg:maven/de.conterra.mapapps/[email protected]",
            /* The location of the sbom file. */
            "sbomFile": "./input/sboms/mapapps-4.18.2.cdx.json"
        },
        {
            "name": "mapapps-sample-disabled",
            "version": "4.17.0",
            /* this project is disabled and not scanned */
            "enabled": false,
            "purl": "pkg:maven/de.conterra.mapapps/[email protected]",
            "sbomFile": "./input/sboms/mapapps-4.17.0.cdx.json"
        },
        {
            "name": "mapapps-sample-silent",
            "version": "4.17.2",
            /* this project is scanned, but detected vulnerabilities are ignored and will never break the build */
            "silent": true,
            "purl": "pkg:maven/de.conterra.mapapps/[email protected]",
            "sbomFile": "./input/sboms/mapapps-4.17.2.cdx.json"
        },
        {
            "name": "mapapps-sample-with-minium-severity",
            "version": "4.17.2",
            /* This project is scanned, but only vulnerabilities with a severity >= HIGH will break the build
               Available values are: "CRITICAL", "HIGH", "MEDIUM", "LOW", "UNKNOWN"
            */
            "minimumSeverity": "HIGH",
            "purl": "pkg:maven/de.conterra.mapapps/[email protected]",
            "sbomFile": "./input/sboms/mapapps-4.17.2.cdx.json"
        }

    ]
}

Usage - Scan

To scan all projects run following command in the directory where the configuration file is located:

$ ct-vuln-scan

To scan a specific project run following command:

$ ct-vuln-scan mapapps 4.18.2

To scan all versions of a project run:

$ ct-vuln-scan mapapps

You may need following environment variables for a successful scan:

# (optional) to fetch sboms from maven repository
MAVEN_REPO_USER=[username]
MAVEN_REPO_PW=[password]

# (optional) for oss index authenticated api
OSS_INDEX_API_USER=[username]
OSS_INDEX_API_TOKEN=[token]

# (optional) for authentication downloading vex files specified by vexUrls option
VEX_URLS_USER=[username]
VEX_URLS_PW=[password]

# (optional) helps to fix the rate limit issue during downloading the trivy database from github
# See <https://aquasecurity.github.io/trivy/v0.38/docs/references/troubleshooting/#github-rate-limiting>
TRIVY_GITHUB_TOKEN=[token]

# (optional) to enable verbose logging, otherwise only scan results are printed
VERBOSE=true

# (optional) flag to enable automatic removal of unused statements in the vex files, during a scan.
AUTO_REMOVE_UNUSED_STATEMENTS=true

NOTE: This variables can be set in the .env file in the root of the project.

For each project following files are created in the output folder:

  • <project-name>-<project-version>-sbom.cdx.json
    • Copy of the sbom file.
  • <project-name>-<project-version>-scan-grype-results.json
    • Result of the grype scanner in the grype json format.
  • <project-name>-<project-version>-scan-trivy-results.json
    • Result of the trivy scanner in the trivy json format.
  • <project-name>-<project-version>-scan-ossindex-results.json
    • Result of the sonatype oss index api requests in json format.
  • <project-name>-<project-version>-scan-aggregated-results.json
    • Aggregations of the results of all scanners in an own @conterra/vuln-scan json format.
  • <project-name>-<project-version>-scan-aggregated-results.sarif.json
    • Aggregations of the results of all scanners in an own sarif json format.
  • <project-name>-<project-version>-openvex.vex.json
    • Aggregation of all vex statements available for the project.

If the createSubDirsForProject flag is set to true, the scanner will create a sub directory in the output folder named <project-name>-<project-version> for each project scanned.

Azure DevOps Pipelines Integration

Attach the output directory as build artifact CodeAnalysisLogs.

- task: PublishBuildArtifacts@1
  inputs:
     PathtoPublish: "output"
     ArtifactName: "CodeAnalysisLogs"

Make sure that your Azure DevOps organization has the extension SARIF SAST Scans Tab installed. This extension visualizes the .sarif.json files which are part of the CodeAnalysisLogs.

If the configuration option failOnNewVulnerabilities flag is set to false, the pipeline will be set to SucceededWithIssues if vulnerabilities are found with no matching vex statement. Otherwise the pipeline will be set to Failed (because of exit code 1).

Usage - Add Vex

This is a currently experimental maintenance workflow, where you want to make a decision if a vulnerability is affecting your project or not or if you currently investigating a vulnerability.

To add a new CVE-<>.json file in the vexDir, run:

$ ct-vuln-add-vex

And follow the instructions.

This will create a new CVE-[id].json file in the vexDir folder.

A CVE-2023-52070.json file may look like this:

{
    "@context": "https://openvex.dev/ns/v0.2.0",
    "@id": "https://openvex.dev/docs/public/vex-fc763e6eb63bfbcda20b7cbbddd4e9f8feaaa317fe8d8a6f51a5663a1180343e",
    "author": "conterra",
    "timestamp": "2024-10-01T18:54:23.3233227+02:00",
    "last_updated": "2024-10-01T19:58:13.2159221+02:00",
    "version": 2,
    "statements": [
        {
            "vulnerability": {
                "name": "CVE-2023-52070"
            },
            "timestamp": "2024-10-01T19:58:13.2159221+02:00",
            "products": [
                {
                    "@id": "pkg:maven/de.conterra.mapapps/[email protected]"
                },
                {
                    "@id": "pkg:maven/de.conterra.mapapps/[email protected]"
                }
            ],
            "status": "not_affected",
            "impact_statement": "Reported to JFreeChart library. The CVE was created by an LLM and valued by the JFreeChart team as invalid and bogus. See https://github.com/jfree/jfreechart/issues/396 for more information."
        }
    ]
}

For more information about the OpenVex specification, please refer to the OpenVex Spec.

Here some valid values for the status field:

| Status | Description | | ------------------- | ---------------------------------------------------------------------------------------------------------------------------------- | | not_affected | This product is known to be not affected by this vulnerability. | | affected | This product is known to be affected by this vulnerability. | | fixed | This product contains a fix for this vulnerability. | | under_investigation | It is not known yet whether these versions are or are not affected by the vulnerability. However, it is still under investigation. |

Here some valid values for the justification field (if status is not_affected):

VEX Status Justification PDF

| Justification | Description | | ------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | component_not_present | The vulnerable component is not present in the product. | | vulnerable_code_not_present | The vulnerable code is not present. Typically this case occurs when source code is configured or built in a way that excludes the vulnerable code. | | vulnerable_code_not_in_execute_path | The vulnerable code can not be executed. Typically this case occurs when the product includes the vulnerable code but does not call or use the vulnerable code. | | vulnerable_code_cannot_be_controlled_by_adversary | The vulnerable code cannot be controlled by an attacker to exploit the vulnerability. | | inline_mitigations_already_exist | The product includes built-in protections or features that prevent exploitation of the vulnerability. These built-in protections cannot be subverted by the attacker and cannot be configured or disabled by the user. These mitigations completely prevent exploitation based on known attack vectors. |

Usage - Add Project

To add a new project to the configuration file and all vex statements, run:

$ ct-vuln-add-project <project-name> <project-version> <project-version-to-add>

for example:

$ ct-vuln-add-project mapapps 4.18.2-SNAPSHOT 4.18.2

This will add a new project entry mapapps with version 4.18.2 to the configuration file clone all options from the reference project mapapps with version 4.18.2-SNAPSHOT. It will also add the product-id to all vex statements, where the reference project it listed, too.

This is useful if you release a snapshot version.

Usage - Remove Project

To remove a project from the configuration file and all vex statements, run:

$ ct-vuln-remove-project <project-name> <project-version>

for example:

$ ct-vuln-remove-project mapapps 4.18.2-SNAPSHOT

This will remove the project entry mapapps with version 4.18.2-SNAPSHOT from the configuration file and remove the product-id from all vex statements, where the project is listed.

Usage - Remove Project from vex files matching a vulnerability id

To remove a project from all vex statements matching a vulnerability id, run:

$ ct-vuln-remove-project <project-name> <project-version> <vuln-id>

for example:

$ ct-vuln-remove-project mapapps 4.18.2-SNAPSHOT CVE-2024-38820

This will remove the product-id from all vex statements matching the given vulnerability. This is useful if a vulnerability is no longer detected for a project and you like to remove an existing statement.

Usage - Simulate a version release with preparation of the next dev version

By combining the ct-vuln-add-project and ct-vuln-remove-project commands, you can simulate a version release.

For example, you have a project mapapps with version 4.18.3-SNAPSHOT and you want to release version 4.18.3 and prepare the next dev version 4.18.4-SNAPSHOT, then you can run following commands:

$ ct-vuln-add-project mapapps 4.18.3-SNAPSHOT 4.18.3
$ ct-vuln-remove-project mapapps 4.18.3-SNAPSHOT
$ ct-vuln-add-project mapapps 4.18.3 4.18.4-SNAPSHOT

Dev Notes

Setup:

  1. Checkout via git
  2. Run pnpm install

Run tests (vitest): pnpm test (watch mode) To run tests once (without watch), use pnpm test run.

Build the project (esbuild): pnpm run build (or watch)