vimp
Import CLI for data output from OSS vulnerability scanners. Extracts vulnerabilities from reports output by common OSS scanners and converts it into a generic format which then is saved into a target store. Useful for comparing data across multiple scanners.
Usage
One of the use-cases where vimp can come handy is getting quick overview of the commonality and differences across the vulnerabilities identified by different scanners. To demo this start by exporting a digest of an image you want to use, for example the official Redis image in Docker Hub:
export image="docker.io/redis@sha256:7b83a0167532d4320a87246a815a134e19e31504d85e8e55f0bb5bb9edf70448"
Next, generate vulnerability report using one or more of the supported OSS scanners:
- grype
grype --add-cpes-if-none -s AllLayers -o json --file report.json $image
- snyk
snyk container test --app-vulns --json-file-output=report.json $image
- trivy
trivy image --format json --output report.json $image
Then, import each one of the scanner outputs:
Note, vimp supports number of targets; data stores like local Sqlite DB or Google BigQuery (the target table will be created if it does not exist). You can also use vimp to export data into a file (json or csv), or stdout.
vimp import --source $image --file report.json --target sqlite://demo.db
In case of import with snyk output for the above image the response should be something like this:
INF found 78 unique vulnerabilities
Once you imported data, you can also run queries against this data. The default query against the same data will provide summary of all the data in your store:
vimp query --target sqlite://demo.db
After importing data for one image from three sources the response will look something like this:
INF found 1 records
{
"https://docker.io/redis": {
"versions": {
"sha256:7b83a0167532d4320a87246a815a134e19e31504d85e8e55f0bb5bb9edf70448": {
"exposures": 240,
"sources": 3,
"packages": 73,
"high_score": 10,
"first_discovered": "2023-04-05T19:29:16Z",
"last_discovered": "2023-04-05T19:41:11Z"
}
}
}
}
To dig deeper into the data for that image, you can list all the vulnerabilities found that image across all of the sources:
vimp query --target sqlite://demo.db \
--image https://docker.io/redis \
--digest sha256:7b83a0167532d4320a87246a815a134e19e31504d85e8e55f0bb5bb9edf70448
The results for that query should look something like this:
Notice the differences in severity and score reported by the different scanners:
{
"image": "https://docker.io/redis",
"digest": "sha256:7b83a0167532d4320a87246a815a134e19e31504d85e8e55f0bb5bb9edf70448",
"exposures": {
"CVE-2005-2541": [
{
"source": "grype",
"severity": "negligible",
"score": 10,
"last_discovered": "2023-04-05T19:40:42Z"
},
{
"source": "snyk",
"severity": "low",
"score": 9.8,
"last_discovered": "2023-04-05T19:29:16Z"
},
{
"source": "trivy",
"severity": "low",
"score": 10,
"last_discovered": "2023-04-05T19:41:11Z"
}
],
"CVE-2007-5686": [
{
"source": "grype",
"severity": "negligible",
"score": 4.9,
"last_discovered": "2023-04-05T19:40:42Z"
},
...
],
}
}
There will be a lot of commonalities in the data returned by each one of the scanners. You can append the --diffs-only flag to highlight only the data where the exposures are not the same across all of the sources.
To drill into the packages impacted by each vulnerabilities you can use the additional --exposure flag:
vimp query --target sqlite://demo.db \
--image https://docker.io/redis \
--digest sha256:7b83a0167532d4320a87246a815a134e19e31504d85e8e55f0bb5bb9edf70448 \
--exposure CVE-2005-2541
The result should look something like this:
INF found 3 records
{
"image": "https://docker.io/redis",
"digest": "sha256:7b83a0167532d4320a87246a815a134e19e31504d85e8e55f0bb5bb9edf70448",
"exposure": "CVE-2005-2541",
"packages": [
{
"source": "grype",
"package": "tar",
"version": "1.34+dfsg-1",
"severity": "negligible",
"score": 10,
"last_discovered": "2023-04-05T19:40:42Z"
},
{
"source": "snyk",
"package": "tar",
"version": "1.34+dfsg-1",
"severity": "low",
"score": 9.8,
"last_discovered": "2023-04-05T19:29:16Z"
},
{
"source": "trivy",
"package": "tar",
"version": "1.34+dfsg-1",
"severity": "low",
"score": 10,
"last_discovered": "2023-04-05T19:41:11Z"
}
]
}
Data Store
The schema created by vimp in the target DB will look something like this (adjusted for DB-specific data types):
image TEXT NOT NULL
digest TEXT NOT NULL
source TEXT NOT NULL
processed TIMESTAMP NOT NULL
cve TEXT NOT NULL
package TEXT NOT NULL
version TEXT NOT NULL
severity TEXT NOT NULL
score FLOAT NOT NULL
fixed BOOL NOT NULL
See sql/query.sql for examples of queries against the imported data.
See https://github.com/mchmarny/artifact-events for how to set up vimp as an import for all new images in GCR or AR on GCP.
Installation
You can install vimp CLI using one of the following ways:
See the release section for vimp checksums and SBOMs.
Go
If you have Go 1.17 or newer, you can install latest vimp using:
go install github.com/mchmarny/vimp@latest
Homebrew
On Mac or Linux, you can install vimp with Homebrew:
brew tap mchmarny/vimp
brew install vimp
New release will be automatically picked up when you run brew upgrade
RHEL/CentOS
rpm -ivh https://github.com/mchmarny/vimp/releases/download/v$VERSION/vimp-$VERSION_Linux-amd64.rpm
Debian/Ubuntu
wget https://github.com/aquasecurity/vimp/releases/download/v$VERSION/vimp-$VERSION_Linux-amd64.deb
sudo dpkg -i vimp-$VERSION_Linux-64bit.deb
Binary
You can also download the latest release version of vimp for your operating system/architecture from here. Put the binary somewhere in your $PATH, and make sure it has that executable bit.
The official vimp releases include SBOMs
Disclaimer
This is my personal project and it does not represent my employer. While I do my best to ensure that everything works, I take no responsibility for issues caused by this code.