Hi Richard,
hi all,

I want to address a flaw in the current CPE generation functionality in
openembedded, which renders the CPEs unusable in regards to the minimal
requirements of the NIST CPE Name Matching Specification standard
(https://nvlpubs.nist.gov/nistpubs/Legacy/IR/nistir7696.pdf).

This makes working with the generated CPEs in thirdparty software close
to impossible, as it would require the thirdparty software to implement
matching logic beyond the requirements defined in the NIST standard.


Status quo:

Currently, the CPE is generated from the optional CVE_PRODUCT
(optionally including the vendor) and CVE_VERSION variables. If neither
are provided, CPE generation will fall back on the BPN and PV of the
recipe.

As a result, the generated CPE will usually look as follows:

cpe:2.3:*:*:${BPN}:${PV}:*:*:*:*:*:*:*:*

Or, if the CVE_PRODUCT includes a vendor:

cpe:2.3:*:${vendor}:${product}:${PV}:*:*:*:*:*:*:*:*



The Issue (The TL;DR):

This will return zero¹ matches when doing CPE matching against CVE CPEs
in accordance with the minimal requirements of the NIST Name Matching
Specification. For reliable matches the components CPE should be as
precise as possible, i.e. not containing any "*" (ANY) values for vital
attributes, such as: Part, Vendor, Product, Version, Target_HW.



The Issue (In detail):

To understand the issue in full detail, in depth knowledge of the NIST
specification is required. However, I will try to provide a
comprehensive summary below:

CPE matching is done using a source CPE and target CPE. Due to
limitations (see Table 6-2, cases 4 & 11), using the CVE CPE as a
source and the component CPE as a target is the only sensible way
(otherwise a CVE CPE containing wildcards would lead to undefined
behavior).

Each attribute of the CVE CPE, will then be matched against the
component CPE, setting the relationship of each source attribute to the
corresponding target attribute to either superset (⊃), equal (=),
subset (⊂) or disjoint (≠) (see Table 6-1, example: Table 6-3).

The NIST standard then defines 4 required CPE Name Comparison Relations
(see Table 6-4), with two of them relevant for what we would consider a
"match" between a CVE CPE and a component CPE:

If all attribute relations are EQUAL (=) -> Then CPE name relation is
EQUAL (=) -> match

If all attribute relations are SUPERSET (⊃) or
EQUAL (=) -> Then CPE name relation is SUPERSET (⊃) -> match

Let's take a look at this, based on a real-world example:

CVE CPE: cpe:2.3:o:linux:linux_kernel:5.15.37:*:*:*:*:*:x86:*:*
Component CPE: cpe:2.3:*:*:linux_kernel:5.15.37:*:*:*:*:*:*:*:*

In this example the CVE CPE has the attributes "Part" ("o"), "Vendor"
("linux") and "Target_HW" defined, while the Component CPE sets these
attributes to "ANY", thus the CVE CPE attributes are subsets of the
component CPEs (see Table 6-2, case 13), making the entire CVE CPE a
subset of the component CPE, thus causing a false-negative.



Proposed solution:

Openembedded should, in accordance with the CPE Naming Specification
(https://nvlpubs.nist.gov/nistpubs/Legacy/IR/nistir7695.pdf), provide
complete and accurate CPE information (at least: Part, Vendor, Product,
Version, Target_HW) for recipes in order to avoid false-negatives
during CVE CPE comparison and ensure compatibility with other tools.

A component CPE could then look like this (something I came up with in
5 minutes, enjoy with a grain of salt):

cpe:2.3:o:linux:linux_kernel:5.15.37:<COMPONENT_SHA_COMMIT_HASH>:*:open
embedded:<OPENEMBEDDED_RELEASE>:<TARGET_ARCH>:en_US (is there a bitbake
variable for this?):*

Setting attributes such as SW_Edition = "openembbeded" and Target_SW =
"<OPENEMBEDDED_VERSION>" also has the positive side-effect of allowing
for the registration of openembedded-specific CVEs, e.g.
vulnerabilities in patches within recipes.

Of course, this is easier said than done, as some of the required
information, especially "Part" and "Vendor" is missing from existing
recipes.

I therefore, suggest the following approach:

Step 1 (non-intrusive): 

Introduce a new, optional variable CVE_PART, which is set to "a"
(application) by default but may be overridden in a recipe (e.g. for
linux_kernel)

For consistency: Introduce the new, optional variable CVE_VENDOR as a
replacement for the CVE_PRODUCT "double role" (for backwards
compatibility, we can evaluate CVE_VENDOR first, then check for a
vendor within CVE_PRODUCT).

Adding already existing information from the build (e.g. Target_HW) to
the CPE.

Start filling in CVE_VENDOR for core recipes (openembedded-core).

Optional: Step 2 (enforcement):

Once a certain threshold of recipes with complete information is
reached, we might want to consider enforcing explicit CVE_* variable
declaration by default, with an option for disabling this behavior
(e.g. introducing a variable CVE_UNKNOWN), similar to the LICENSE
variable bahavior.


I hope I was able to give some insights on why I believe that
improvements to the openembedded CPE generation process, as well as to
information provided by the recipes (even though a diligent task) are
vital.

I am looking forward to your feedback on this.

Cheers,
Jasper


¹: This is also partly due to my
commit 
https://git.openembedded.org/openembedded-core/commit/?id=e7c1def3c3c3a72249802ef6fb64292277a7a53e
which, while technically correct, makes a bad situation even worse.
Still, only a handful of recipes which happen to be of type
"application" and explicitly set the "vendor" attribute, had the chance
to successfully match some (but not all) CVE CPEs. False negatives
would still lie at > 99%.


-- 
With best regards

Jasper Orschulko
DevOps Engineer

Tel. +49 30 58 58 14 265
Fax +49 30 58 58 14 999
jasper.orschu...@iris-sensing.com

• • • • • • • • • • • • • • • • • • • • • • • • • •

iris-GmbH
infrared & intelligent sensors
Ostendstraße 1-14 | 12459 Berlin

https://iris-sensing.com/

-=-=-=-=-=-=-=-=-=-=-=-
Links: You receive all messages sent to this group.
View/Reply Online (#186724): 
https://lists.openembedded.org/g/openembedded-core/message/186724
Mute This Topic: https://lists.openembedded.org/mt/100962508/21656
Group Owner: openembedded-core+ow...@lists.openembedded.org
Unsubscribe: https://lists.openembedded.org/g/openembedded-core/unsub 
[arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-

Reply via email to