Trivy Can Now Scan Unpackaged Binary Files
Trivy, the all-in-one security scanner, is now able to scan binary files in your scan targets such as container images.
Most security scanners rely on package managers to discover vulnerabilities. Trivy now uses Rekor from Sigstore to look up the hash of a binary file. If a relevant SBOM is found through the hash, Trivy uses the information from the SBOM to discover security issues.
The following sections detail the process and technologies.
How does it work?
Previously, Trivy relied on package manager metadata in order to identify applications. This data was then used to discover dependencies and the packages used within which in turn are then scanned for vulnerabilities. The downside of this was that Trivy could not have identified software outside of a package manager and, thus, could not have scanned it for vulnerabilities and other security issues.
For example, any Dockerfile-centric workflow where you build the binary and COPY or ADD the binary into the container image would have been missed.
With Trivy v0.33, we are releasing an experimental approach to address this common concern using SBOM and Sigstore.
An SBOM (Software Bill of Material) is an inventory list of all the dependencies in your resources; for instance, in your container image. Trivy can use the SBOM of a container image to scan that container image for security issues. Similarly, other resources, such as filesystems, can be scanned for security issues by using their SBOM.
If you are new to SBOMs, have a look at our tutorial on generating and using SBOMs with Trivy.
Rekor is a public, immutable transparency log for signed metadata, developed by Sigstore. Whenever something changes in a software project, the metadata of that change can be signed by an authority who initiated and verified the change. To allow everyone to keep track of and verify changes, the signed metadata can be forwarded and stored in Rekor. This allows everyone who has access to the log data to verify what changes took place to the resource and the entity, and who authorized those changes. Given that Rekor provides an immutable record, once the data is stored it cannot be changed or tampered with.
Rekor hosts a public instance of their transparency log. However, an organization could also spin up their own instance. This can become useful to verify changes across teams.
Bringing it all together
During a security scan, when Trivy stumbles upon an executable binary, Trivy will look up the hash of the binary in Rekor. If the hash of the resource is found in Rekor, Trivy will check whether there is a relevant SBOM. If Trivy finds the SBOM to the resource scanned, it will use it for vulnerability detection.
With this change to Trivy, we are ensuring that we will discover all the resources that went into the build process of a container image. This in turn helps us generate more reliable and accurate scan results.
We will demonstrate Trivy’s new functionality based on a Rust app. Both Java and Rust apps are generally good examples since their dependencies are not loaded into the binary. In comparison, Trivy can automatically scan Golang binaries for vulnerabilities since Go embeds dependencies into the binary.
To follow this example, you do not need existing Rust experience. However, you will need to have Trivy installed. The installation section in the Docs lists several examples.
We are going to use the example in the Trivy documentation. For those who are curious, the example used is a cat clone but with Syntax highlights and some other features.
Here are the steps that we are going to follow in the tutorial:
- Clone the repository
- Generate an SBOM from Cargo.lock
- Install trivy-plugin-attest (one shot)
- Run trivy attest with the generated SBOM and the compiled binary
- Generating attestation, signing, and uploading will be done by the trivy-plugin-attest.
- Run Trivy on the container image that adds the binary
First, we are going to clone the application:
git clone -b v0.20.0 https://github.com/sharkdp/bat
Next, we are going to create an SBOM for the application. The SBOM is based on the Cargo.lock file, which lists all our dependencies:
trivy fs --format cyclonedx --output bat.cdx ./Cargo.lock
You should now find a bat.cdx file inside of the repository.
Downloading the binary
In a later step, we will use the binary of the project in a container image.
To showcase how Trivy cannot scan the Rust binary before discovering the SBOM through Rekor, we will now create a simple container image, add the binary and scan it for vulnerabilities.
Get the binary and make it executable with the following command:
tar xvf bat-v0.20.0-x86_64-apple-darwin.tar.gz
Move the binary into your current directory:
cp ./bat-v0.20.0-x86_64-apple-darwin/bat bat
Next, create a Dockerfile with the following content:
ADD bat bat
Lastly, we can create the container image and try to scan it for vulnerabilities. This is shown in the following screenshot:
The scan was only able to access the packages in the Ubuntu base image. However, the line Number of language-specific files:0 indicates that Trivy could not scan the binary nor related packages.
To follow along, run these commands:
docker build –t USERNAME/bat:demo-1 ./
trivy image USERNAME/bat:demo-1
However, we are going to change that in the next steps by uploading the SBOM to Rekor.
Next, we will install the trivy-attest-plugin, use it to create an SBOM attestation, and upload the attestation to Rekor.
Trivy is using Cosign to generate the SBOM attestation. However, Cosign currently does not support keyless signing for blob attestation. That’s why we have created a plugin. Alternatively, Rekor has several examples in their documentation that show how to sign and upload an attestation with different keys.
Install the plugin with the following command:
trivy plugin install github.com/aquasecurity/trivy-plugin-attest
Now that we have the plugin installed, we are going to create the SBOM attestation and publish it through the plugin to Rekor. The attestation must be in the following format:
trivy attest --type PREDICATE_TYPE --predicate PREDICATE_PATH BINARY-FILE-PATH
In our case, this will translate to the following command:
trivy attest --type cyclonedx --predicate ./result.cdx ./rust-jreleaser
The PREDICATE_PATH is the SBOM file and the PREDICATE_TYPE is the type of SBOM that you generated, which in our case is CycloneDX.
Once you run the command, a window should pop-up in your browser that asks you to log into Sigstore. In my case, I am using GitHub to authorize Sigstore:
Once you have logged in successfully, you should see a success message and a token printed to your terminal.
Lastly, we can verify that Trivy can now successfully scan the binary in our container image for vulnerabilities through the attestation to our SBOM uploaded to Rekor. For this, we need to build a new container image and then run the Trivy vulnerability scan on it. Since this is still an experimental feature, we need to include the following flag in the image scan: --sbom-sources rekor.
Once you run the scan, Trivy will find the SBOM to the binary file through Rekor and can scan the packages detailed within for vulnerabilities:
The complete command for the scan is:
trivy image --sbom-sources rekor anaisurlichs/bat:demo-2
In this blog we detailed changes to Trivy vulnerability scanning. Specifically, how Trivy is now utilizing Rekor to access the SBOM of a resource for more reliable and detailed security scans.
All projects, including Trivy and Rekor by Sigstore, are open source. If you like those projects, we would highly appreciate if you could give them a star on GitHub.
Additionally, join the Slack community if you have any questions.