Skip to content

Commit 0998f29

Browse files
authored
Fix NVD download of CVE data
fixes #906
1 parent 4def96c commit 0998f29

File tree

9 files changed

+78
-41
lines changed

9 files changed

+78
-41
lines changed

cve_bin_tool/async_utils.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,9 @@ def run_coroutine(coro):
4646

4747
async def aio_run_command(args):
4848
process = await asyncio.create_subprocess_exec(
49-
*args, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE,
49+
*args,
50+
stdout=asyncio.subprocess.PIPE,
51+
stderr=asyncio.subprocess.PIPE,
5052
)
5153
stdout, stderr = await process.communicate()
5254
return stdout, stderr # binary encoded

cve_bin_tool/cli.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,11 @@ def main(argv=None):
8686
)
8787

8888
input_group.add_argument(
89-
"-i", "--input-file", action="store", default="", help="provide input filename",
89+
"-i",
90+
"--input-file",
91+
action="store",
92+
default="",
93+
help="provide input filename",
9094
)
9195
input_group.add_argument(
9296
"-C", "--config", action="store", default="", help="provide config file"
@@ -144,7 +148,10 @@ def main(argv=None):
144148
help="update schedule for NVD database (default: daily)",
145149
)
146150
parser.add_argument(
147-
"-x", "--extract", action="store_true", help="autoextract compressed files",
151+
"-x",
152+
"--extract",
153+
action="store_true",
154+
help="autoextract compressed files",
148155
)
149156
parser.add_argument(
150157
"--disable-version-check",

cve_bin_tool/cve_scanner.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ def __init__(
4848
self.all_cve_data = defaultdict(CVEData)
4949

5050
def get_cves(self, product_info: ProductInfo, triage_data: TriageData):
51-
""" Get CVEs against a specific version of a product.
51+
"""Get CVEs against a specific version of a product.
5252
5353
Example:
5454
nvd.get_cves('haxx', 'curl', '7.34.0')

cve_bin_tool/cvedb.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,8 @@ class CVEDB:
4747
LOGGER = LOGGER.getChild("CVEDB")
4848
NVDCVE_FILENAME_TEMPLATE = "nvdcve-1.1-{}.json.gz"
4949
CURL_CVE_FILENAME_TEMPLATE = "curlcve-{}.json"
50-
META_REGEX = re.compile(r"https://.*/json/.*-[0-9]*\.[0-9]*-[0-9]*\.meta")
50+
META_LINK = "https://nvd.nist.gov"
51+
META_REGEX = re.compile(r"\/feeds\/json\/.*-[0-9]*\.[0-9]*-[0-9]*\.meta")
5152
RANGE_UNSET = ""
5253

5354
def __init__(
@@ -91,7 +92,10 @@ async def nist_scrape(self, session):
9192
json_meta_links = self.META_REGEX.findall(page)
9293
return dict(
9394
await asyncio.gather(
94-
*[self.getmeta(session, meta_url) for meta_url in json_meta_links]
95+
*[
96+
self.getmeta(session, f"{self.META_LINK}{meta_url}")
97+
for meta_url in json_meta_links
98+
]
9599
)
96100
)
97101

@@ -561,7 +565,7 @@ def curl_versions(self):
561565
regex = re.compile(r"curlcve-(\d+.\d+.\d).json")
562566
return [
563567
regex.search(filename).group(1)
564-
for filename in glob.glob(os.path.join(self.cachedir, "curl-*.json"))
568+
for filename in glob.glob(os.path.join(self.cachedir, "curlcve-*.json"))
565569
]
566570

567571
def clear_cached_data(self):

cve_bin_tool/egg_updater.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,8 @@ def update_egg():
4646
)
4747
for filename in os.listdir(
4848
os.path.join(
49-
os.path.abspath(os.path.dirname(__file__)), "checkers",
49+
os.path.abspath(os.path.dirname(__file__)),
50+
"checkers",
5051
)
5152
)
5253
if filename.endswith(".py") and "__init__" not in filename

cve_bin_tool/output_engine/html.py

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -92,13 +92,17 @@ def output_html(
9292

9393
# Chart configuration for product_pie
9494
product_pie.update_layout(
95-
autosize=True, legend_orientation="h",
95+
autosize=True,
96+
legend_orientation="h",
9697
)
9798
product_pie.update_traces(
9899
hoverinfo="label+percent",
99100
textinfo="value",
100101
textfont_size=14,
101-
marker=dict(colors=["#d80032", "#1a936f"], line=dict(color="white", width=2),),
102+
marker=dict(
103+
colors=["#d80032", "#1a936f"],
104+
line=dict(color="white", width=2),
105+
),
102106
)
103107

104108
# dash graph2: Product CVE's Graph
@@ -117,7 +121,9 @@ def output_html(
117121
)
118122

119123
# Chart configuration for cve_bar
120-
cve_bar.update_layout(yaxis_title="Number of CVE's",)
124+
cve_bar.update_layout(
125+
yaxis_title="Number of CVE's",
126+
)
121127

122128
all_paths = defaultdict(list)
123129

@@ -134,19 +140,34 @@ def output_html(
134140
hid = f"{product_info.vendor}{product_info.product}{''.join(product_info.version.split('.'))}"
135141

136142
new_cves = render_cves(
137-
hid, cve_row, "NEW", cve_by_remark[Remarks.NewFound],
143+
hid,
144+
cve_row,
145+
"NEW",
146+
cve_by_remark[Remarks.NewFound],
138147
)
139148
mitigated_cves = render_cves(
140-
hid, cve_row, "MITIGATED", cve_by_remark[Remarks.Mitigated],
149+
hid,
150+
cve_row,
151+
"MITIGATED",
152+
cve_by_remark[Remarks.Mitigated],
141153
)
142154
confirmed_cves = render_cves(
143-
hid, cve_row, "CONFIRMED", cve_by_remark[Remarks.Confirmed],
155+
hid,
156+
cve_row,
157+
"CONFIRMED",
158+
cve_by_remark[Remarks.Confirmed],
144159
)
145160
unexplored_cves = render_cves(
146-
hid, cve_row, "UNEXPLORED", cve_by_remark[Remarks.Unexplored],
161+
hid,
162+
cve_row,
163+
"UNEXPLORED",
164+
cve_by_remark[Remarks.Unexplored],
147165
)
148166
ignored_cves = render_cves(
149-
hid, cve_row, "IGNORED", cve_by_remark[Remarks.Ignored],
167+
hid,
168+
cve_row,
169+
"IGNORED",
170+
cve_by_remark[Remarks.Ignored],
150171
)
151172

152173
analysis_data = Counter(cve.severity for cve in cve_data["cves"])
@@ -173,7 +194,10 @@ def output_html(
173194
hoverinfo="label+percent",
174195
textinfo="value",
175196
textfont_size=14,
176-
marker=dict(colors=colors, line=dict(color="white", width=2),),
197+
marker=dict(
198+
colors=colors,
199+
line=dict(color="white", width=2),
200+
),
177201
)
178202
analysis_pie.update_layout(
179203
autosize=True,

test/test_cli.py

Lines changed: 16 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -187,34 +187,28 @@ def test_update(self, caplog):
187187
with caplog.at_level(logging.INFO):
188188
main(["cve-bin-tool", "-u", "daily", test_path])
189189
assert (
190-
(
191-
"cve_bin_tool.CVEDB",
192-
logging.INFO,
193-
"Using cached CVE data (<24h old). Use -u now to update immediately.",
194-
)
195-
in caplog.record_tuples
196-
or (
197-
"cve_bin_tool.CVEDB",
198-
logging.INFO,
199-
"Updating CVE data. This will take a few minutes.",
200-
)
201-
in caplog.record_tuples
202-
)
190+
"cve_bin_tool.CVEDB",
191+
logging.INFO,
192+
"Using cached CVE data (<24h old). Use -u now to update immediately.",
193+
) in caplog.record_tuples or (
194+
"cve_bin_tool.CVEDB",
195+
logging.INFO,
196+
"Updating CVE data. This will take a few minutes.",
197+
) in caplog.record_tuples
203198
caplog.clear()
204199

205200
with caplog.at_level(logging.INFO):
206201
main(["cve-bin-tool", "-u", "now", test_path])
207202
db_path = DISK_LOCATION_DEFAULT
208203
assert (
209-
("cve_bin_tool.CVEDB", logging.WARNING, f"Deleting cachedir {db_path}",)
210-
in caplog.record_tuples
211-
and (
212-
"cve_bin_tool.CVEDB",
213-
logging.INFO,
214-
"Updating CVE data. This will take a few minutes.",
215-
)
216-
in caplog.record_tuples
217-
)
204+
"cve_bin_tool.CVEDB",
205+
logging.WARNING,
206+
f"Deleting cachedir {db_path}",
207+
) in caplog.record_tuples and (
208+
"cve_bin_tool.CVEDB",
209+
logging.INFO,
210+
"Updating CVE data. This will take a few minutes.",
211+
) in caplog.record_tuples
218212
caplog.clear()
219213

220214
with caplog.at_level(logging.INFO):

test/test_data/icecast.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
mapping_test_data = [
2-
{"product": "icecast", "version": "2.3.0", "version_strings": ["Icecast 2.3.0"],}
2+
{
3+
"product": "icecast",
4+
"version": "2.3.0",
5+
"version_strings": ["Icecast 2.3.0"],
6+
}
37
]
48
package_test_data = [
59
{

test/test_json.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@ def test_json_validation(self, year):
3737
""" Validate latest nvd json file against their published schema """
3838
# Open the latest nvd file on disk
3939
with gzip.open(
40-
os.path.join(DISK_LOCATION_DEFAULT, f"nvdcve-1.1-{year}.json.gz"), "rb",
40+
os.path.join(DISK_LOCATION_DEFAULT, f"nvdcve-1.1-{year}.json.gz"),
41+
"rb",
4142
) as json_file:
4243
nvd_json = json.loads(json_file.read())
4344
LOGGER.info(f"Loaded json for year {year}: nvdcve-1.1-{year}.json.gz")

0 commit comments

Comments
 (0)