Merge ~emitorino/ubuntu-cve-tracker:add_cvss_score_to_ubuntu_table into ubuntu-cve-tracker:master

Proposed by Emilia Torino
Status: Rejected
Rejected by: Emilia Torino
Proposed branch: ~emitorino/ubuntu-cve-tracker:add_cvss_score_to_ubuntu_table
Merge into: ubuntu-cve-tracker:master
Diff against target: 174 lines (+88/-2)
3 files modified
scripts/cve_lib.py (+2/-0)
scripts/report-todo-nvd-plot (+40/-0)
scripts/ubuntu-table (+46/-2)
Reviewer Review Type Date Requested Status
Alex Murray Needs Fixing
Review via email: mp+411828@code.launchpad.net

Commit message

- ubuntu_table: add new optional arg to display the NVD provided CVSS score
- cve_lib.py: support getting package component for esm releases
- report-todo-nvd-plot: add script to report outstanding cves based on nvd cvss

To post a comment you must log in.
acd8454... by Emilia Torino

Only getting the original release name if current rel is an active esm release

Signed-off-by: Maria Emilia Torino <email address hidden>

Revision history for this message
Alex Murray (alexmurray) wrote :

Thanks for looking into this Emi - the general concept seems fine but a bunch of things can be cleaned up (ie can use the baseSeverity directly from the existing CVSS parsing in cve_lib plus I am not sure we should have some of the other behavioural changes here...

review: Needs Fixing
Revision history for this message
Emilia Torino (emitorino) wrote :

I dont think we need this anymore since this was needed for metrics purposes and now we have specific code for this. I am rejecting this MP. Thanks Eduardo for the heads up

Unmerged commits

acd8454... by Emilia Torino

Only getting the original release name if current rel is an active esm release

Signed-off-by: Maria Emilia Torino <email address hidden>

86ae092... by Emilia Torino

Add support for CVSS rating into ubuntu table

Signed-off-by: Maria Emilia Torino <email address hidden>

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/scripts/cve_lib.py b/scripts/cve_lib.py
2index fd714cf..4e2cd10 100755
3--- a/scripts/cve_lib.py
4+++ b/scripts/cve_lib.py
5@@ -1884,6 +1884,8 @@ def is_supported(map, pkg, rel, cvedata=None):
6 ('universe-binary' in cvedata['tags'][pkg] or
7 'not-ue' in cvedata['tags'][pkg]):
8 return False
9+ if is_active_esm_release(rel):
10+ rel = get_orig_rel_name(rel)
11 # Look for a supported component
12 if rel in map and pkg in map[rel] and \
13 (map[rel][pkg]['section'] == 'main' or
14diff --git a/scripts/report-todo-nvd-plot b/scripts/report-todo-nvd-plot
15new file mode 100755
16index 0000000..482ea08
17--- /dev/null
18+++ b/scripts/report-todo-nvd-plot
19@@ -0,0 +1,40 @@
20+#!/bin/bash
21+
22+# Author: Emilia Torino <emilia.torino@canonical.com>
23+# Copyright (C) 2021 Canonical Ltd.
24+#
25+# This script is distributed under the terms and conditions of the GNU General
26+# Public License, Version 2 or later. See http://www.gnu.org/copyleft/gpl.html
27+# for details.
28+
29+# Reports a terse numeric of CVEs that need attention for supported packages considering
30+# the nvd CVSS scoring system.
31+TABLE=$(./scripts/ubuntu-table "$@")
32+for category in ${CATEGORY:-SUPPORTED}
33+do
34+ if [ "x$category" = "xuniverse" ]; then
35+ filter="-v '(SUPPORTED|PARTNER)'"
36+ elif [ "x$category" = "xesm" ]; then
37+ filter=""
38+ else
39+ filter=$category
40+ fi
41+ # ESM releases does not need to be filtered since ubuntu-table
42+ # does not report the SUPPORTED/UNIVERSE value properly and
43+ # we query universe and main differently with this script args
44+ if [ -n "$filter" ]; then
45+ TABLE=$(echo "$TABLE" | grep $filter)
46+ fi
47+
48+ for nvd_prio in nvd_critical nvd_high nvd_medium nvd_low
49+ do
50+ # make sure we don't count each CVE more than once by sorting on unique CVE id
51+ NVD_COUNT=$(echo "$TABLE" | grep "$nvd_prio" | cut -d" " -f1 | sort -u | wc -l)
52+ NVD_OUT="$NVD_OUT$NVD_COUNT "
53+ done
54+ if [ -n "$OUT" ]; then
55+ NVD_COUNT=$(echo "$TABLE" | cut -d" " -f2 | cut -d: -f1 | sort -u | wc -l)
56+ NVD_OUT="$NVD_OUT$NVD_COUNT"
57+ fi
58+ echo "$NVD_OUT"
59+done
60diff --git a/scripts/ubuntu-table b/scripts/ubuntu-table
61index e64e200..aa0b563 100755
62--- a/scripts/ubuntu-table
63+++ b/scripts/ubuntu-table
64@@ -28,13 +28,15 @@ map = source_map.load()
65 releases = list(cve_lib.all_releases)
66
67
68-def htmlTableHeader(show_crd=False, show_assignee=False):
69+def htmlTableHeader(show_crd=False, show_assignee=False, show_nvd_cvss=False):
70 header = "<thead class=\"thead-dark\">\n"
71 header += '<tr><th>CVE</th><th>Package</th>'
72 if show_crd:
73 header += '<th>CRD</th>'
74 if show_assignee:
75 header += '<th>Assigned To</th>'
76+ if show_nvd_cvss:
77+ header += '<th>CVSS</th>'
78 for rel in releases:
79 name = rel
80 header += "<th>%s</th>" % (cve_lib.release_names[name])
81@@ -43,6 +45,19 @@ def htmlTableHeader(show_crd=False, show_assignee=False):
82 return header
83
84
85+def nvd_rating(cvss_string):
86+ parsed_cvss = cve_lib.parse_cvss(cvss_string)
87+ base_score = parsed_cvss['baseMetricV3']['cvssV3']['baseScore']
88+ rating = "nvd_low"
89+ if 9 <= base_score <= 10:
90+ rating= "nvd_critical"
91+ elif 7 <= base_score < 9:
92+ rating= "nvd_high"
93+ elif 4 <= base_score < 7:
94+ rating= "nvd_medium"
95+ return rating
96+
97+
98 parser = optparse.OptionParser()
99 parser.add_option("-H", "--html", help="Output html", action="store_true")
100 parser.add_option("-r", "--all-releases", help="Show details for all releases not just those in releases_list in ~/.ubuntu-security-tools.conf", action="store_true")
101@@ -67,6 +82,7 @@ parser.add_option("--public-date", help="Show only packages with a CRD date newe
102 parser.add_option("--omit-header", help="Suppress printing the releases header", action="store_true")
103 parser.add_option("--show-crd", help="Show CRD", action="store_true")
104 parser.add_option("--show-assignee", help="Show who the CVE is assigned to", action="store_true")
105+parser.add_option("--show-nvd-cvss", help="Show the CVE CVSS score in the format used by NVD", action="store_true")
106 parser.add_option("--omit-status", help="Omit per-release status", action="store_true", default=False)
107 parser.add_option("--subproject", help="Show CVE status for a subproject", action="append", default=[])
108 (opt, args) = parser.parse_args()
109@@ -148,7 +164,7 @@ else:
110
111 if opt.html:
112 print('<table id="cves" class="table table-bordered table-hover">')
113- print(htmlTableHeader(opt.show_crd, opt.show_assignee))
114+ print(htmlTableHeader(opt.show_crd, opt.show_assignee, opt.show_nvd_cvss))
115 print("<tbody>\n")
116 else:
117 prefix = '%-35s'
118@@ -156,12 +172,16 @@ else:
119 crdformat = '%24s'
120 assigneeformat = '%11s'
121 relformat = '%14s'
122+ # nvd_css score is nvd_<priority> where maximum is nvd_critical
123+ cvssformat = '%12s'
124 if not opt.omit_header:
125 print(prefix % ' ', end=' ')
126 if opt.show_crd:
127 print(crdformat % 'CRD', end=' ')
128 if opt.show_assignee:
129 print(assigneeformat % 'Assigned To', end=' ')
130+ if opt.show_nvd_cvss:
131+ print(cvssformat % 'CVSS', end=' ')
132 if not opt.omit_status:
133 for rel in releases:
134 if '/' in rel:
135@@ -294,6 +314,17 @@ for cve in sorted(cves):
136 if opt.show_assignee:
137 assignee = cveinfo[cve]['Assigned-to']
138 print('<td class="assignee">%s</td>' % (escape(assignee)), end=' ')
139+ if opt.show_nvd_cvss:
140+ rating = ""
141+ try:
142+ cvss = cveinfo[cve]['CVSS']
143+ for cvss_source in cvss:
144+ source, value= cvss_source
145+ if source == 'nvd':
146+ rating = nvd_rating(value)
147+ except Exception as e:
148+ rating = ""
149+ print('<td class="cvss">%s</td>' % (escape(rating)), end=' ')
150
151 for rel in releases:
152 if mark[rel] != '*':
153@@ -323,8 +354,21 @@ for cve in sorted(cves):
154 if opt.show_assignee:
155 assignee = cveinfo[cve]['Assigned-to']
156 print(assigneeformat % assignee, end=' ')
157+ if opt.show_nvd_cvss:
158+ rating = ""
159+ try:
160+ cvss = cveinfo[cve]['CVSS']
161+ for cvss_source in cvss:
162+ source, value = cvss_source
163+ if source == 'nvd':
164+ rating = nvd_rating(value)
165+ except Exception as e:
166+ rating = ""
167+ print(cvssformat % rating, end=' ')
168 if not opt.omit_status:
169 for rel in releases:
170+ if mark[rel] != '*':
171+ universe = True
172 pkg_status = table[cve][pkg][rel]
173 if not opt.unmask_needed and table[cve][pkg][rel] in ['active', 'deferred']:
174 pkg_status = 'needed'

Subscribers

People subscribed via source and target branches