Strategies for Minimizing your CVE Risk

A conceptual article outlining best practices for reducing one's CVE risk.

Common vulnerabilities and exposures, often referred to as “CVEs”, are an increasing concern for both developers and consumers of software. A new CVE that appears in a widely-used application or a vulnerability scan with a large number of positive results would naturally be worrisome for developers, CISOs, and end users alike.

Chances are, your software has already been impacted by a CVE. It’s likely there are active CVEs in software you are using. After all, there are software vulnerabilities currently in existence that haven’t even been discovered (known as zero-day vulnerabilities). With that said, this conceptual article aims to highlight a few practices and strategies you and your team can use to reduce the risk of CVEs on your software. It also includes a section on tools recommended by Chaingaurd that can help to reduce your attack surface area and minimize your risk of CVEs.

Understanding potential risks

An important step to minimizing your CVE risk is to understand the potential impacts and develop a sense of how CVEs can make their way into your applications.

One way you can do this is to familiarize yourself with the various databases that list known CVEs and their exploitations, including the CVE Program and the Known Exploited Vulnerabilities (KEV) Catalog. It also might be helpful to stay up to date with industry news. Software vulnerabilities and attacks have gained more attention from technology journalists. For example, the Heartbleed vulnerability received widespread coverage when it was discovered in 2014, as did the Log4Shell vulnerability in 2021.

Bear in mind, just keeping up to date with industry news and recent CVEs won’t prevent vulnerabilites from encroaching on your projects. After all, malicious actors could be exploiting a vulnerability in your code long before the CVE is discovered and reported. Having said that, understanding how vulnerabilities are discovered, categorized, and exploited can be useful when thinking about how to harden your system’s defenses.

Another way to prepare yourself for the potential risks associated with CVEs is to have a plan in place for what you should do if new vulnerabilities affecting your software arise. It’s becoming more common for organizations to develop a playbook built out ahead of time. The Cybersecurity & Infrastructure Security Agency (CISA) recently published a Vulnerability Response Playbook. The goal of this playbook is to provide a framework for Federal Civilian Executive Branch agencies to identify and mitigate vulnerabilities. Although this playbook is meant specifically for organizations working with the federal government, the idea of having a plan in place ahead of a vulnerability is a great way to minimize the risk.

Maintaining dependency hygiene

Dependency hygiene is the practice of ensuring that the dependencies you introduce into your project do not contain vulnerabilities. We’ve found that many popular container images, when not updated, will accumulate about one known vulnerability per day. Many of the most widely used container images aren’t updated regularly and past academic software engineering research has found that most images on Docker Hub, the most widely used container registry, have not been updated for over 120 days.

Some teams go so far as to actively avoid using dependencies, working under the belief that taking a “roll-your-own” approach to all their tooling is an effective way to reduce CVEs. Although first-party tools may report fewer CVEs when scanned, they won’t be battle-tested like widely used open-source software, meaning there are drawbacks to this approach.

This section outlines a few categories of tools that can be useful for minimizing CVEs, and provides a few examples for each.

Scanners

There are a number of tools available that allow you to scan your third party code for CVEs.

At Chainguard, we use Grype to scan our own Chainguard Images, as it’s open-source and it can scan Software Bills of Materials (or SBOMs). Additionally, Grype biases towards false positives over false negatives. Looking into a vulnerability in an image that turns out to be a false positive can be preferable to overlooking a real vulnerability that impacts end users.

Another open-source scanning option is Falco. Falco works with environments running in individual containers, hosts, Kubernetes, and the cloud. Falco works by collecting data from various sources — including Linux kernal syscalls, Kubernetes audit logs, and events from systems like GitHub or Okta — and compares them with a set of rules. Falco comes with a list of rules by default, but you can also create your own rules to suit the needs of your project. If any of the collected data breaks one of the rules, Falco will identify it as a security issue.

Be aware that the results of a vulnerability scan can only tell you part of the story. Say, for example, that Project A has only a few dependencies while Project B has many. Logically, a vulnerability scan of Project A will likely return fewer results than one for Project B, but that doesn’t mean that Project A is at any less of a risk. Although its results might show only a few CVEs, one of these vulnerabilities could still have a serious impact on Project A. Conversely, Project B’s scan results might show a large number of CVEs, but most or all of these could be false positives.

Scorecard is another scanning tool, though it isn’t specifically a vulnerability scanner. Scorecard is an automated tool from the Open Source Security Foundation that performs a variety of security checks on software, returning a score between 1 and 10 for each one. These scores can help you understand what you need to work on to improve your project’s security, and can also help you assess the security of your dependencies.

For a more in-depth discussion of how scanners may fail to collect certain information, we encourage you to check out our blog post on “Software Dark Matter”.

Automating updates

As stated in the preceding section on dependency hygeine, out-of-date dependencies pose a serious risk to software projects. The older and more out of date a given dependency is, the more likely it is to contain vulnerabilities. Automating updates for your projects can help avoid the problems associated with outdated dependencies

One tool that’s useful for automating updates for your dependencies is Dependabot. Dependabot is a free tool offered by GitHub that sends alerts to repositories affected by new vulnerabilities and — if possible — raises a pull request to update the affected dependencies.

If you’d like to automate updates outside of GitHub repositories, Snyk is another tool that enables automatic updates. Synk can integrate into IDEs as well as repositories, allowing you to continously scan for vulnerabilities. Like Dependabot, Snyk will automatically submit a pull request when it encoutners a vulnerability and it can recommend a solution.

There are a number of important considerations one should make when keeping container images up to date. Please check out our conceptual article on the subject.

Minimal container images

As mentioned previously, the fewer dependencies a given piece of software uses, the lower likelihood that it will be impacted by CVEs. To this end, Chainguard provides a library of minimal container images that can minimize your CVE risk.

Chainguard Images are distroless, meaning they contain only an application and its runtime dependencies. These images do not even contain a shell or package manager. Because Chainguard Images minimize the number of dependencies in this manner and thus reduce the potential attack surface, they inherently contain few to zero CVEs. Also, Chainguard Images are rebuilt nightly to ensure images are completely up-to-date and contain all available security patches, and the engineering team often fixes vulnerabilities before they’re detected.

If you’re looking for a certain image that isn’t included in Chainguard’s library, you can build your own minimal container images with Wolfi, a community Linux distribution designed by Chainguard for the container and cloud-native era. Chainguard started the Wolfi project to enable building Chainguard Images, which required a Linux distribution with components at the appropriate granularity and with support for glibc.

Wolfi includes a fully declarative and reproducible build system and provides a high-quality, build-time SBOM as standard for all packages. Its packages are designed to be granular and independent — in order to support minimal images — and uses the proven and reliable apk package format.

Please note that as of March of 2024, Chainguard will maintain one version of each Wolfi package at a time. These track the latest version of the upstream software in the package. Chainguard does not provide patch support for previous versions of packages in Wolfi. Existing packages will not be removed from Wolfi and you may continue to use them, but be aware that older packages will no longer be updated and will accrue vulnerabilities over time. This change ensures that Chainguard can provide the most up-to-date patches to all packages for our Images users. Note that specific package versions can be made available in Production Images, if you have a request for a specific package version, please contact support.

Learn more

As mentioned in the introduction, there’s no way to guarantee that no CVEs will affect your software. However, we hope that by reading this article you’ll have learned some practical tips you can use to help minimize your exposure to vulnerabilities and keep your software secure.

If you’d like to learn more about CVEs, and strategies for remediating them, we encourage you to check out the following resources:

Last updated: 2024-03-29 11:07