At worst, a software vulnerability can impose a critical security flaw that warrants attention. Developers care about mitigating software vulnerabilities because their presence may harm the integrity of their product, negatively affect downstream users, or slow down efforts toward meeting regulatory requirements. However, modern software development practices which incorporate third-party packages in addition to newly scripted code can complicate the vulnerability remediation process. Keeping track of how and where vulnerabilities are introduced, as well as what introduced them, is an arduous task when multitudes of dependencies are working together.
In this article, you will explore some steps you can take to make vulnerability remediation easier from start to finish. You will begin by learning how various tools can help you catalog the components of your software. Next, you will move on to identifying, triaging, and remediating vulnerabilities, and learn how to address vulnerabilities present in container images.
Vulnerability remediation can be difficult when your code incorporates a wide array of packages. On top of this, projects often rely on dependencies which have their own dependencies (called transitive dependencies), thus further adding to the layers which compose a piece of software. When working on large-scale projects with hundreds of files, dependencies, and collaborators, keeping track of everything can become overwhelming.
To combat this, an SBOM, or Software Bill of Materials, can be used. SBOMs are machine-readable documents that track the dependencies of a project. A good SBOM includes dependency names and their version numbers, enabling accurate identification of every component. By using an SBOM to catalog project dependencies, you can gain insight into the many inputs comprising a piece of software.
In addition to generating an SBOM for your project, you can take your software security one step further with the use of attestations, which guarantee the provenance of a software artifact. Establishing provenance of an artifact ensures that it has not been altered after generation, enabling trust and confidence in its composition.
To learn more about using SBOMs and attestations to secure your software supply chain, check out our article comparing the two options.
After taking steps to understand and catalog your software components, you can move on to scanning for vulnerabilities. A vulnerability scanner is a tool which ingests databases of known software vulnerabilities (most notably the National Vulnerability Database database) and scans your software to determine if any reported vulnerabilities may be present. Having an SBOM generated for your software can streamline this process, as the SBOM itself can be scanned to determine if you’re running any packages affected by vulnerabilities.
A couple examples of open source vulnerability scanners that you can use are as follows:
Trivy is a jack-of-all-trades project that can scan a variety of targets including containers, filesystems, and remote Git repositories.
Grype integrates with Syft, an SBOM generation tool, making it easier to generate and then scan an SBOM for your software.
After identifying what vulnerabilities may be present in your software, you can begin triaging them. Vulnerability triage is the process of sorting and prioritizing which vulnerabilities need to be addressed first. There are a few factors to be considered when triaging, including false positive vulnerabilities, vulnerability severity, and exploitability status.
False positives - Though vulnerability scanners may find and report a CVE for a given dependency, it may not be present in your software. If the vulnerability is outside of your program’s scope (for example, in a function that you are not calling) then the vulnerability may not truly impact your application, and you do not need to spend time addressing it.
Vulnerability severity – CVEs are assigned a Common Vulnerability Scoring System (CVSS) score to assess the severity of their impacts if exploited. A CVE with a CVSS score of critical may have serious consequences to the confidentiality, integrity, and availability of a system, making it a priority to remediate. In comparison, a CVE with a low severity score may be difficult to exploit or has minimal impact, so it can be remediated after higher priorities are addressed.
Exploitability status – Not all vulnerabilities have been observed to be exploited. Checking to see if a vulnerability is in the Known Exploited Vulnerabilities (KEV) Catalog can tell you if there is an active attacker threat “in the wild” for vulnerabilities present in your software. Note that a vulnerability’s absence from the KEV Catalog does not mean it won’t be exploitable, as unreported or unobserved attacks on a vulnerability may still exist (or may occur in the future).
Vulnerability Exploitability eXchange (VEX) documents can be helpful references when triaging vulnerabilities. VEX is a model which allows software developers to report the status of vulnerabilities in a software product to inform downstream users of what actions they should take to address them. If a scanner reports a vulnerability in a product, a VEX document can elaborate on how the vulnerability truly impacts it.
To learn more about how you can use VEX, check out OpenVEX, an open source implementation of VEX that you can leverage when generating or ingesting VEX documents.
Once you have triaged the vulnerabilities found in your software, you can move on to remediating them. Vulnerability remediation is the act of correcting and removing CVEs from your software. Using a CVE ID, you can check sources such as the National Vulnerability Database (NVD) for advisories regarding a vulnerability. Here, you can learn what steps should be taken to address the vulnerability. Oftentimes, this will include updating dependencies to patched versions. After you have followed guidance to fix the vulnerability, you should scan your software again to ensure that it was properly remediated.
Note that not all true positive vulnerabilities may be remediable. In some cases, a patch is not yet made available to address the vulnerability, or updating the package version may introduce breaking changes to your program. In situations like these, focus on what you can remediate given your resources at the time.
Container images are like little bundles of code containing the files and dependencies they each need to run. They are called containers because they operate as a discrete unit; each container has what it needs, and can run independently from other containers.
Container images are helpful as they prevent inputs, permissions, and dependencies from clashing with one another. However, containers are prone to accumulating vulnerabilities if they are not properly maintained. As vulnerabilities are discovered and reported, containers should be rebuilt to use updated, secured versions, or else they will begin to collect vulnerabilities. Research from Chainguard Labs has shown that container images from Docker Hub, a popular container image registry, will accumulate one vulnerability per day if not updated.
To combat the accumulation of vulnerabilities in containers, you should choose lightweight, minimal container images which are frequently rebuilt. Popular container images often come bundled with hundreds of packages, some of which may be unnecessary for your applications. These extra components contribute to vulnerability accumulation as they don’t necessarily add functionality, but add more vectors to attack.
Using a distribution such as Alpine Linux or the Wolfi undistro, both of which prioritize security and size, can reduce dead weight in your containers. In addition, frequently rebuilding your images ensures that packages are up-to-date and include security patches.
Chainguard Images offer minimal, frequently rebuilt images to help you reduce vulnerabilities present in your containers. Built on top of Wolfi, the goal of Chainguard Images is to minimize total attack surface and update continuously in order to reduce your CVE count. The following graph illustrates the drastic reduction in CVEs seen by switching from an official base image to its Chainguard Images variant.
Comparing the latest official Python image with cgr.dev/chainguard/python
Check out our article on selecting a base image to explore more factors that should impact your container image choice.
After identifying, triaging, and remediating vulnerabilities, you will be left with both a better understanding of your software and a more secure product. However, vulnerability remediation does not stop there. As your software is developed further, new vulnerabilities may be introduced or discovered. It is important to continue scanning your software frequently in order to address any new security concerns that may arise.
Vulnerability management can be daunting at first, especially when your scanners report high CVE counts across hundreds of project dependencies. By leveraging the tools and procedures fit for your needs, you can work towards securing your software, one vulnerability at a time.
In this article, you learned four steps that you can take towards reducing vulnerabilities in your software. You learned how you can use resources such as SBOMs, VEX, and the KEV Catalog to aid you in vulnerability triage. In addition, you explored factors that impact triage and remediation, and how you can choose container images with less vulnerabilities.
To learn more about software vulnerabilities, you can read our other articles about CVEs. For more information on getting started with Chainguard Images, check out our website and Images documentation.