@conterra/vuln-scan
v0.0.9
Published
con terra vulnerability scan process
Downloads
367
Keywords
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 two 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
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.
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.
If true the process ends with exit code 1 if a vulnerability is detected without a vex information.
Otherwise only the log statement "##vso[task.complete result=SucceededWithIssues;]NEW_VULNERABILITIES_DETECTED" is issued.
*/
"failOnNewVulnerabilities": false,
/* 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,
/* 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]
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.
- Aggregations of the results of all scanners in an own
<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
):
| 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. |