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] -=-=-=-=-=-=-=-=-=-=-=-