Merge ~litios/ubuntu-cve-tracker:oval-cve-tag into ubuntu-cve-tracker:master

Proposed by David Fernandez Gonzalez
Status: Merged
Merge reported by: David Fernandez Gonzalez
Merged at revision: 349332baab42728fef77dc722637e3dbecf2f017
Proposed branch: ~litios/ubuntu-cve-tracker:oval-cve-tag
Merge into: ubuntu-cve-tracker:master
Diff against target: 157 lines (+57/-19)
2 files modified
scripts/generate-oval (+0/-1)
scripts/oval_lib.py (+57/-18)
Reviewer Review Type Date Requested Status
Eduardo Barretto Approve
Review via email: mp+440876@code.launchpad.net

Description of the change

This change will add a new tag: <cve>

This tag will be used to represent the cve in the advisory, as this is especially needed for OVAL for packages. This cve tag tries to follow Red Hat approach:

<cve cvss3="5.4/CVSS:3.0/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:L/A:N" cwe="CWE-285" href="https://access.redhat.com/security/cve/CVE-2019-0816" impact="moderate" public="20190305">CVE-2019-0816</cve>

Some comments:

* Severity is extracted from Ubuntu's priority.
* Severity and public date are omitted in CVE format as they are already on the advisory.
* USNs are also added as a comma-separated list of elements.
* The most recent CVSS vector and score are added.

Examples:

- OVAL PKG advisory:

<rights>Copyright (C) 2023 Canonical Ltd.</rights>
<component>main</component>
<current_version>2.4.52-1ubuntu4.4</current_version>
<cve href="https://ubuntu.com/security/CVE-2023-25690" severity="medium" public="20230307" cvss_score="9.8" cvss_vector="CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H" usns="942-1,942-2">CVE-2023-25690</cve>
<cve href="https://ubuntu.com/security/CVE-2023-27522" severity="medium" public="20230307" cvss_score="7.5" cvss_vector="CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:N" usns="942-1">CVE-2023-27522</cve>

- OVAL CVE advisory:

<severity>Medium</severity>
<rights>Copyright (C) 2023 Canonical Ltd.</rights>
<public_date>2023-01-11</public_date>
<public_date_at_usn>2023-01-11</public_date_at_usn>
<cve href="https://ubuntu.com/security/CVE-2023-0210" cvss_score="7.5" cvss_vector="CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H" usns="915-1,982-1,987-1,004-1">CVE-2023-0210</cve>

To post a comment you must log in.
32f0063... by David Fernandez Gonzalez

oval_lib: add cve tag to usns

Revision history for this message
Eduardo Barretto (ebarretto) wrote :

overall lgtm, but I do have a doubt if we decided to not have severity in the <cve> tag for CVE-based OVAL and USN-based OVAL. Do you remember?

review: Approve
Revision history for this message
David Fernandez Gonzalez (litios) wrote :

Yeah, for CVE-based OVAL we decided to not add it as it was redundant.

> we already have severity on the top, I wonder if we keep severity from us, and in the cve tag whatever is from cvss

For USN-based OVAL we didn't discuss it but the severity we are using is computed from all the CVEs to represent the general severity. I think it would be useful to have the severities for each of the CVEs on the USN.

349332b... by David Fernandez Gonzalez

oval_lib: refactor cve tag generation to unify across formats

Revision history for this message
David Fernandez Gonzalez (litios) wrote :

As discussed with Eduardo, it's best to keep a stable format for all OVAL formats. The format follows the structure as described in the PKG format in the description:

<cve href="https://ubuntu.com/security/CVE-2022-21427" severity="medium" public="20220419" cvss_score="4.9" cvss_vector="CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:N/I:N/A:H" usns="400-1,400-2,739-1">CVE-2022-21427</cve>

Revision history for this message
Eduardo Barretto (ebarretto) wrote :

lgtm, thanks for addressing the last changes!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/scripts/generate-oval b/scripts/generate-oval
2index f703733..d168786 100755
3--- a/scripts/generate-oval
4+++ b/scripts/generate-oval
5@@ -234,7 +234,6 @@ def parse_cve_file(filepath, cache, pkg_filter=None):
6 cve_header_data['References'].insert(0, get_cve_url(filepath))
7 cve_header_data['Bugs'] = [bug.strip() for bug in cve_header_data['Bugs'].split('\n') if len(bug.strip()) > 0]
8 cve_header_data['Notes'] = ' '.join(user + '> ' + note.replace('\n', ' ') for user, note in cve_header_data['Notes'])
9- cve_header_data['CVSS'] = ' '.join(cvss['source'] + ': ' + cvss['vector'] for cvss in cve_header_data['CVSS'])
10
11 packages = {}
12 for pkg in data['pkgs']:
13diff --git a/scripts/oval_lib.py b/scripts/oval_lib.py
14index d8365c2..a08edab 100644
15--- a/scripts/oval_lib.py
16+++ b/scripts/oval_lib.py
17@@ -120,6 +120,26 @@ def debug(message):
18 if debug_level > 0:
19 sys.stdout.write('\rDEBUG: {0}\n'.format(message))
20
21+def generate_cve_tag(cve):
22+ cve_ref = '<cve href="https://ubuntu.com/security/{0}" severity="{1}" public="{2}"'.format(cve['Candidate'], cve['Priority'], cve['PublicDate'].split(' ')[0].replace('-', ''))
23+
24+ if cve['CVSS']:
25+ cve_ref += ' cvss_score="{0}" cvss_vector="{1}"'.format(cve['CVSS'][0]['baseScore'], cve['CVSS'][0]['vector'])
26+
27+ cve_ref_usns = False
28+ for ref in cve['References']:
29+ if 'https://ubuntu.com/security/notices/USN' in ref:
30+ if not cve_ref_usns:
31+ cve_ref_usns = True
32+ cve_ref += ' usns="'
33+ cve_ref += '{0},'.format(ref[41:])
34+
35+ if cve_ref_usns:
36+ cve_ref = '{0}"'.format(cve_ref[:-1])
37+
38+ cve_ref += '>{0}</cve>'.format(cve['Candidate'])
39+ return cve_ref
40+
41 class OvalGenerator:
42 supported_oval_elements = ('definition', 'test', 'object', 'state', 'variable')
43 generator_version = '1.1'
44@@ -424,6 +444,13 @@ class CVE:
45 def __init__(self, number, info, pkgs=[]) -> None:
46 self.number = number
47 self.description = info['Description']
48+ self.severity = info['Priority']
49+ self.public_date = info['PublicDate']
50+ self.cvss = info['CVSS']
51+ self.usns = []
52+ for url in info['References'].split('\n'):
53+ if 'https://ubuntu.com/security/notices/USN-' in url:
54+ self.usns.append(url[41:])
55 self.pkg_rel_entries = {}
56 self.pkgs = pkgs
57
58@@ -501,6 +528,10 @@ class OvalGeneratorPkg(OvalGenerator):
59 component = etree.SubElement(advisory, "component")
60 version = etree.SubElement(advisory, "current_version")
61
62+ for cve in package.cves:
63+ cve_obj = self._generate_cve_object(cve)
64+ advisory.append(cve_obj)
65+
66 rights.text = f"Copyright (C) {datetime.now().year} Canonical Ltd."
67 component.text = package.section
68 version.text = package.version
69@@ -558,6 +589,22 @@ class OvalGeneratorPkg(OvalGenerator):
70 definition.append(criteria)
71 return definition
72
73+ def _generate_cve_object(self, cve: CVE) -> etree.Element:
74+ cve_tag = etree.Element("cve",
75+ attrib={
76+ 'href' : f"https://ubuntu.com/security/{cve.number}",
77+ 'severity': cve.severity,
78+ 'public': cve.public_date.split(' ')[0].replace('-', '')
79+ })
80+
81+ cve_tag.text = cve.number
82+ if cve.cvss:
83+ cve_tag.set('cvss_score', cve.cvss[0]['baseScore'])
84+ cve_tag.set('cvss_vector', cve.cvss[0]['vector'])
85+ if cve.usns:
86+ cve_tag.set('usns', ','.join(cve.usns))
87+
88+ return cve_tag
89 def _generate_var_object(self, comment, id, binaries) -> etree.Element:
90 var = etree.Element("constant_variable",
91 attrib={
92@@ -1297,8 +1344,9 @@ class OvalGeneratorCVE:
93 continue
94 mapping['cve_title'] = escape(cve_title)
95 mapping['references'] = '\n <reference source="CVE" ref_id="{0}" ref_url="{1}" />'.format(mapping['cve_title'], escape(ref))
96- else:
97- advisory.append('<ref>{0}</ref>'.format(escape(ref)))
98+
99+ cve_ref = generate_cve_tag(header)
100+ advisory.append(cve_ref)
101 mapping['advisory_elements'] = '\n '.join(advisory)
102
103 if self.oval_format == 'dpkg':
104@@ -1993,10 +2041,10 @@ class OvalGeneratorUSN():
105 def create_cves_references(self, cves):
106 references = ""
107 for cve in cves:
108+ cve_ref = generate_cve_tag(cve)
109 references += \
110- """ <reference source="CVE" ref_url="{}" ref_id="{}"/>
111-""".format(cve['CVE_URL'], cve['Candidate'])
112-
113+ """{0}
114+ """.format(cve_ref)
115 return references.strip()
116
117 def get_usn_severity(self, cves):
118@@ -2075,11 +2123,11 @@ class OvalGeneratorUSN():
119 <platform>{platform}</platform>
120 </affected>
121 <reference source="USN" ref_url="{usn_url}" ref_id="{usn_id}"/>
122- {cves_references}
123 <description>{description}</description>
124 <advisory from="security@ubuntu.com">
125 <severity>{severity}</severity>
126 <issued date="{usn_timestamp}"/>
127+ {cves_references}
128 {bug_references}
129 </advisory>
130 </metadata>
131@@ -2342,23 +2390,14 @@ class OvalGeneratorUSN():
132
133 public_date = cve_object['PublicDate']
134 priority = cve_object['Priority']
135-
136+ references = cve_object['References']
137 # TODO: deal with multiple CVSS?
138- cvss = None
139- baseScore = None
140- baseSeverity = None
141- if cve_object['CVSS']:
142- cvss = cve_object['CVSS'][0]['vector']
143- baseScore = cve_object['CVSS'][0]['baseScore']
144- baseSeverity = cve_object['CVSS'][0]['baseSeverity'].title()
145-
146 cve_info = {
147 'Candidate': cve,
148 'PublicDate': public_date,
149 'Priority': priority,
150- 'CVSS': cvss,
151- 'CVSS_SEVERITY_LEVEL': baseSeverity,
152- 'CVSS_SCORE': baseScore,
153+ 'CVSS': cve_object['CVSS'],
154+ 'References': references.split('\n'),
155 'CVE_URL': self.cve_base_url.format(cve),
156 'MITRE_URL': self.mitre_base_url.format(cve)
157 }

Subscribers

People subscribed via source and target branches