diff options
Diffstat (limited to 'bin/common/srtool_utils.py')
-rwxr-xr-x | bin/common/srtool_utils.py | 83 |
1 files changed, 77 insertions, 6 deletions
diff --git a/bin/common/srtool_utils.py b/bin/common/srtool_utils.py index 573a86d5..0ac64713 100755 --- a/bin/common/srtool_utils.py +++ b/bin/common/srtool_utils.py @@ -1106,6 +1106,9 @@ def fix_severity(datasource_list): DATA_MAP_V2_Severity = 3 + # Allow "MOD" as shorthand for the modification datasource + datasource_list = datasource_list.replace('MOD','NIST Modified Data') + # # Gather the NIST data source list # @@ -1149,6 +1152,9 @@ def fix_severity(datasource_list): # try: + if not os.path.isfile(nist_file): + print("ERROR: no such file '%s'" % nist_file) + exit(1) f = open(nist_file, 'r') source_dct = json.load(f) for item in source_dct["CVE_Items"]: @@ -1197,15 +1203,19 @@ def fix_severity(datasource_list): cur_cve.execute('SELECT * FROM orm_cve WHERE name = "%s"' % cve_name) cve = cur_cve.fetchone() if not cve: - print("WARNING: MISSING CVE in orm_cvesource '%d:%d' : %s" % (cvesource[ORM.CVESOURCE_CVE_ID],cvesource[ORM.CVESOURCE_DATASOURCE_ID],ds[ORM.DATASOURCE_DESCRIPTION])) + print("WARNING: MISSING CVE in orm_cvesource : %s" % cve_name) continue cve_name = cve[ORM.CVE_NAME] if cve_name in nist_data_map: fix_count += 1 if (nist_data_map[cve_name][DATA_MAP_V3_Score] != cve[ORM.CVE_CVSSV3_BASESCORE]) or (nist_data_map[cve_name][DATA_MAP_V3_Severity] != cve[ORM.CVE_CVSSV3_BASESEVERITY]) or \ (nist_data_map[cve_name][DATA_MAP_V2_Score] != cve[ORM.CVE_CVSSV2_BASESCORE]) or (nist_data_map[cve_name][DATA_MAP_V2_Severity] != cve[ORM.CVE_CVSSV2_SEVERITY ]): - print("CHANGE: %s V3(%s to %s,%s to %s)V2(%s to %s,%s to %s)" % (cve_name,cve[ORM.CVE_CVSSV3_BASESCORE],nist_data_map[cve_name][DATA_MAP_V3_Score],cve[ORM.CVE_CVSSV3_BASESEVERITY],nist_data_map[cve_name][DATA_MAP_V3_Severity], - cve[ORM.CVE_CVSSV2_BASESCORE],nist_data_map[cve_name][DATA_MAP_V2_Score],cve[ORM.CVE_CVSSV2_SEVERITY ],nist_data_map[cve_name][DATA_MAP_V2_Severity])) + print("CHANGE: %s V3(%s to %s,%s to %s)V2(%s to %s,%s to %s) (%s,%s)" % ( + cve_name, + cve[ORM.CVE_CVSSV3_BASESCORE],nist_data_map[cve_name][DATA_MAP_V3_Score],cve[ORM.CVE_CVSSV3_BASESEVERITY],nist_data_map[cve_name][DATA_MAP_V3_Severity], + cve[ORM.CVE_CVSSV2_BASESCORE],nist_data_map[cve_name][DATA_MAP_V2_Score],cve[ORM.CVE_CVSSV2_SEVERITY ],nist_data_map[cve_name][DATA_MAP_V2_Severity], + ORM.get_orm_string(cve[ORM.CVE_STATUS],ORM.STATUS_STR),cve[ORM.CVE_COMMENTS], + )) if force: sql = ''' UPDATE orm_cve @@ -1259,6 +1269,56 @@ def fix_severity(datasource_list): print("CVE COUNT=%d, fix_count=%d" % (cve_count,fix_count)) if force: conn.commit() +# +# Trim the V3/V2 scores to one decimal place, in line with NIST public pages +# + +def fix_trim_cve_scores(): + conn = sqlite3.connect(srtDbName) + cur = conn.cursor() + cur_wr = conn.cursor() + + def fixscore(score): + if not score: + return '' + return '%02.1f' % float(score) + + cve_count = 0 + fix_count = 0 + + cur.execute('SELECT * FROM orm_cve') + for i,cve in enumerate(cur): + if 0 == i % 100: + print("%4d) C=%-30s\r" % (i,cve[ORM.CVE_NAME]), end='') + + new_v3score = fixscore(cve[ORM.CVE_CVSSV3_BASESCORE]) + new_v2score = fixscore(cve[ORM.CVE_CVSSV2_BASESCORE]) + + if (new_v3score != cve[ORM.CVE_CVSSV3_BASESCORE]) or (new_v2score != cve[ORM.CVE_CVSSV2_BASESCORE]): + fix_count += 1 + if verbose: + print("CHANGE:%s:%s to %s,%s to %s" % (cve[ORM.CVE_NAME],cve[ORM.CVE_CVSSV3_BASESCORE],new_v3score,cve[ORM.CVE_CVSSV2_BASESCORE],new_v2score)) + + if force: + sql = ''' UPDATE orm_cve + SET cvssV3_baseScore = ?, cvssV2_baseScore = ? + WHERE id = ?''' + cur_wr.execute(sql, (new_v3score,new_v2score,cve[ORM.CVE_ID],)) + + # Development/debug support + cve_count += 1 + if cmd_skip and (cve_count < cmd_skip): continue + if cmd_count and ((cve_count - cmd_skip) > cmd_count): break + + # Progress indicator support + if (0 == cve_count % 1000): + print('%05d: %-20s\r' % (cve_count,cve[ORM.CVE_NAME]), end='') + if force: conn.commit() + print('') + pass + + if force: conn.commit() + print("CVE COUNT=%d, fix_count=%d" % (cve_count,fix_count)) # Sample code that does a CVE lookup data fetch and CVE update #def example_datasource_lookup(cve,nist_ds,cvesource,cur): @@ -1405,6 +1465,13 @@ def find_bad_links(): print('\n=== CVE Source Check ===\n') # + # Find the data source mapping + cur.execute('SELECT * FROM orm_datasource;') + datasource_map = {} + for datasource in cur: + # DataSource Map is [cve_file,ds_desc,ds_lastmodifieddate,ds_lastupdateddate] + datasource_map[datasource[ORM.DATASOURCE_ID]] = datasource[ORM.DATASOURCE_DESCRIPTION] + cur.execute('SELECT * FROM orm_cvesource') is_change = False for i,cs in enumerate(cur): @@ -1417,7 +1484,7 @@ def find_bad_links(): if (1 > srcid): error = True if error: - print("ERROR: [%4d] CVE=%6d,SRC=%6d" % (cs[ORM.CVESOURCE_ID],cveid,srcid)) + print("ERROR: [%4d] CVE=%6d,SRC=%6d (%s)" % (cs[ORM.CVESOURCE_ID],cveid,srcid,datasource_map[srcid])) if force: sql = 'DELETE FROM orm_cvesource WHERE id=?' cur_del.execute(sql, (cs[ORM.CVESOURCE_ID],)) @@ -1561,15 +1628,16 @@ def main(argv): parser.add_argument('--fix-remove-bulk-cve-history', action='store_const', const='fix_remove_bulk_cve_history', dest='command', help='foo') parser.add_argument('--fix-bad-mitre-init', action='store_const', const='fix_bad_mitre_init', dest='command', help='foo') parser.add_argument('--fix-bad-new', action='store_const', const='fix_bad_new', dest='command', help='foo') + parser.add_argument('--find-empty-status', action='store_const', const='find_empty_status', dest='command', help='foo') parser.add_argument('--fix-severity', dest='fix_severity', help='Fix bad score/severity values, broken cve source links') - parser.add_argument('--find-empty-status', action='store_const', const='find_empty_status', dest='command', help='foo') + parser.add_argument('--fix-trim-cve-scores', action='store_const', const='fix_trim_cve_scores', dest='command', help='Trim V3/V2 scores to one decimal place standard') parser.add_argument('--find-multiple-defects', action='store_const', const='find_multiple_defects', dest='command', help='foo') parser.add_argument('--find-duplicate-names', action='store_const', const='find_duplicate_names', dest='command', help='foo') parser.add_argument('--fix-defects-to-products', action='store_const', const='fix_defects_to_products', dest='command', help='foo') - parser.add_argument('--find-bad-links', action='store_const', const='find_bad_links', dest='command', help='Find bad links, e.g. "orm_cvesource" (with "-f" to fix)') + parser.add_argument('--find-bad-links', action='store_const', const='find_bad_links', dest='command', help='Find bad links, e.g. "orm_cvesource" (add "-f" to fix)') parser.add_argument('--database', '-D', dest='database', help='Selected database file') @@ -1637,8 +1705,11 @@ def main(argv): fix_bad_mitre_init() elif 'fix_bad_new' == args.command: fix_bad_new() + elif args.fix_severity: fix_severity(args.fix_severity) + elif 'fix_trim_cve_scores' == args.command: + fix_trim_cve_scores() elif 'find_multiple_defects' == args.command: find_multiple_defects() |