
Security is a critical aspect of software development, and staying ahead of vulnerabilities is essential for us application developers. Google’s OSV Scanner is a powerful tool that helps detect vulnerabilities in open-source dependencies.
This article will guide us through setting up and using OSV Scanner to secure our projects, scan for invalid licenses, scan OCI images and finally how to fix findings via guided remediation.
What to scan
There are two categories of files that can be scanned, artifacts and lockfiles/manifests:
Artifacts that may be scanned are …
-
Alpine APK Packages
-
Debian/Ubuntu dpkg/apt Packages
-
Go Binaries
-
Java Uber Jars
-
Node Modules
-
Python wheels
Lockfiles/manifests that may be scanned are…
-
C/C++: conan.lock + commit scanning
-
Dart: pubspeck.lock
-
Elixir: mix.lock
-
Go: go.mod
-
Haskell: cabal.project.freeze, stack.yaml.lock
-
Java: buildscript-gradle.lockfile, gradle.lockfile, gradle/verification-metadata.xml, pom.xml
-
Javascript: package-lock.json, pnpm-lock.yaml, yarn.lock
-
.NET: deps.json
-
PHP: composer.lock
-
Python: Pipfile.lock, poetry.lock, requirements.txt*, pdm.lock, uv.lock
-
R: renv.lock
-
Ruby: Gemfile.lock
-
Rust: cargo.lock
For a complete list of supported artifacts, lockfiles and manifests please consulte the OSV Scanner Docs: Supported Languages and Lockfiles. |
Installation
There are several ways to install the scanner:
go install github.com/google/osv-scanner/cmd/osv-scanner@v1
brew install osv-scanner
apk add osv-scanner
For other installation variants, please take a look at the OSV Docs: Installation |
CVE Scanning
Different environments and locations can contain vulnerabilities or invalid licenses so we proceed step by step…
Project Sources Scanning
To demonstrate the scan process for a typical Java™ project using Maven or Gradle, we’re creating an empty sample project and add a dependency with known vulnerabilities to it:
mkdir osv-sample-project && cd osv-sample-project &&
mvn archetype:generate -DgroupId=com.example -DartifactId=osv-sample -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false &&
cd osv-sample
There, we add the vulnerable dependency com.fasterxml.jackson.core:jackson-databind:2.9.0
to the pom.xml
:
<dependencies>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.0</version>
</dependency>
</dependencies>
Now we may scan our fresh project like this..
Scanning by single pom.xml
osv-scanner --lockfile=pom.xml
In the response, we receive an interesting list of CVEs:
Scanned /private/tmp/hascode-osv-sample-project/hascode-osv-sample/pom.xml file and found 3 packages
╭─────────────────────────────────────┬──────┬───────────┬─────────────────────────────────────────────┬─────────┬─────────╮
│ OSV URL │ CVSS │ ECOSYSTEM │ PACKAGE │ VERSION │ SOURCE │
├─────────────────────────────────────┼──────┼───────────┼─────────────────────────────────────────────┼─────────┼─────────┤
│ https://osv.dev/GHSA-27xj-rqx5-2255 │ 8.1 │ Maven │ com.fasterxml.jackson.core:jackson-databind │ 2.9.0 │ pom.xml │
│ https://osv.dev/GHSA-288c-cq4h-88gq │ 7.5 │ Maven │ com.fasterxml.jackson.core:jackson-databind │ 2.9.0 │ pom.xml │
│ https://osv.dev/GHSA-4gq5-ch57-c2mg │ 9.8 │ Maven │ com.fasterxml.jackson.core:jackson-databind │ 2.9.0 │ pom.xml │
│ https://osv.dev/GHSA-4w82-r329-3q67 │ 9.8 │ Maven │ com.fasterxml.jackson.core:jackson-databind │ 2.9.0 │ pom.xml │
│ https://osv.dev/GHSA-57j2-w4cx-62h2 │ 7.5 │ Maven │ com.fasterxml.jackson.core:jackson-databind │ 2.9.0 │ pom.xml │
│ https://osv.dev/GHSA-58pp-9c76-5625 │ 8.8 │ Maven │ com.fasterxml.jackson.core:jackson-databind │ 2.9.0 │ pom.xml │
│ https://osv.dev/GHSA-5949-rw7g-wx7w │ 8.1 │ Maven │ com.fasterxml.jackson.core:jackson-databind │ 2.9.0 │ pom.xml │
│ https://osv.dev/GHSA-5p34-5m6p-p58g │ 9.8 │ Maven │ com.fasterxml.jackson.core:jackson-databind │ 2.9.0 │ pom.xml │
│ https://osv.dev/GHSA-5r5r-6hpj-8gg9 │ 8.1 │ Maven │ com.fasterxml.jackson.core:jackson-databind │ 2.9.0 │ pom.xml │
│ https://osv.dev/GHSA-5ww9-j83m-q7qx │ 7.5 │ Maven │ com.fasterxml.jackson.core:jackson-databind │ 2.9.0 │ pom.xml │
│ https://osv.dev/GHSA-645p-88qh-w398 │ 9.8 │ Maven │ com.fasterxml.jackson.core:jackson-databind │ 2.9.0 │ pom.xml │
...
Scanning Project Directory
Way more interesting because our OSV scanner analyzes all SBOMs, lockfiles, and git directories in the given path…
osv-scanner scan source -r /path/to/project
osv-scanner scan source -r hascode-osv-sample
Scanning dir hascode-osv-sample
Scanned /private/tmp/hascode-osv-sample-project/hascode-osv-sample/pom.xml file and found 3 packages
╭─────────────────────────────────────┬──────┬───────────┬─────────────────────────────────────────────┬─────────┬────────────────────────────╮
│ OSV URL │ CVSS │ ECOSYSTEM │ PACKAGE │ VERSION │ SOURCE │
├─────────────────────────────────────┼──────┼───────────┼─────────────────────────────────────────────┼─────────┼────────────────────────────┤
│ https://osv.dev/GHSA-27xj-rqx5-2255 │ 8.1 │ Maven │ com.fasterxml.jackson.core:jackson-databind │ 2.9.0 │ hascode-osv-sample/pom.xml │
│ https://osv.dev/GHSA-288c-cq4h-88gq │ 7.5 │ Maven │ com.fasterxml.jackson.core:jackson-databind │ 2.9.0 │ hascode-osv-sample/pom.xml │
│ https://osv.dev/GHSA-4gq5-ch57-c2mg │ 9.8 │ Maven │ com.fasterxml.jackson.core:jackson-databind │ 2.9.0 │ hascode-osv-sample/pom.xml │
│ https://osv.dev/GHSA-4w82-r329-3q67 │ 9.8 │ Maven │ com.fasterxml.jackson.core:jackson-databind │ 2.9.0 │ hascode-osv-sample/pom.xml │
│ https://osv.dev/GHSA-57j2-w4cx-62h2 │ 7.5 │ Maven │ com.fasterxml.jackson.core:jackson-databind │ 2.9.0 │ hascode-osv-sample/pom.xml │
│ https://osv.dev/GHSA-58pp-9c76-5625 │ 8.8 │ Maven │ com.fasterxml.jackson.core:jackson-databind │ 2.9.0 │ hascode-osv-sample/pom.xml │
│ https://osv.dev/GHSA-5949-rw7g-wx7w │ 8.1 │ Maven │ com.fasterxml.jackson.core:jackson-databind │ 2.9.0 │ hascode-osv-sample/pom.xml │
│ https://osv.dev/GHSA-5p34-5m6p-p58g │ 9.8 │ Maven │ com.fasterxml.jackson.core:jackson-databind │ 2.9.0 │ hascode-osv-sample/pom.xml │
[...]
For more detailed information about the scan process, its configuration, how to ignore configurations or enable scanning with call analysis, please consult the OSV Scanner Docs: Scan Source. |
License Scanning
Using the wrong licenses can cause us a lot of trouble but luckily the OSV Scanner includes a license scan for us…
Display license information
osv-scanner --licenses /path/to/repository
Using our sample project, this is the output of running the license check:
osv-scanner --licenses ./hascode-osv-sample
[...]
╭────────────┬─────────────────────────╮
│ LICENSE │ NO. OF PACKAGE VERSIONS │
├────────────┼─────────────────────────┤
│ Apache-2.0 │ 3 │
╰────────────┴─────────────────────────╯
Check against a given Allow-List
osv-scanner --licenses="allowed-license-1,allowed-license-2" /path/to/directory
The licenses must be entered as defined in the SPDX License List! |
As an example, we want to run the license check with only the GNU Lesser General Public License v2.1 only as allowed license which gives us a nice warning about the licenses violated:
osv-scanner --licenses="LGPL-2.1-only" hascode-osv-sample
Scanning dir hascode-osv-sample
[...]
╭───────────────────┬───────────┬────────────────────────────────────────────────┬─────────┬────────────────────────────╮
│ LICENSE VIOLATION │ ECOSYSTEM │ PACKAGE │ VERSION │ SOURCE │
├───────────────────┼───────────┼────────────────────────────────────────────────┼─────────┼────────────────────────────┤
│ Apache-2.0 │ Maven │ com.fasterxml.jackson.core:jackson-annotations │ 2.9.0 │ hascode-osv-sample/pom.xml │
│ Apache-2.0 │ Maven │ com.fasterxml.jackson.core:jackson-core │ 2.9.0 │ hascode-osv-sample/pom.xml │
│ Apache-2.0 │ Maven │ com.fasterxml.jackson.core:jackson-databind │ 2.9.0 │ hascode-osv-sample/pom.xml │
╰───────────────────┴───────────┴────────────────────────────────────────────────┴─────────┴────────────────────────────╯
Container Image Scans
Also important is the ability to scan container images for known vulnerabilities.
osv-scanner scan image <image-name>:<tag>
As an example, we want to scan an old Docker image for Confluent Kafka:
osv-scanner scan image confluentinc/cp-kafka:5.4.3
[...]
Container Scanning Result (Debian GNU/Linux 8 (jessie)):
Total 20 packages affected by 55 known vulnerabilities (3 Critical, 23 High, 24 Medium, 5 Low, 0 Unknown) from 1 ecosystem.
55 vulnerabilities can be fixed.
Maven
╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ Source:artifact:etc/confluent/docker/docker-utils.jar │
├─────────────────────────────────────────────┬───────────────────┬───────────────┬────────────┬──────────────────┬───────────────────────┤
│ PACKAGE │ INSTALLED VERSION │ FIX AVAILABLE │ VULN COUNT │ INTRODUCED LAYER │ IN BASE IMAGE │
├─────────────────────────────────────────────┼───────────────────┼───────────────┼────────────┼──────────────────┼───────────────────────┤
│ com.fasterxml.jackson.core:jackson-databind │ 2.10.5 │ Fix Available │ 5 │ # 26 Layer │ confluentinc/cp-kafka │
│ com.google.code.gson:gson │ 2.8.5 │ Fix Available │ 1 │ # 26 Layer │ confluentinc/cp-kafka │
│ io.netty:netty-codec │ 4.1.48.Final │ Fix Available │ 2 │ # 26 Layer │ confluentinc/cp-kafka │
│ io.netty:netty-common │ 4.1.48.Final │ Fix Available │ 2 │ # 26 Layer │ confluentinc/cp-kafka │
│ io.netty:netty-handler │ 4.1.48.Final │ Fix Available │ 1 │ # 26 Layer │ confluentinc/cp-kafka │
│ org.apache.zookeeper:zookeeper │ 3.5.8 │ Fix Available │ 1 │ # 26 Layer │ confluentinc/cp-kafka │
│ org.yaml:snakeyaml │ 1.26 │ Fix Available │ 7 │ # 26 Layer │ confluentinc/cp-kafka │
╰─────────────────────────────────────────────┴───────────────────┴───────────────┴────────────┴──────────────────┴───────────────────────╯
╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ Source:artifact:usr/share/java/kafka/avro-1.9.2.jar │
├──────────────────────┬───────────────────┬───────────────┬────────────┬──────────────────┬───────────────────────┤
│ PACKAGE │ INSTALLED VERSION │ FIX AVAILABLE │ VULN COUNT │ INTRODUCED LAYER │ IN BASE IMAGE │
├──────────────────────┼───────────────────┼───────────────┼────────────┼──────────────────┼───────────────────────┤
│ org.apache.avro:avro │ 1.9.2 │ Fix Available │ 2 │ # 48 Layer │ confluentinc/cp-kafka │
╰──────────────────────┴───────────────────┴───────────────┴────────────┴──────────────────┴───────────────────────╯
╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ Source:artifact:usr/share/java/kafka/commons-compress-1.19.jar │
├─────────────────────────────────────┬───────────────────┬───────────────┬────────────┬──────────────────┬───────────────────────┤
│ PACKAGE │ INSTALLED VERSION │ FIX AVAILABLE │ VULN COUNT │ INTRODUCED LAYER │ IN BASE IMAGE │
├─────────────────────────────────────┼───────────────────┼───────────────┼────────────┼──────────────────┼───────────────────────┤
│ org.apache.commons:commons-compress │ 1.19 │ Fix Available │ 5 │ # 48 Layer │ confluentinc/cp-kafka │
╰─────────────────────────────────────┴───────────────────┴───────────────┴────────────┴──────────────────┴───────────────────────╯
╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ Source:artifact:usr/share/java/kafka/guava-20.0.jar │
├────────────────────────┬───────────────────┬───────────────┬────────────┬──────────────────┬───────────────────────┤
│ PACKAGE │ INSTALLED VERSION │ FIX AVAILABLE │ VULN COUNT │ INTRODUCED LAYER │ IN BASE IMAGE │
├────────────────────────┼───────────────────┼───────────────┼────────────┼──────────────────┼───────────────────────┤
│ com.google.guava:guava │ 20.0 │ Fix Available │ 3 │ # 48 Layer │ confluentinc/cp-kafka │
╰────────────────────────┴───────────────────┴───────────────┴────────────┴──────────────────┴───────────────────────╯
[...]
Guided Remediation
Guided remediation is there to help us developers fix our findings by providing actionable steps.
There are different remediation strategies, a full list and more detailed information can be found in the OSV Scanner Docs: Remediation Strategies.
The general syntax for remediation is this:
osv-scanner fix --strategy=STRATEGY
So if we wanted to fix our affected dependency in our sample project we do this:
osv-scanner fix --strategy=override -M hascode-osv-sample/pom.xml
Resolving hascode-osv-sample/pom.xml...
Found 67 vulnerabilities matching the filter
Can fix 67/67 matching vulnerabilities by overriding 1 dependencies
OVERRIDE-PACKAGE: com.fasterxml.jackson.core:jackson-databind,2.12.7.1
FIXED-VULN-IDS: GHSA-27xj-rqx5-2255,GHSA-288c-cq4h-88gq,GHSA-4gq5-ch57-c2mg,GHSA-4w82-r329-3q67,GHSA-57j2-w4cx-62h2,GHSA-58pp-9c76-5625,GHSA-5949-rw7g-wx7w,GHSA-5p34-5m6p-p58g,GHSA-5r5r-6hpj-8gg9,GHSA-5ww9-j83m-q7qx,GHSA-645p-88qh-w398,GHSA-6fpp-rgj9-8rwc,GHSA-6wqp-v4v6-c87c,GHSA-758m-v56v-grj4,GHSA-85cw-hj65-qqv9,GHSA-89qr-369f-5m5x,GHSA-8c4j-34r4-xr8g,GHSA-8w26-6f25-cm9x,GHSA-95cm-88f5-f2c7,GHSA-9gph-22xh-8x98,GHSA-9m6f-7xcq-8vf8,GHSA-9mxf-g3x6-wv74,GHSA-9vvp-fxw6-jcxr,GHSA-c265-37vj-cwcc,GHSA-c2q3-4qrh-fm48,GHSA-c8hm-7hpq-7jhg,GHSA-cf6r-3wgc-h863,GHSA-cggj-fvv3-cqwv,GHSA-cjjf-94ff-43w7,GHSA-cmfg-87vq-g5g4,GHSA-cvm9-fjm9-3572,GHSA-f3j5-rmmp-3fc5,GHSA-f9hv-mg5h-xcw9,GHSA-f9xh-2qgp-cq57,GHSA-fmmc-742q-jg75,GHSA-fqwf-pjwf-7vqv,GHSA-gjmw-vf9h-g25v,GHSA-gwp4-hfv6-p7hw,GHSA-gww7-p5w4-wrfv,GHSA-h3cw-g4mq-c5x2,GHSA-h4rc-386g-6m85,GHSA-h592-38cm-4ggp,GHSA-h822-r4r5-v8jg,GHSA-j823-4qch-3rgm,GHSA-jjjh-jjxp-wpff,GHSA-m6x4-97wx-4q27,GHSA-mc6h-4qgp-37qh,GHSA-mph4-vhrx-mv67,GHSA-mx7p-6679-8g3q,GHSA-mx9v-gmh4-mgqw,GHSA-p43x-xfjf-5jhr,GHSA-q93h-jc49-78gg,GHSA-qjw2-hr98-qgfh,GHSA-qmqc-x3r4-6v39,GHSA-qr7j-h6gg-jmgc,GHSA-r3gr-cxrf-hg25,GHSA-r695-7vr9-jgc2,GHSA-rf6r-2c4q-2vwg,GHSA-rfx6-vp9g-rh7v,GHSA-rgv9-q543-rqg4,GHSA-rpr3-cw39-3pxh,GHSA-v3xw-c963-f5hc,GHSA-v585-23hc-c647,GHSA-vfqx-33qm-g869,GHSA-w3f4-3q6j-rh82,GHSA-wh8g-3j2c-rqj5,GHSA-x2w5-5m2g-7h5m
REMAINING-VULNS: 0
UNFIXABLE-VULNS: 0
Rewriting hascode-osv-sample/pom.xml...
When we inspect now our changed pom.xml
, we can see, that the version of our dependency jackson-databind
was changed from 2.9.0
to 2.12.7.1
.
OSV Schema
The advisories in the OSV database all use the Open Source Vulnerability format
, which is specified in the following schema: https://ossf.github.io/osv-schema/
There is also a JSON Schema that may be used for validations: https://github.com/ossf/osv-schema/blob/main/validation/schema.json
View the complete schema
{
"schema_version": string,
"id": string,
"modified": string,
"published": string,
"withdrawn": string,
"aliases": [ string ],
"upstream": [ string ],
"related": [ string ],
"summary": string,
"details": string,
"severity": [ {
"type": string,
"score": string
} ],
"affected": [ {
"package": {
"ecosystem": string,
"name": string,
"purl": string
},
"severity": [ {
"type": string,
"score": string
} ],
"ranges": [ {
"type": string,
"repo": string,
"events": [ {
"introduced": string,
"fixed": string,
"last_affected": string,
"limit": string
} ],
"database_specific": { see description }
} ],
"versions": [ string ],
"ecosystem_specific": { see description },
"database_specific": { see description }
} ],
"references": [ {
"type": string,
"url": string
} ],
"credits": [ {
"name": string,
"contact": [ string ],
"type": string
} ],
"database_specific": { see description }
}
Tutorial Sources
Please feel free to download the sample project for the scans from my GitHub repository, fork it there or clone it using Git:
git clone https://github.com/hascode/sample-project-to-scan.git