import json import requests def download_vulns(): vulns = requests.get("https://security-tracker.debian.org/tracker/data/json").json() with open('vulns.json', 'w+') as f: json.dump(vulns, f, indent=4) fmt_str = '{:35s} {:20s} {:15s} {:10s} {:15s} {:10} {:20s} {:20s} {:40s} {:30s}' column_order = ['source_package', 'cve_name', 'release_name', 'status', 'nodsa_reason', 'state', 'urgency', 'fixed_version', 'repo_ver', 'nodsa'] def process_vuln(d, column_order): repo_ver = '' for repository, version in d.get('repositories').items(): repo_ver += ', sec: ' if repository.endswith('-security') else '' repo_ver += '{}'.format(version) d['repo_ver'] = repo_ver if d['status'] in ['undetermined']: state = 'UNDET' elif d['status'] in ['resolved'] and d['fixed_version'] in ['0']: state = 'NOT_AFF' elif d['status'] in ['open'] and d['nodsa_reason'] in ['postponed']: state = 'FIX_LATER' elif d['status'] in ['open'] and d['nodsa_reason'] in ['ignored']: state = 'WONT_FIX' elif d['status'] in ['open'] and d['nodsa'] not in [''] and 'Minor issue' in d['nodsa']: state = 'VULN_MIN' elif d['status'] in ['open'] and d['nodsa'] not in [''] and 'Minor issue' not in d['nodsa']: state = 'VULN' elif d['status'] in ['open'] and d['nodsa'] in ['']: state = 'VULN_CHK' elif d['status'] in ['resolved'] and d['fixed_version'] not in ['0', '']: state = 'FIXED' else: state = 'UNKNOWN' d['state'] = state if state not in ['FIXED', 'NOT_AFF']: print(fmt_str.format(*[d.get(c) for c in column_order])) def analyze(source_packages_filter, releases_filter): with open('vulns.json') as f: vulns_data = json.load(f) print(fmt_str.format(*column_order)) for source_package, vulns in vulns_data.items(): # if source_packages_filter and source_package not in source_packages_filter: if not source_package.startswith('python'): continue for cve_name, cve_details in vulns.items(): description = cve_details.get('description', '') debianbug = cve_details.get('debianbug', '') scope = cve_details.get('scope', '') releases = cve_details.get('releases', {}) # TODO: for checking if not vulnerable in # if 'sid' in releases and releases['sid']['status'] in ['open'] and \ # ( # # 'bookworm' in releases and releases['bookworm']['status'] in ['resolved'] or \ # 'bullseye' in releases and releases['bullseye']['status'] in ['resolved'] # ): # print() for release_name, release_details in releases.items(): if release_name not in releases_filter: continue status = release_details.get('status', '') fixed_version = release_details.get('fixed_version', '') urgency = release_details.get('urgency', '') nodsa = release_details.get('nodsa', '') nodsa_reason = release_details.get('nodsa_reason', '') repositories = release_details.get('repositories', {}) process_vuln( dict( source_package=source_package, cve_name=cve_name, release_name=release_name, status=status, fixed_version=fixed_version, nodsa_reason=nodsa_reason, nodsa=nodsa, repositories=repositories, urgency=urgency, ), column_order ) if __name__ == '__main__': # download_vulns() analyze([], [ # 'buster', 'buster-security', # 'bullseye', 'bullseye-security', 'bookworm', 'bookworm-security', 'trixie', 'sid', ])