22
22
from rich .progress import track
23
23
24
24
from cve_bin_tool .async_utils import run_coroutine
25
- from cve_bin_tool .data_sources import curl_source , gad_source , nvd_source , osv_source
25
+ from cve_bin_tool .data_sources import (
26
+ curl_source ,
27
+ epss_source ,
28
+ gad_source ,
29
+ nvd_source ,
30
+ osv_source ,
31
+ )
26
32
from cve_bin_tool .error_handler import ERROR_CODES , CVEDBError , ErrorMode , SigningError
27
33
from cve_bin_tool .fetch_json_db import Fetch_JSON_DB
28
34
from cve_bin_tool .log import LOGGER
@@ -88,6 +94,8 @@ def __init__(
88
94
self .cve_count = - 1
89
95
self .all_cve_entries : list [dict [str , Any ]] | None = None
90
96
97
+ self .epss_data = None
98
+
91
99
self .exploits_list : list [Any ] = []
92
100
self .exploit_count = 0
93
101
@@ -126,6 +134,8 @@ async def refresh(self) -> None:
126
134
if self .version_check :
127
135
check_latest_version ()
128
136
137
+ epss = epss_source .Epss_Source ()
138
+ self .epss_data = await epss .update_epss ()
129
139
await self .get_data ()
130
140
131
141
def refresh_cache_and_update_db (self ) -> None :
@@ -342,7 +352,29 @@ def insert_queries(self):
342
352
)
343
353
VALUES (?,?,?)
344
354
"""
345
- return insert_severity , insert_cve_range , insert_exploit
355
+ insert_cve_metrics = """
356
+ INSERT or REPLACE INTO cve_metrics (
357
+ cve_number,
358
+ metric_id,
359
+ metric_score,
360
+ metric_field
361
+ )
362
+ VALUES (?, ?, ?, ?)
363
+ """
364
+ insert_metrics = """
365
+ INSERT or REPLACE INTO metrics (
366
+ metrics_id,
367
+ metrics_name
368
+ )
369
+ VALUES (?, ?)
370
+ """
371
+ return (
372
+ insert_severity ,
373
+ insert_cve_range ,
374
+ insert_exploit ,
375
+ insert_cve_metrics ,
376
+ insert_metrics ,
377
+ )
346
378
347
379
def init_database (self ) -> None :
348
380
"""Initialize db tables used for storing cve/version data"""
@@ -429,6 +461,9 @@ def populate_db(self) -> None:
429
461
we'll need a better parser to match those together.
430
462
"""
431
463
464
+ self .store_epss_data ()
465
+ self .populate_metrics ()
466
+
432
467
for idx , data in enumerate (self .data ):
433
468
_ , source_name = data
434
469
@@ -457,7 +492,7 @@ def populate_db(self) -> None:
457
492
self .db_close ()
458
493
459
494
def populate_severity (self , severity_data , cursor , data_source ):
460
- (insert_severity , _ , _ ) = self .insert_queries ()
495
+ (insert_severity , _ , _ , _ , _ ) = self .insert_queries ()
461
496
del_cve_range = "DELETE from cve_range where CVE_number=?"
462
497
463
498
for cve in severity_data :
@@ -500,7 +535,7 @@ def populate_severity(self, severity_data, cursor, data_source):
500
535
cursor .executemany (del_cve_range , [(cve ["ID" ],) for cve in severity_data ])
501
536
502
537
def populate_affected (self , affected_data , cursor , data_source ):
503
- (_ , insert_cve_range , _ ) = self .insert_queries ()
538
+ (_ , insert_cve_range , _ , _ , _ ) = self .insert_queries ()
504
539
try :
505
540
cursor .executemany (
506
541
insert_cve_range ,
@@ -522,6 +557,21 @@ def populate_affected(self, affected_data, cursor, data_source):
522
557
except Exception as e :
523
558
LOGGER .info (f"Unable to insert data for { data_source } - { e } " )
524
559
560
+ def populate_metrics (self ):
561
+ cursor = self .db_open_and_get_cursor ()
562
+ # Insert a row without specifying cve_metrics_id
563
+ (_ , _ , _ , _ , insert_metrics ) = self .insert_queries ()
564
+ data = [
565
+ (1 , "EPSS" ),
566
+ (2 , "CVSS-2" ),
567
+ (3 , "CVSS-3" ),
568
+ ]
569
+ # Execute the insert query for each row
570
+ for row in data :
571
+ cursor .execute (insert_metrics , row )
572
+ self .connection .commit ()
573
+ self .db_close ()
574
+
525
575
def clear_cached_data (self ) -> None :
526
576
self .create_cache_backup ()
527
577
if self .cachedir .exists ():
@@ -712,12 +762,19 @@ def create_exploit_db(self):
712
762
self .db_close ()
713
763
714
764
def populate_exploit_db (self , exploits ):
715
- (_ , _ , insert_exploit ) = self .insert_queries ()
765
+ (_ , _ , insert_exploit , _ , _ ) = self .insert_queries ()
716
766
cursor = self .db_open_and_get_cursor ()
717
767
cursor .executemany (insert_exploit , exploits )
718
768
self .connection .commit ()
719
769
self .db_close ()
720
770
771
+ def store_epss_data (self ):
772
+ (_ , _ , _ , insert_cve_metrics , _ ) = self .insert_queries ()
773
+ cursor = self .db_open_and_get_cursor ()
774
+ cursor .executemany (insert_cve_metrics , self .epss_data )
775
+ self .connection .commit ()
776
+ self .db_close ()
777
+
721
778
def dict_factory (self , cursor , row ):
722
779
d = {}
723
780
for idx , col in enumerate (cursor .description ):
@@ -866,7 +923,13 @@ def db_to_json(self, path, private_key, passphrase):
866
923
shutil .rmtree (temp_gnupg_home )
867
924
868
925
def json_to_db (self , cursor , db_column , json_data ):
869
- (insert_severity , insert_cve_range , insert_exploit ) = self .insert_queries ()
926
+ (
927
+ insert_severity ,
928
+ insert_cve_range ,
929
+ insert_exploit ,
930
+ insert_cve_metrics ,
931
+ insert_metrics ,
932
+ ) = self .insert_queries ()
870
933
columns = []
871
934
for data in json_data :
872
935
column = list (data .keys ())
@@ -887,6 +950,10 @@ def json_to_db(self, cursor, db_column, json_data):
887
950
cursor .executemany (insert_cve_range , values )
888
951
elif db_column == "cve_severity" :
889
952
cursor .executemany (insert_severity , values )
953
+ elif db_column == "cve_metrics" :
954
+ cursor .executemany (insert_cve_metrics , values )
955
+ elif db_column == "metrics" :
956
+ cursor .executemany (insert_metrics , values )
890
957
891
958
def json_to_db_wrapper (self , path , pubkey , ignore_signature , log_signature_error ):
892
959
try :
0 commit comments