cpe
cpe copied to clipboard
CPEs with just one (or very few?) (wfn) attributes will cause wrong 2.3 uris
We import a (non-official) dictionary from a corporate security advisory service provider, which contains some generic cpes that just have vendor, product or version set.
(No idea for what internal purpose they're being used at the vendor, but if we import them, they land in our (customers) database.)
I'll work on a PR for this today, but first I wanted to give you a description of the behaviour we see.
(with python 2 in current 1.2.0)
cpe_uri2_3_test.py:
#!/bin/env python
import cpe
import cpe.cpe2_3_uri
for uri in """
cpe:/a
cpe:/:vendor
cpe:/::product
cpe:/:::version
cpe:/::::update
cpe:/:::::edition
cpe:/:::::~edition~sw_edition~target_sw~target_hw~other
cpe:/:::::~~~~target_hw~
cpe:/::::::en
""".split():
c = cpe.cpe2_3_uri.CPE2_3_URI(uri)
print(("original uri: \"{uri}\":\n"
" as wfn: {wfn},\n"
" as uri_2_3: \"{uri2_3}\"\n").format(
uri=uri,
wfn=c.as_wfn(),
uri2_3=c.as_uri_2_3()))
Outputs:
original uri: "cpe:/a":
as wfn: wfn:[part="a"],
as uri_2_3: "::::cpe:/a"
original uri: "cpe:/:vendor":
as wfn: wfn:[part=ANY, vendor="vendor"],
as uri_2_3: "cpe:/::::vendor"
original uri: "cpe:/::product":
as wfn: wfn:[part=ANY, vendor=ANY, product="product"],
as uri_2_3: "cpe:/::product"
original uri: "cpe:/:::version":
as wfn: wfn:[part=ANY, vendor=ANY, product=ANY, version="version"],
as uri_2_3: "cpe:/:::version"
original uri: "cpe:/::::update":
as wfn: wfn:[part=ANY, vendor=ANY, product=ANY, version=ANY, update="update"],
as uri_2_3: "cpe:/::::update"
original uri: "cpe:/:::::edition":
as wfn: wfn:[edition="edition"],
as uri_2_3: "::::cpe:/:edition"
original uri: "cpe:/:::::~edition~sw_edition~target_sw~target_hw~other":
as wfn: wfn:[part=ANY, vendor=ANY, product=ANY, version=ANY, update=ANY, edition="edition", sw_edition="sw_edition", target_sw="target_sw", target_hw="target_hw", other="other"],
as uri_2_3: "cpe:/:::::~edition~sw_edition~target_sw~target_hw~other"
original uri: "cpe:/:::::~~~~target_hw~":
as wfn: wfn:[part=ANY, vendor=ANY, product=ANY, version=ANY, update=ANY, edition=ANY, sw_edition=ANY, target_sw=ANY, target_hw="target_hw", other=ANY],
as uri_2_3: "cpe:/:::::~~~~target_hw~"
original uri: "cpe:/::::::en":
as wfn: wfn:[part=ANY, vendor=ANY, product=ANY, version=ANY, update=ANY, edition=ANY, language="en"],
as uri_2_3: "cpe:/::::::en"
- Part alone yields very funny results, fortunately our third-party dictionary is not that weird.
- vendor alone lands in the update attribute of the uri
- version alone is correct
- update alone is correct
- legacy edition has leading colons
- packed edition is correct (also with missing attributes) (in that last case we have apparently an additional bug in our software which I can't reproduce with cpe alone)
- language alone is correct
I'll try to come up with testcases and PR later today (since I know your time is constrained and we'd like this to work soonish).
(Also I'm not sure if the wfn for just the legacy edition is correct. I'm trying to make sense of NISTIR 7695 if the ANY values in the wfn string are required or not. You seem to assume they are required, at least they're consistently present in every other case.)
Hi, sorry for the long delay, I'm not having much time lately for maintaining the package. I've merged #29 and uploaded version 1.2.1. I've seen the tests marked as xfail, but I don't know what should be the proper behavior here. Maybe @galindale can help here...
Hi,
I'm afraid the current implementation of the cpe library about WFN to URI conversion is wrong. In the second step of the section 6.1.3.1 called "Summary of algorithm", the standard specification (NISTIR-7695-CPE-Naming) says:
For URI components 1-5 and 7, decode the string and set the corresponding WFN attribute value. Decoding entails: converting sole "" to ANY, sole "-" to NA, adding quoting to embedded periods and hyphens, and decoding percent-encoded forms.
Therefore, the part, vendor, product, version, update and language components must always appear in the WFN although they are empty. The edition component WFN value depends on if its URI value is packed or not.
For example, the correct WFN of URI "cpe:/a" is:
wfn:[part="a", vendor=ANY, product=ANY, version=ANY, update=ANY, edition=ANY, language=ANY]
not:
wfn:[part="a"]
It's necessary to review the implementation of converter from URI to WFN with CPEs version 2.3.
For instance, I saw that in the line 383 of cpe2_3_uri module there is a wrong continue statement (the attribute is not set) instead of setting ANY value with "v.append(CPEComponent2_3_WFN.VALUE_ANY)".
In the case of binding a WFN to a URI some components can disappear if they have empty values. For example:
wfn:[part="a",vendor="microsoft",product="internet_explorer",version="8\.0\.6001",update="beta",edition=ANY]
binds to the following URI (edition part is missing because trailing colons are removed):
cpe:/a:microsoft:internet_explorer:8.0.6001:beta
I hope my explanation helps you @TauPan. Thank you very much for your pull request and your tests.
Hm, interesting. Thanks @galindale for pointing out how the reference implementation works.
However I see in Section 5.2 (WFN Attributes): Each permitted attribute MAY be used at most once in a WFN. If an attribute is not used in a WFN, it is said to be unspecified, and its value SHALL default to the logical value ANY (cf. 5.3.1)
So it appears the current implementation conforms to that statement. I think it's a design choice if you want to conform to the reference implementation which is more strict (i.e. not omitting any attributes) or if you want to conform to the more lenient statement that omitting attributes in a wfn is permissible.