Skip to content

Commit c6368b9

Browse files
sacca97copernico
authored andcommitted
extracting version from the apposite section of the NVD json response and not from text (more accurate when available)
1 parent 49bfe5d commit c6368b9

File tree

2 files changed

+73
-17
lines changed

2 files changed

+73
-17
lines changed

prospector/datamodel/advisory.py

Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ def __init__(
6161
# references: List[str] = None,
6262
# references_content: List[str] = None,
6363
affected_products: List[str] = None,
64-
versions: List[Tuple[str, str]] = None,
64+
versions: Dict[str, List[str]] = None,
6565
files: Set[str] = None,
6666
keywords: Set[str] = None,
6767
):
@@ -72,17 +72,17 @@ def __init__(
7272
self.references = references or dict()
7373
# self.references_content = references_content or list()
7474
self.affected_products = affected_products or list()
75-
self.versions = versions or list()
75+
self.versions = versions or dict()
7676
self.files = files or set()
7777
self.keywords = keywords or set()
7878

7979
def analyze(
8080
self,
8181
fetch_references: bool = False,
8282
):
83-
self.versions = [
84-
version for version in self.versions if version[0] != version[1]
85-
]
83+
# self.versions = [
84+
# version for version in self.versions if version[0] != version[1]
85+
# ]
8686
# self.versions.extend(extract_versions(self.description))
8787
# self.versions = list(set(self.versions))
8888

@@ -92,7 +92,7 @@ def analyze(
9292
# TODO: this could be done on the words extracted from the description
9393
self.files.update(extract_affected_filenames(self.description))
9494

95-
self.keywords.update(extract_words_from_text(self.description))
95+
self.keywords.update(set(extract_words_from_text(self.description)))
9696

9797
logger.debug("References: " + str(self.references))
9898
# TODO: misses something because of subdomains not considered e.g. lists.apache.org
@@ -105,11 +105,6 @@ def analyze(
105105
# TODO: I should extract interesting stuff from the references immediately ad maintain them just for a fast lookup
106106
logger.debug(f"Relevant references: {len(self.references)}")
107107

108-
# if fetch_references:
109-
# self.references_content = [
110-
# " ".join(str(fetch_url(r)).split()) for r in self.references
111-
# ]
112-
113108
def get_advisory(self):
114109
data = get_from_local(self.cve_id)
115110
if not data:
@@ -125,13 +120,28 @@ def parse_advisory(self, data):
125120
self.last_modified_timestamp = int(isoparse(data["lastModified"]).timestamp())
126121
self.description = data["descriptions"][0]["value"]
127122
self.references = [r["url"] for r in data.get("references", [])]
128-
self.versions = [
129-
(
130-
item.get("versionStartIncluding", item.get("versionStartExcluding")),
131-
item.get("versionEndExcluding", item.get("versionEndIncluding")),
132-
)
133-
for item in data["configurations"][0]["nodes"][0]["cpeMatch"]
123+
self.versions = {
124+
"affected": [
125+
item.get("versionEndIncluding", item.get("versionStartIncluding"))
126+
for item in data["configurations"][0]["nodes"][0]["cpeMatch"]
127+
], # TODO: can return to tuples
128+
"fixed": [
129+
item.get("versionEndExcluding")
130+
for item in data["configurations"][0]["nodes"][0]["cpeMatch"]
131+
],
132+
}
133+
self.versions["affected"] = [
134+
v for v in self.versions["affected"] if v is not None
134135
]
136+
self.versions["fixed"] = [v for v in self.versions["fixed"] if v is not None]
137+
138+
# [
139+
# (
140+
# item.get("versionEndIncluding"), # item.get("versionStartExcluding")
141+
# item.get("versionEndExcluding"), # , item.get("versionEndIncluding")
142+
# )
143+
# for item in data["configurations"][0]["nodes"][0]["cpeMatch"]
144+
# ]
135145

136146

137147
def get_from_nvd(cve_id: str):

prospector/datamodel/advisory_test.py

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import time
2+
13
from datamodel.advisory import AdvisoryRecord, build_advisory_record
24

35
ADVISORY_TEXT = """Unspecified vulnerability in Uconnect before 15.26.1, as used
@@ -15,6 +17,42 @@
1517
but not further above (thus "limited" path traversal), if the calling code would
1618
use the result to construct a path value."""
1719

20+
cve_list = """
21+
CVE-2020-13924
22+
CVE-2020-11987
23+
CVE-2020-17516
24+
CVE-2021-25640
25+
CVE-2020-11995
26+
CVE-2021-25646
27+
CVE-2020-13922
28+
CVE-2020-17514
29+
CVE-2020-11997
30+
CVE-2020-9492
31+
CVE-2020-1926
32+
CVE-2020-13950
33+
CVE-2020-35452
34+
CVE-2021-20190
35+
CVE-2020-27223
36+
CVE-2020-9493
37+
CVE-2020-17534
38+
CVE-2021-21295
39+
CVE-2021-25958
40+
CVE-2020-17532
41+
CVE-2020-17523
42+
CVE-2020-1946
43+
CVE-2020-17525
44+
CVE-2020-13949
45+
CVE-2021-25122
46+
CVE-2020-17522
47+
CVE-2020-13936
48+
CVE-2020-13959
49+
CVE-2021-23926
50+
CVE-2020-11988
51+
CVE-2019-10095
52+
CVE-2020-13929"""
53+
54+
test = """The Apache Beam MongoDB connector in versions 2.10.0 to 2.16.0 has an option to disable SSL trust verification. However this configuration is not respected and the certificate verification disables trust verification in every case. This exclusion also gets registered globally which disables trust checking for any code running in the same JVM."""
55+
1856

1957
def test_advisory_basic():
2058
adv = AdvisoryRecord(
@@ -42,3 +80,11 @@ def test_build_advisory_record():
4280

4381
assert advisory.cve_id == "CVE-2014-005"
4482
assert advisory.versions == []
83+
84+
85+
def test_private():
86+
for i in cve_list.split()[:10]:
87+
advisory = build_advisory_record(i, fetch_references=False)
88+
print(advisory.cve_id, advisory.affected_products)
89+
time.sleep(6)
90+
raise NotImplementedError

0 commit comments

Comments
 (0)