Notes on CVE assessment

This post collects some notes about the lifecycle of vulnerabilities. It also discusses the challenges I faced during the assessment process: from the need to keep the analysis consistent to the limits of the CVSS base score. The post interchanges the terms "vulnerability" and "CVE". A "system" is any solution or service, which is deployed somewhere or consumed by another upstream component.

Vulnerabilities lifecycle

CVE is an acronym for Common Vulnerabilities and Exposures. "A CVE" is usually referring to a specific vulnerability affecting a system. For example, if you read "This CVE is affecting X," it means a CVE-ID vulnerability is present in component X or its downstream dependencies (i.e.: 3rd party Open-source dependencies).

CVE is a system maintained by The MITRE Organization in collaboration with some other organisations.

The lifecycle of a vulnerability usually follows these steps:

  1. A person or an organisation (let's call them a researcher) finds a security flaw in a software product.
  2. The researcher disclose in private the security concern to the owner(s) (let's call they vendor) of the software product.
  3. The vendor plans a fix by following a pre-defined security policy. It also prepares the disclosure of the vulnerability.
  4. At the start of the disclosure process, the vendor reports the vulnerability to a CVE Program Partner [1]. This process assigns a CVE ID to the vulnerability.
  5. The CNA submits the details of the vulnerability linked to the CVE ID.
  6. Finally, the CVE ID is published.

The final result usually looks like something similar to this: CVE-2023-27536 - The CVE details summarize the problem briefly and they display the name of the CNA that published the CVE.

Note that, the website does not provide any information on the severity of a CVE. The next section, "Scoring process", explains how severities are assigned.

Vulnerabilities in Open-Source

Open-Source security reporting process varies across projects. The owner of an OSS package may be an individual, a community, or an organization. As a result, the Open-source ecosystem does not have a unified vulnerabilities reporting process. Yet, there are some similarities:

  • Open-source projects usually have a file. It describes the process for reporting security problems for the project.
  • Maintainers and small organisation owning a open-source projects, use the MITRE Corporation CNA to create CVE-IDs.
  • As a general rule, vulnerabilities or security concerns should never been disclosed in public (e.g.: Issue Github page of the project). Usually, the best approach is to follow the process in the file. In alternative, reach the organization or the maintainer in private.

Note that, more mature OSS organizations usually have a more established security teams and processes in place. [2]

Scoring process

When a CVE-ID is generated, multiple groups and vendors take part to the process of assigning the severity and other details to the vulnerability. The details include:

  • The severity of the vulnerability, usually measured through the CVSS standard.
  • The proof of exploitation, if any.
  • All the component vulnerable versions.
  • Any reference to the vulnerability.
  • Any link to a specific CWE-ID tracked in the Common Weakness Enumeration List (CWE) maintained by MITRE.

These groups and vendors keep records of the details in their databases. Some of the well-known examples are: the National Vulnerability Database (NVD)[3] which is supported by NIST, GitHub Advisories Database, or more vendor specific databases such as the Ubuntu CVEs report.

CVSS is the common scoring system for measuring the severity of a CVE. The most adopted version is CVSS 3.1. Few months back, CVSS 4.0 has been released, but it will take time for the field to adopt it. Vulnerability databases map the CVSS severity score to the CVEs. This score is also referred as "Base score", because it keeps track of the intrinsic characteristics of the vulnerability which are constant over time.

The CVSS score of a CVE is linked to a CVSS vector. A CVSS vector gives a short view of a vulnerability's characteristics. These characteristics determine its severity. The vector string has metric names and values separated by forward slashes. For example, the following CVSS vector:


Represents a vulnerability with the following metrics: Attack Vector (AV): Local, Attack Complexity (AC): High, Priviledge Required (PR): Low and User Interaction(UI): Required.

The result at the end of the scoring process is what developers and engineers usually exchange when they refer to a CVE: CVE-2023-27536 -

Challenges in vulnerabilities assessment

This section summarizes some of the challenges you might face in doing vulnerabilities assessment and in defining a vulnerabilities assessment process.

CVEs system is not perfect

CVEs, CVSS scoring are not perfect. Some OSS software maintainers have expressed their frustration with reported CVEs that are not really security flaws[4][5]. This is the main cause of CVE disputes. You should look at why the CVE is disputed. This prevents wasting effort in assessing something that is not a vulnerability.

CVSS base score is not accurate

The CVSS base score is the raw score and severity given to a CVE as you find on NVD or other CVEs databases. It doesn't include any environmental, temporal metrics[6]. The CVSS base score is not enough to measure the true severity of a vulnerability. It ignores how and where the affected component is deployed or consumed. The new CVSS 4.0 specification clarifies that the base score alone is not an accurate measure of the severity of a vulnerability. The specification states that the base score (CVSS-B) should be combined with the other metric groups. These include the Threat (CVSS-BT) and Environmental (CVSS-BE) groups.

Populating the Environmental and Temporal metric groups, in addition to the Base score metrics, gives a more precise measure of the vulnerability risk[7]. This enables organizations to prioritize their mitigation efforts and use resources more efficiently.

Keep analysis consistent

It is important to keep analysis consistent when evaluating vulnerabilities. This means the similar/same CVEs should be analyzed in the same way. This is true for the different services it impacts. Also, the analysis should not depend on who is doing it. The same CVE might be evaluated by different engineers on the project. Inconsistency often indicates a lack of a documented process that is shared across the team.

Vulnerabilities hot spots

Vulnerabilities' hot spots are the parts and components of the software dependency tree affected by many CVEs. There are different factors that can lead to vulnerabilities hotspots. It could be an old dependency. Older dependencies usually get more CVEs. Or, it could be a base image that installs many packages.

It is important to identify these hot spots. That said, some parts of a system are more prone to vulnerabilities. For example, config parsing and I/O systems are more sensitive to vulnerabilities. For instance, sometimes a CVE impacts a protocol. For example, CVE-2023-44487 affects the HTTP/2 protocol, which implies that all the components handling HTTP/2 protocol will be vulnerable.

Analyze vulnerabilities

This section contains some tips on how to assess vulnerabilities. It presumes you did everything possible to fix the vulnerabilities in your system. For example, you updated to the latest dependency versions. And you have a system in place (usually a vulns. scan tooling running at CI level across your repositories) for detecting new vulnerabilities.

Early checks

I typically perfrom some early checks before doing an in-depth analysis. The early checks should be documented and shared between the engineers in the team. There are many reasons for performing some early checks:

  • Vulnerabilities analysis tooling might detect false positive.
  • Vulnerabilities data sources are not always accurate.
  • Vulnerabilities are usually affecting section of a dependency.

Below some questions to ask yourself before analyze a vulnerability. The goal of a early checks is to save time by excluding the vulnerability from a more in-depth analysis.

1. Is a false positive?

The tools that find CVEs are not always reliable. They might report false positives[8]. It is better to rule out this scenario first.

Also, the scans tools can have errors at different levels. Most of the tools look for the packages and binaries within a dependency. They compare them with a set of data sources, usually NVD, GitHub Advisory Database, and others. If the CVE metadata in a database is not correct, then the tooling would flag a false-positive. An example is CVE-2023-39017. It affected the quartz-jobs package but also showed up on the quartz package[9].

2. Is the CVE OS-specific?

Some vulnerabilities are effetive only when the affected system run on a certain operating system. If your deployment is not using that OS, then the vulnerability cannot be exploited.

For reference:

It is often not very costly to check if a vulnerability depends on the OS. Therefore, doing this early check usually saves time excluding vulnerabilities affecting a OS not used by your solution.

3. Is the CVE exploitable under any particular condition?

This point builds on the previous one. A vulnerability may only impact some features of a library. For instance, CVE-2023-37276 only affects the HTTP server (i.e. aiohttp.Application) of the aiohttp package. It is possible that your system only uses the HTTP client capabilities of the package. So, the system affected by a vulnerability might be safe.

4. Is the CVE disputed?

Vendors or maintainers might dispute vulnerabilities. Disputes can happen for various reasons, few examples:

  • CVE-2018-20225 the vulnerability is considered a feature of the pip package manager.
  • CVE-2023-45322 is not considered critical enough by the vendor to reserve a CVE ID.
  • CVE-2023-39017 is another disputed vulnerability. The reason is the plausibility of untrusted user input to reach the code where injection could occur.

A disputed CVE is not always a sign of low risk. But, the person who disputes the CVE is usually the maintainer or owner of the affected component. They usually give the background and insights explaining why the CVE is not a security issue. Depending on that the prioritization of the fix might change.

Scoring analysis

The early checks eliminates the vulnerabilities that are not exploitable or do not affect the product. Then, the scoring analysis assess the severity of the vulnerability is for the system. This can be done by populating the additional metrics groups of the CVSS score.[10]

Next there are some questions to consider while populating the additional metrics groups and assessing of the severity.

Is the affected system deployed behind network boundary?

Many vulnerabilities are associated to the Attack Vector: Network metric. The network attack vector establishes that the attack has to be conducted over the network to be successful. If the affected component is in a private network or behind a firewall, the attacker would need to be inside the network to exploit the vulnerability. So, if the system is deployed on a private network, the Modified Attack Vector can be overwritten to Adj. network[11]. This will contribute to reduce the severity of the vulnerability.

Is the affected system running on containers?

The CVSS metrics might have different implications depending on the infrastructure where the vulnerable component is running. For example in case the affected system is deployed in a container orchestration environment (e.g.: Kubernetes) [12].

A vulnerability with Attack Vector: Local means that the attacker needs local access to the system. In a container orchestration system, that would mean that the attacker has high privilege and they can run a local command on a container. So, the privileges needed to launch an attack increases.

Moreover, a vulnerability that enables privilege escalation on a system deployed in a container orchestrated environment would only give the privileges within the container (not the whole host). Therefore, in some cases, the CVSS confidentiality availability and integrity metrics can be lowered.

Populate the Temporal Score metrics

The Temporal score metrics[6:1] measure the current state of exploit techniques. In CVSS 3.1, temporal metrics are defined as:

  • Exploit Code Maturity which measures the likelihood of the vulnerability being attacked.
  • Remediation Level which tracks if there is an official fix or a workaround in place.
  • Report confidence which measures the degree of confidence in the existence of the vulnerability and the technical details related to that.

During analysis, fill in Temporal Score metrics to reflect the status of the vulnerability at the time of the assessment.

An approach to analysed vulnerabilities tracking

As discussed, analysis consistency can be challenging. Specially when the analysis is performed by multiple engineers. A possible solution is to have a set of assessment questions that the engineer should answer when doing vulnerability analysis. Besides that, it is helpful to record in a central place the vulnerabilities previously analysed. One way to do this is to maintain a file with the known vulnerabilities of the system in the git repository(s). If the system is built by many repositories, each service will have its own analysis file. The file should contain the following information for each vulnerability that is analysed:

  • CVE-ID (string): The unique identifier of the vulnerability.
  • Affected component (string): The component affected by the vulnerability. For example: a 3rd-party OSS package or a container image. Note that the version of the affected component should be specified as well. (i.e.: crypthography:38.0.0, <your_registry>/busybox:1.27).
  • Modified score (numeric): The modified score derived from the analysis and the modified CVSS vector.
  • Modified CVSS vector (string): The modified CVSS vector derived from the assessment.
  • Analysis details (text): A text that briefly explains the reasoning behind the analysis that has been done.

The fields above would be repeated for each assessed vulnerability, and they can be stored on a versioned file in any format: JSON, YAML, Markdown. By documenting the examined vulnerabilities and adding them to the repositories, there are several benefits:

  • You can keep track of all the analysis in one place and everything is versioned. An engineer can look at previous analysis and take them as reference or correct them.
  • If you use git tags or release branches to deploy the service, you will have an analysis file for each release. Therefore you can check the status of the vulnerabilities at each release point.
  • You can track the history of the analysis using git history.
  • It is easy to add automation to the CI pipeline (e.g.: alerting the internal security team in case a new vulnerability is detected but not analyzed yet).

Vulnerabilities in container images

Today, a lot of production software runs container orchestration systems (e.g. Kubernetes). Orchestration systems comes with Cloud-native patterns, e.g.: sidecar containers and container injection. These patterns can be useful and efficient in some cases. But, they also force you to depend on a high number of container images[13]. This can pose some problems. A container image might have a lot of packages and dependencies which are vectors for vulnerabilities.

Minimal container images come handy here. Make sure you have only the minimum dependencies to run your app. Also, have the correct pre-configured nonroot user. Scratch or distroless images are good for these cases. Canonical recently presented an interesting set of toolings inspired by distroless images, called "chisel"[14]. Chisel produces "chiselled images": it lets you create images with a subset of Debian packages. It is based on the idea that a package (let's call it package A) which depends on another package (package B) only uses some of package B's files. So, we can chisel package B to cut the unnecessary content. This will reduce the chance of vulnerabilities.

Finally, before adding a container image as a dependency of your system, check if the image follows best practices.

  • Is there a nonroot user set up in the image?
  • Does the image come from a reputable vendor?
  • Is the image creation process open-sourced?
  • How often is a new version of the image released per month?
  • In case a CVE impacts the image, how does the source release a fixed version of the image?
  • In case a CVE impacts the image, does the vendor fix all the major versions of the image or only the most recent one?
  • If you are running on a containerized environment, make sure to use minimal container images.

The considerations above might help you reduce the number of vulnerabilities to assess in your container-based system.

Prioritize mitigation with EPSS is introducing a new scoring system called EPSS. The definition is:

The Exploit Prediction Scoring System (EPSS) is a data-driven effort for estimating the likelihood (probability) that a software vulnerability will be exploited in the wild.

A detailed explanation of EPSS can be found in the paper: Enhancing Vulnerability Prioritization: Data-Driven Exploit Predictions with Community-Driven Insights.

EPSS doesn't measure the risk of a vulnerability, but the probability for the vulnerability to be exploited. So, if we combine the EPSS and CVSS scores, we can see the chance of a vulnerability being exploited and the impact of the exploit. This can help organizations prioritize their vulnerability management. It can also help them allocate resources better.

Final thoughts

This post went through the lifecycle and the challenges in assessing vulnerabilities. The few takeaways:

  • There is no doubt that vulnerabilities must be fixed. Try your best to keep updated all the 3rd party components consumed by your software.
  • The ecosystem surrounding CVEs and CVSS works, but is not perfect. Don't blindly accept the severity of a CVE as accurate.
  • CVSS Base score does not reflect the true impact of a vulnerability on your system. To get a accurate severity, you need to assess the CVE in relation to your system and populate the additional CVSS metrics.
  • Establish a method for identifying, evaluating, and tracking CVEs.
  • Do whatever you could to keep the container images as slim as possible.

  1. A partner is a trusted source participating to the CVE program. It could be a company or an organization. A Partner could be also a CVE Numbering Authority (CNA) that assigns new CVE IDs. The list of partners is available on ↩︎

  2. For example, the Apache Software Foundation (ASF) has an established security policy. That said, usually the new vulnerabilities are reported in-private directly in the project security mailing list. ↩︎

  3. At the time of writing, NVD is delaying the analysis of vulnerabilities and addressing challenges in the NVD program. More details available at Death Knell of the NVD? - Resilient Cyber ↩︎

  4. CVE-2020-19909 is everything that is wrong with CVEs | ↩︎

  5. PostgreSQL: CVE-2020-21469 is not a security vulnerability ↩︎

  6. Starting from CVSS 4.0 the "Temporal score metrics" have been renamed to "Threat metrics". ↩︎ ↩︎

  7. Announcing CVSS v4.0 - ↩︎

  8. The vuln. detection tools can detect false positive/false negatives. Here is two lists: Trivy false positive reports and Grype false positive reports ↩︎

  9. See the following GitHub issue quartz-scheduler - #943. The discussion in the issue highlights multiple problems related to the CVE. From the wrong package associated to the vulnerability to the "indefensible" CVSS 3.1 base score. ↩︎

  10. There are multiple CVSS tools online for populating the additional metrics groups. Few examples: NVD - CVSS v3 Calculator, Common Vulnerability Scoring System Version 3.0 Calculator. You can copy and paste the CVSS vector of the vulnerability and start populating the metrics. ↩︎

  11. See "Table 1: Attack Vector" for a description of the "Adjacent" metric in CVSS v3.1: Specification Document ↩︎

  12. Containers vulnerability risk assessment - Red Hat Blog discusses how the impact of vulnerabilities on containerized environments can differ from traditional operating systems by providing some concrete examples. ↩︎

  13. The container images are usually fetched from, or built by 3rd party providers. Some examples on top of my mind are Istio or Ingress NGINX controller image. ↩︎

  14. Github - canonical/chisel ↩︎