Last December in the annual CNA
Workshop run by CVE.org, an important issue was
brought up during a presentation by Lisa Olsen of Microsoft. I wrote in my
post:
Lisa pointed out that in some CVE
reports, the “affected” version of the product refers to the fixed version of
the product (i.e., the version to which the patch has been applied), while in
other reports (usually from different CNAs), the “affected” version is the
unpatched version.
This is a huge difference, since it
means some organizations may be applying patches to versions of a product to
which the patch has already been applied. Lisa said the new CVE schema will
allow the CNA (which is in many cases the developer of the affected product) to
indicate which case applies. However, it seems to me there should be a rule:
The “affected” product is always the one in which the vulnerability has not
been patched.
It's good that the new CVE schema will allow the CNA to
indicate whether the vulnerability is found in the patched or the unpatched
version of the product, but I was surprised there should be any question about
this: After all, only the unpatched version of the product is vulnerable to the
CVE, so in my opinion – at least at the time – there should be a rule that the
CVE always applies to the unpatched version (frankly, I was surprised that
Microsoft seems to take the opposite position). However, I now realize it’s
more complicated than that, and there are two other serious questions that come
into play here.
The first of those questions is how the supplier will
distinguish between the patched and the unpatched versions of the product. I
have always assumed that, when a patch is applied to a software product, the
version number will automatically change to a new one; for example, if the
product follows “semantic versioning”, when a
patch is applied to version 5.2.0 of a product, the patched version might be numbered
5.2.1. In this example, when the supplier reports the vulnerability, they will list
v5.2.0 in the CVE record, if they follow my rule.
Of course, this is done so that, when a software user learns
that version 5.2.0 of a product they use is affected by a new CVE, they will check
to see which version they are using. If it’s v5.2.0, they will download and
apply the patch. But if it’s v5.2.1, they will know they’re already running the
patched version.
However, a lot of software suppliers (both commercial and
open source suppliers) don’t change the version number when a patch is applied.
Instead, the user needs to do something else to learn what patches are
installed on their system. In Microsoft Windows, Windows Update or PowerShell provides
this information, but it doesn’t automatically find its way into a CVE record
for a product.
Of course, it all software suppliers were required by
CVE.org (in the best practices sense, not the regulatory sense) to follow
semantic versioning or a similar versioning scheme, it might be possible always
to represent the patched version of a product with a different version string –
derived by following a particular rule – than the version string used by the unpatched
version. Would that solve our problem?
No, it wouldn’t. To understand why, you should review this post
in which Bruce (whom I just referred to as “the Director of Project Security of
one of the largest software developers in the US”) pointed out that developers
often release multiple patches in between two consecutive versions of the
product; it is up to the user to decide which of those patches, if any, they
wish to apply[i].
This means that, until a new version is published (in which
all patches released since the last version are included), the supplier will
never know which patches are on a particular user’s system, unless they ask the
user to tell them (perhaps during a help desk call). Since a version string
that took account of patches would need to represent each of the patches that
has been applied since the last version (major or minor) was released, this
would make it very difficult to accurately represent all those patches.
To illustrate this problem, suppose there have been five
patches released since the last version of a product, conveniently numbered
1,2,3,4, and 5 (of course, real patch numbers are much more complicated).
Suppose a user had applied patch numbers 1, 3 and 4, but not 2 and 5. The
version string for their instance of the product might be 5.2.1_3_4, or
something like that. A user that had just applied patches 3 and 5 would see the
version string 5.2.3_5.
Now let’s say the supplier wants to report a new
vulnerability in their product. Since they shouldn’t report the vulnerability
until they have a patch available for it, let’s suppose this is the sixth patch
since the 5.2.0 release of the product. What will the patched version be
called? It will have to depend on which of the previous five patches the user
has applied. For example, if the user had applied patches 1 and 4, the new
version would be called v5.2.1_4_6; if the user had applied patches 2,3, and 4,
the new patch would be v5.2.2_3_4_6, etc.
This isn’t just a numbering problem. Since the code for a
patch often varies depending on which patches have already been applied, the
developer may need to develop a different new patch for each combination of
previously applied patches. Bruce calculated that the number of patches[ii]
that may be needed is equal to 2 raised to the number of independent patches
that have been issued since the last update. In the above example with six
patches, this is 2 to the sixth power, or 64. If there are 10 independent patches,
the total number of new patches required is 1,024. Needless to say, it isn’t
possible to develop this many patches whenever a single new patch is needed.
In other words, my idea that a patched version of a software
product could be distinguished from the unpatched version simply by changing a
number will not work in practice. Our original question (the one Lisa Olsen discussed
in the CNA Workshop in December) was whether the CVE record should refer to the
patched or the unpatched version.
The answer is that, since there might be hundreds of “patched
versions” applying to a single unpatched version, there is no good way to use
versioning as a way to distinguish patched from unpatched products. Of course,
this is why patch reports are usually very complicated documents, such as this
one from Oracle (chosen at random).
Naturally, this is a disappointment. I originally thought the
problem Lisa brought up could be easily solved, but that’s far from being the
case. So, how can it be solved? Like almost every complicated problem,
it requires people with a stake in solving the problem to get together
(presumably virtually) to work out an acceptable solution. It won’t be a thing
of beauty, of course, but hopefully it will at least be usable.
Who are the people with a stake in this problem and how will
they get together? In my previous post,
I called for a proof of concept for introducing purl identifiers into the CVE
ecosystem. That PoC will gather stakeholders in the vulnerability management
process, including software developers, CNAs, and vulnerability database
operators. Since one of the objectives of the PoC will be to identify new or
changed “rules of the road” for reporting new vulnerabilities in CVE records,
and since this question very much involves one of those rules of the road, it
would be appropriate to include a discussion (and hopefully resolution) of this
problem in the proof of concept.
I will put this in the to-do list for the PoC. Please join
us for this project. Email me at tom@tomalrich.com
to discuss participating in the project (or at least the initial planning
phase) and/or financially supporting the project by donating to OWASP.
My book "Introduction to SBOM and VEX" is available in paperback and Kindle versions! For background on the book and the link to order it, see this post.
[i] Sometimes,
developers release “cumulative” patches, meaning one patch will include all
previous patches. However, suppose a supplier releases a cumulative patch C,
which includes patches A and B. A user doesn’t want to apply Patch A (because
of a possible incompatibility with their instance of the product), but they’d
like to apply C. Obviously, they can’t do that. This is one reason why
cumulative patches aren’t the norm in the software industry.
[ii] The
2023 post was about SBOMs, but the argument applies equally to patches.