Wednesday, February 8, 2023

OpenVEX is neither open nor VEX


Last week, a big announcement was made by Chainguard, a software supply chain security tools vendor, that they had developed, along with six other organizations, a specification for a new VEX format called OpenVEX. This was followed within a couple of days by a web presentation to the Open Source Software Foundation’s Vulnerability Disclosures Working Group, at which Chainguard’s founder Dan Lorenc, and the two leaders of the CISA VEX working group (one a CISA employee (!), the other now a private consultant) praised the new spec and made a (completely erroneous) derogatory comment about one of the two existing VEX formats. It was also followed by publication of a Security Week interview with Dan Lorenc, which contained at least four total falsehoods, although I doubt Dan even knew they were false.

There are two big problems with the OpenVEX spec:

1.      It’s not “open”, since it purports to be the only VEX format that’s completely “compliant” with the contents of an unfinished document being developed by the CISA VEX working group. Even when it’s finished and published, the document will not in any way be a “standard”, “requirement”, “specification”, “papal encyclical”, or anything else that’s compulsory. I’ll elaborate on this statement in another post, coming soon to an inbox near you.

2.      It’s not VEX, as I’ll discuss in this post and (hopefully) the next one.

If OpenVEX isn’t VEX, what is VEX? It would be nice if there were a published VEX definition or specification, but unfortunately, there isn’t one[i] – and the document that’s still unfinished won’t be anything close to that[ii]. The closest thing to an “official” VEX definition is what’s found on pages 1-3 of the VEX Use Cases document. But unofficially, by far the best “definition” of VEX is the document drafted by Dr. Allan Friedman in 2021, when the VEX working group was still under the auspices of the NTIA. Unfortunately, that document was never published (although I recommended last year to the working group – then as now under CISA – that it be updated and published. It would still be worthwhile to do that, but I’m sure it won’t happen).

Here's my VEX “definition”: VEX is a concept that was developed by members of the NTIA Software Component Transparency Initiative to address a specific problem that was identified as part of that initiative. The problem was that a huge percentage of vulnerabilities (almost certainly over 90%), that have been separately identified in components that are included in an SBOM for a software product or an intelligent device (collectively, a “product”), and which are publicly reported (usually to CVE.org), aren’t in fact exploitable in the product itself.

Therefore, if end users, after receiving an SBOM and identifying vulnerabilities for components, start searching for those vulnerabilities on their networks and contacting the product supplier about them, a huge amount of time and effort will be wasted by both software users and suppliers’ help desk employees in discussing these false positive observations (i.e., more than 9/10 of the time and effort will be wasted). This isn’t a sustainable situation, of course. Suppliers need to have a way of reliably and efficiently notifying their customers of non-exploitable component vulnerabilities in the products they operate. Until they have that, they won’t regularly distribute SBOMs to their customers.

It wasn’t foreordained that the solution to this problem would be a format. Yet, since the issue arose due to the imminence of distributing formatted SBOMs in volume to software customers[iii], it seemed natural that the solution to the problem would also be a format. While neither I nor anyone else questioned this at the time (I attended the second weekly meeting of the VEX working group in the summer of 2020 and have missed few meetings since then), it’s clear to me now that focusing immediately on documents was a mistake. I now think my real-time VEX API proposal is the best way to address the most important VEX use, which I just described. There are still other use cases for VEX documents, but if we can address by far the most important use case – and the one that VEX was designed to address – this year, we will have made a huge leap forward.

However, not only does OpenVEX not address the most important VEX use case at all (or even understand what it is), but it would actually set users back. This is because it will take away what will be a capability needed by probably a majority of suppliers. This is the ability to specify the exploitability status of a vulnerability in multiple versions of a product, not just the product itself – and especially in a range of versions. The reason this is necessary is simple: Almost any commercial product has versions. If there weren’t versions, the product would literally be unsupportable (as Bruce Lowenthal, Oracle’s Senior Director of Product Security, has pointed out regularly in past VEX working group meetings).

True, there are some open source projects that don’t have versions, but both private sector and government organizations run primarily on commercial software (which includes open source software that is supported by a commercial organization like Red Hat™). Essentially, private sector and government organizations want one throat to choke when there are problems; having to beg an open source project team to invest some of their own time to fix a problem just doesn’t appeal to most organizations. Since it’s almost never the case that all versions of a software product have the same status with respect to one vulnerability – i.e., they’re all affected or they’re all not affected – a VEX document that doesn’t support versions is literally useless for the great majority of private and public sector organizations.

However, not only must a VEX format support product versions, but it must support version ranges. After all, an exploitable vulnerability almost always is identified in a product at some point in its lifecycle – very seldom was it "baked into” the product when it was first developed. While it’s essential to make VEX statements like “Versions 2.1 and 2.2 are affected by CVE-2023-12345. All other versions are not affected”, that’s not sufficient. It’s also essential to be able to say, “All versions of Product A before version 6.5 are not affected…”

But OpenVEX doesn’t have a separate field for version numbers. To specify a specific version of a product, you need to construct a synthetic “product”, consisting of the product name and the version number.[iv] That is, in order to say “Version 3.7 of Product B”, you need to create a “product” named “B v3.7” or something like that, and then state the status of the vulnerability with respect to that “product”. Since OpenVEX allows only one product per statement, there needs to be a separate statement for each version.

For example, if you wanted to say that Product C Versions 3.1.5 and 3.2.0 are subject to a particular vulnerability, you would in effect need to write, “C 3.1.5 is affected by CVE-2021-54321” and “C 3.2.0 is affected by CVE-2021-54321”. Annoying, right? Well, now try to say that all versions before version 10.5.0 are subject to CVE-2022-98765. You would have to create a statement for every version.

How hard can that be? Quite hard, as it turns out. Consider that, for VEX purposes, every patch version, every new build, etc. needs to be a separate version number, along with of course every major and minor version. It’s not out of the question that a version range would include more than 1,000 versions. Guess how many statements that would take in OpenVEX? You got it…1,000. Now, how many statements would this take in CycloneDX VEX? One. You would have to write, in effect, “vers:generic/>=1.0.0|<=10.5.0 is not affected by CVE-2022-98765”.[v]

In my (hopefully) next post, I will discuss the second reason why OpenVEX isn’t VEX: the fact that it doesn’t address the main VEX use case.

Any opinions expressed in this blog post are strictly mine and are not necessarily shared by any of the clients of Tom Alrich LLC. If you would like to comment on what you have read here, I would love to hear from you. Please email me at tom@tomalrich.com.


[i] People often point to this one-page NTIA document as the “definition” or “specification” of VEX. It was indeed intended to be that at the time it was written (which I can say with confidence because I drafted it). However, we were all thinking then that there was no need to go into details. This was because we were sure there would soon be fully automated tools that would both create and consume VEX documents, without the user needing to know anything at all about the specification. Of course, those tools have never appeared, and none are currently on the horizon.

Since now there are two ways to create VEX – using CSAF or using CycloneDX VEX - which are very different from each other, there need to be two specifications. There will never be a single VEX uber-specification. Tools to produce and consume VEX documents in either format will need to wait for the specification for that format. Nobody will invest time or money in creating a tool without a firm specification to base it on. 

[ii] In fact, the unfinished document has had at least five titles. One of them was something like “VEX Specification”. When it became too obvious that the document was anything but that, the title was changed to “VEX Data Model”. And when that was shown to be a misnomer, the title was changed over the holiday break to “Minimum Requirements for VEX”. None of these title changes was ever discussed in advance with the working group – they simply appeared in the document, with little or no justification provided. There were other “magical” changes to wording in the document as well, presumably inserted by little green men from Mars. 

[iii] Unfortunately, distribution of SBOMs is just as “imminent” today as it was in the summer of 2020, when the VEX working group first started meeting. While use of SBOMs by suppliers – for their internal product risk management purposes – has skyrocketed in the last five years, it has yet to take off in any meaningful sense for the 99.5% of public and private organizations whose primary business isn’t developing software. 

[iv] This is also the case with CSAF. 

[v] The CycloneDX VEX format doesn’t support version ranges for all version formats – only the large number that are included in the Version Range Specifier (AKA “VERS”). Essentially, there needs to be some way to determine with precision whether a particular version falls within a range. For example, if the range is “4.2.0 to 5.0.9”, a version identified as “4.4.7” will definitely fall between 4.4.6 and 4.5.0; this version format is one of the formats supported by VERS. 

However, it’s impossible to precisely locate a version identified as “4.3a patch 015”. There will never be a way for a VEX consumption tool to properly interpret a range based on version strings like that one, unless the supplier itself creates code that can be incorporated into the consumption tools. This might happen at some point, but each supplier would have to create their own code and provide a way to update all VEX consumption tools that are available. This would also require that the supplier has consistently applied their proprietary versioning rules, which might not always be the case – especially for acquired products.

 

No comments:

Post a Comment