Merge ~pfsmorigo/ubuntu-cve-tracker:pfsmorigo/priority-reason into ubuntu-cve-tracker:master
- Git
- lp:~pfsmorigo/ubuntu-cve-tracker
- pfsmorigo/priority-reason
- Merge into master
Status: | Merged |
---|---|
Merged at revision: | 7a65edaede42610c3f147c8d3c57d83b6c641741 |
Proposed branch: | ~pfsmorigo/ubuntu-cve-tracker:pfsmorigo/priority-reason |
Merge into: | ubuntu-cve-tracker:master |
Diff against target: |
408 lines (+53/-30) 23 files modified
scripts/active_edit (+4/-1) scripts/check-syntax (+1/-1) scripts/cve_lib.py (+22/-5) scripts/cve_packages (+3/-3) scripts/oval_lib.py (+3/-3) scripts/publish-cves-to-website-api.py (+1/-1) scripts/report-date.py (+2/-2) scripts/sis-generate-usn (+2/-2) test/okay/cve-id-N7.json (+1/-1) test/okay/cve-id-NNNN.json (+1/-1) test/okay/patches-missing-1.json (+1/-1) test/okay/patches-missing-2.json (+1/-1) test/okay/patches-missing-3.json (+1/-1) test/okay/patches-missing-4.json (+1/-1) test/okay/priority-critical (+1/-0) test/okay/priority-critical.json (+1/-1) test/okay/priority-high (+1/-0) test/okay/priority-high.json (+1/-1) test/okay/priority-low (+1/-0) test/okay/priority-low.json (+1/-1) test/okay/priority-medium.json (+1/-1) test/okay/priority-negligible.json (+1/-1) test/okay/priority-untriaged.json (+1/-1) |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Alex Murray | Approve | ||
Review via email: mp+437974@code.launchpad.net |
Commit message
Description of the change
Alex Murray (alexmurray) wrote : | # |
Paulo Flabiano Smorigo (pfsmorigo) wrote : | # |
Thanks for the feedback. About the questions...
1. Leaving just as Reason feels vague but I'm ok to use it instead. This change also works for the package priority so, for instance, Priority-
2 and 3. I'm ok with both alternatives as long as we have a good way to parse it properly. Maybe parentesis like we do for package states: "Priority: low (it is not a real vulnerability)"
4. Not sure. We can always check git for the author. Not sure if it matters for the person browsing the CVE.
5. If we go with 2 and 3 suggestions, only the boilerplates that has a low/high/critical would be modified. Nowadays only one boilerplate has low (thunderbird). Now, if we make it mandatory, we would need to change all CVE that fits the criteria.
6. check-syntax uses a function in cve_lib.py to verify the CVEs. I just added an additional check there for the priority reason.
Paulo Flabiano Smorigo (pfsmorigo) wrote : | # |
AlexM: I changed the format to be a comment in parenthesis after the tag. I still using priority-reason for the name but I'm ok about using other term. Also, maybe we can start without enforcing it for now. Otherwise we will need to add a reason for all the CVEs we have that fits the criteria.
Camila Camargo de Matos (ccdm94) wrote : | # |
Since the priority reason will need to be short because it will be included in the parenthesis, maybe it is interesting to come with some "default" possible texts to include, so that we can use them as reference. For example, when we update the status of a release to 'not-affected', for example, and the reason behind it not being affected is because the function being patched doesn't exist, or because the code doesn't include some other function which is needed to trigger the vulnerability, we usually put something like 'code not present' for all cases. I don't know if this PR is the right one to possibly include these changes, but it could be useful for some cases that are commonly found during triage. An example would be a 'code not compiled in Ubuntu' for a priority set as 'low'.
Paulo Flabiano Smorigo (pfsmorigo) wrote : | # |
Hello Alex and other reviewers,
A couple of months ago we had a discussion and I did all the changes at the time. I was waiting for the review but I just realised that I didn't push the new changes to this PR so I did it now. I took the opportunity to change a little bit and merged all commits into one.
This commit will:
- Change the priority field to a tuple in the format ('priority', 'priority reason');
- The format for the reason will be a line after the Priority field with a space at the begin:
Priority: high
classified as high because...
- It will make check_syntax complains if priority is other than 'medium' and there is no reason for it;
- The check only complains if the PublishDate is after this month (avoid check in old CVEs);
Alex Murray (alexmurray) wrote : | # |
LGTM still - thanks @pfsmorigo
Preview Diff
1 | diff --git a/scripts/active_edit b/scripts/active_edit |
2 | index 4e2be92..d9068d6 100755 |
3 | --- a/scripts/active_edit |
4 | +++ b/scripts/active_edit |
5 | @@ -232,7 +232,10 @@ def create_or_update_cve(cve, packages, priority=None, bug_urls=None, ref_urls=N |
6 | print('Bugs:', file=fp) |
7 | for url in (bug_urls if bug_urls else []): |
8 | print(" %s" % url, file=fp) |
9 | - print('Priority: %s' % (priority if priority else "untriaged"), file=fp) |
10 | + priority_text = priority if priority else "untriaged" |
11 | + if priority in cve_lib.PRIORITY_REASON_REQUIRED: |
12 | + priority_text += "\n XXX-Reason-XXX" |
13 | + print('Priority: %s' % priority_text, file=fp) |
14 | print('Discovered-by:', file=fp) |
15 | print('Assigned-to:', file=fp) |
16 | print('CVSS:', file=fp) |
17 | diff --git a/scripts/check-syntax b/scripts/check-syntax |
18 | index f3a5128..2bf4202 100755 |
19 | --- a/scripts/check-syntax |
20 | +++ b/scripts/check-syntax |
21 | @@ -764,7 +764,7 @@ def check_cve(cve): |
22 | if ( |
23 | len(supported) |
24 | and (is_active(cve) or is_embargoed(cve)) |
25 | - and ("Priority" not in data or data["Priority"] not in cve_lib.priorities) |
26 | + and ("Priority" not in data or data["Priority"][0] not in cve_lib.priorities) |
27 | ): |
28 | filename = srcmap["Priority"][0] if "Priority" in srcmap else cvepath |
29 | linenum = srcmap["Priority"][1] if "Priority" in srcmap else 1 |
30 | diff --git a/scripts/cve_lib.py b/scripts/cve_lib.py |
31 | index 9b2e44e..d90dbd7 100755 |
32 | --- a/scripts/cve_lib.py |
33 | +++ b/scripts/cve_lib.py |
34 | @@ -64,6 +64,8 @@ else: |
35 | boilerplates_dir = "boilerplates" |
36 | |
37 | PRODUCT_UBUNTU = "ubuntu" |
38 | +PRIORITY_REASON_REQUIRED = ["low", "high", "critical"] |
39 | +PRIORITY_REASON_DATE_START = "2023-07-11" |
40 | |
41 | # common to all scripts |
42 | # these get populated by the contents of subprojects defined below |
43 | @@ -1856,8 +1858,8 @@ def contextual_priority(cveinfo, pkg=None, rel=None): |
44 | if rel_p in cveinfo: |
45 | return 2, cveinfo[rel_p] |
46 | if pkg_p in cveinfo: |
47 | - return 1, cveinfo[pkg_p] |
48 | - return 0, cveinfo.get('Priority', 'untriaged') |
49 | + return 1, cveinfo[pkg_p][0] |
50 | + return 0, cveinfo['Priority'][0] if 'Priority' in cveinfo else 'untriaged' |
51 | |
52 | |
53 | def find_cve(cve): |
54 | @@ -2095,6 +2097,7 @@ def load_cve(cve, strict=False, srcmap=None): |
55 | raise ValueError("File does not exist: '%s'" % (cve)) |
56 | linenum = 0 |
57 | notes_parser = NotesParser() |
58 | + priority_reason = {} |
59 | cvss_entries = [] |
60 | with codecs.open(cve, encoding="utf-8") as inF: |
61 | lines = inF.readlines() |
62 | @@ -2112,6 +2115,12 @@ def load_cve(cve, strict=False, srcmap=None): |
63 | code, newmsg = notes_parser.parse_line(cve, line, linenum, code) |
64 | if code != EXIT_OKAY: |
65 | msg += newmsg |
66 | + elif lastfield.startswith('Priority'): |
67 | + priority_part = lastfield.split('_')[1] if '_' in lastfield else None |
68 | + if priority_part in priority_reason: |
69 | + priority_reason[priority_part].append(line.strip()) |
70 | + else: |
71 | + priority_reason[priority_part] = [line.strip()] |
72 | elif 'Patches_' in lastfield: |
73 | try: |
74 | _, pkg = lastfield.split('_', 1) |
75 | @@ -2186,7 +2195,7 @@ def load_cve(cve, strict=False, srcmap=None): |
76 | msg += "%s: %d: bad field with 'Priority_': '%s'\n" % (cve, linenum, field) |
77 | code = EXIT_FAIL |
78 | continue |
79 | - data.setdefault(field, value) |
80 | + data.setdefault(field, [value]) |
81 | srcmap.setdefault(field, (cve, linenum)) |
82 | if value not in ['untriaged', 'not-for-us'] + priorities: |
83 | msg += "%s: %d: unknown Priority '%s'\n" % (cve, linenum, value) |
84 | @@ -2265,7 +2274,7 @@ def load_cve(cve, strict=False, srcmap=None): |
85 | |
86 | # Fill in defaults for missing fields |
87 | if 'Priority' not in data: |
88 | - data.setdefault('Priority', 'untriaged') |
89 | + data.setdefault('Priority', ['untriaged']) |
90 | srcmap.setdefault('Priority', (cve, 1)) |
91 | # Perform override fields |
92 | if 'PublicDateAtUSN' in data: |
93 | @@ -2277,6 +2286,14 @@ def load_cve(cve, strict=False, srcmap=None): |
94 | data['PublicDate'] = data['CRD'] |
95 | srcmap['PublicDate'] = srcmap['CRD'] |
96 | |
97 | + if data["PublicDate"] > PRIORITY_REASON_DATE_START and \ |
98 | + data["Priority"][0] in PRIORITY_REASON_REQUIRED and not priority_reason: |
99 | + msg += "%s: %d: needs a reason for being '%s'\n" % (cve, linenum, data["Priority"][0]) |
100 | + code = EXIT_FAIL |
101 | + for item in priority_reason: |
102 | + field = 'Priority' if not item else 'Priority_' + item |
103 | + data[field].append(' '.join(priority_reason[item])) |
104 | + |
105 | # entries need an upstream entry if any entries are from the internal |
106 | # list of subprojects |
107 | for pkg in affected: |
108 | @@ -2339,7 +2356,7 @@ def load_table(cves, uems, opt=None, rcves=[], icves=[]): |
109 | # Allow for Priority overrides |
110 | priority[cve]['default'] = 'untriaged' |
111 | try: |
112 | - priority[cve]['default'] = info['Priority'] |
113 | + priority[cve]['default'] = info['Priority'][0] |
114 | except KeyError: |
115 | priority[cve]['default'] = 'untriaged' |
116 | |
117 | diff --git a/scripts/cve_packages b/scripts/cve_packages |
118 | index da038c4..c4903af 100755 |
119 | --- a/scripts/cve_packages |
120 | +++ b/scripts/cve_packages |
121 | @@ -253,9 +253,9 @@ for cve in sorted(cves): |
122 | if cveinfo[cve]['CVSS']: |
123 | p = cveinfo[cve]['CVSS'][0]['baseSeverity'].lower() |
124 | else: |
125 | - p = priority[cve]['default'] |
126 | + p = priority[cve]['default'][0] |
127 | else: |
128 | - p = priority[cve]['default'] |
129 | + p = priority[cve]['default'][0] |
130 | |
131 | if pkg in packages: |
132 | packages[pkg] += 1 |
133 | @@ -263,7 +263,7 @@ for cve in sorted(cves): |
134 | packages[pkg] = 1 |
135 | |
136 | if pkg in priority[cve]: |
137 | - p = priority[cve][pkg] |
138 | + p = priority[cve][pkg][0] |
139 | |
140 | if pkg in priorities[p]: |
141 | priorities[p][pkg] += 1 |
142 | diff --git a/scripts/oval_lib.py b/scripts/oval_lib.py |
143 | index ed64318..f8decdd 100644 |
144 | --- a/scripts/oval_lib.py |
145 | +++ b/scripts/oval_lib.py |
146 | @@ -1266,7 +1266,7 @@ class OvalGeneratorCVE: |
147 | 'cve_title': escape(header['Candidate']), |
148 | 'description': escape('{0} {1}'.format(header['Description'], |
149 | header['Ubuntu-Description']).strip() + instruction), |
150 | - 'priority': escape(header['Priority']), |
151 | + 'priority': escape(header['Priority'][0]), |
152 | 'criteria': '', |
153 | 'references': '', |
154 | 'notes': '' |
155 | @@ -1316,7 +1316,7 @@ class OvalGeneratorCVE: |
156 | # convert additional data <advisory> metadata elements |
157 | advisory = [] |
158 | advisory.append('<severity>{0}</severity>'.format( |
159 | - escape(header['Priority'].title()))) |
160 | + escape(header['Priority'][0].title()))) |
161 | advisory.append( |
162 | '<rights>Copyright (C) {0}Canonical Ltd.</rights>'.format(escape( |
163 | header['PublicDate'].split('-', 1)[0] + ' ' |
164 | @@ -2471,7 +2471,7 @@ class OvalGeneratorUSN(): |
165 | return None |
166 | |
167 | public_date = cve_object['PublicDate'] |
168 | - priority = cve_object['Priority'] |
169 | + priority = cve_object['Priority'][0] |
170 | references = cve_object['References'] |
171 | # TODO: deal with multiple CVSS? |
172 | cve_info = { |
173 | diff --git a/scripts/publish-cves-to-website-api.py b/scripts/publish-cves-to-website-api.py |
174 | index aa80880..d6af0e7 100755 |
175 | --- a/scripts/publish-cves-to-website-api.py |
176 | +++ b/scripts/publish-cves-to-website-api.py |
177 | @@ -166,7 +166,7 @@ def post_single_cve(cve_filename): |
178 | for [author, note] in cve_data["Notes"]: |
179 | notes.append({"author": author, "note": note}) |
180 | |
181 | - priority = cve_data["Priority"] |
182 | + priority = cve_data["Priority"][0] |
183 | |
184 | if priority == "untriaged": |
185 | priority = "unknown" |
186 | diff --git a/scripts/report-date.py b/scripts/report-date.py |
187 | index c983072..e350e0c 100755 |
188 | --- a/scripts/report-date.py |
189 | +++ b/scripts/report-date.py |
190 | @@ -78,9 +78,9 @@ for priority in ['untriaged'] + cve_lib.priorities: |
191 | continue |
192 | |
193 | # Only report if we have a matching priority |
194 | - this_priority = info[cve]['Priority'] |
195 | + this_priority = info[cve]['Priority'][0] |
196 | if info[cve].has_key('Priority_%s' % (pkg)): |
197 | - this_priority = info[cve]['Priority_%s' % (pkg)] |
198 | + this_priority = info[cve]['Priority_%s' % (pkg)][0] |
199 | if this_priority == priority: |
200 | pkglist.add(pkg) |
201 | |
202 | diff --git a/scripts/sis-generate-usn b/scripts/sis-generate-usn |
203 | index 4a46e18..4535210 100755 |
204 | --- a/scripts/sis-generate-usn |
205 | +++ b/scripts/sis-generate-usn |
206 | @@ -198,8 +198,8 @@ def check_cve_priority(cve): |
207 | print("ERROR: {} does not exist in UCT in either {}".format(cve, state), |
208 | file=sys.stderr) |
209 | sys.exit(1) |
210 | - if cve_data['Priority'] in ['untriaged', 'not-for-us']: |
211 | - print("ERROR: {} has Priority {}".format(cve, cve_data['Priority']), |
212 | + if cve_data['Priority'][0] in ['untriaged', 'not-for-us']: |
213 | + print("ERROR: {} has Priority {}".format(cve, cve_data['Priority'][0]), |
214 | file=sys.stderr) |
215 | sys.exit(1) |
216 | |
217 | diff --git a/test/okay/cve-id-N7.json b/test/okay/cve-id-N7.json |
218 | index 6685f37..afbffa1 100644 |
219 | --- a/test/okay/cve-id-N7.json |
220 | +++ b/test/okay/cve-id-N7.json |
221 | @@ -13,7 +13,7 @@ |
222 | "Notes": [], |
223 | "Mitigation": "", |
224 | "Bugs": "", |
225 | - "Priority": "negligible", |
226 | + "Priority": ["negligible"], |
227 | "Discovered-by": "", |
228 | "Assigned-to": "", |
229 | "CVSS": [], |
230 | diff --git a/test/okay/cve-id-NNNN.json b/test/okay/cve-id-NNNN.json |
231 | index 1d19260..0c008ca 100644 |
232 | --- a/test/okay/cve-id-NNNN.json |
233 | +++ b/test/okay/cve-id-NNNN.json |
234 | @@ -13,7 +13,7 @@ |
235 | "Notes": [], |
236 | "Mitigation": "", |
237 | "Bugs": "", |
238 | - "Priority": "negligible", |
239 | + "Priority": ["negligible"], |
240 | "Discovered-by": "", |
241 | "Assigned-to": "", |
242 | "CVSS": [], |
243 | diff --git a/test/okay/patches-missing-1.json b/test/okay/patches-missing-1.json |
244 | index f438ff6..c78d347 100644 |
245 | --- a/test/okay/patches-missing-1.json |
246 | +++ b/test/okay/patches-missing-1.json |
247 | @@ -11,7 +11,7 @@ |
248 | "Notes": [], |
249 | "Mitigation": "", |
250 | "Bugs": "", |
251 | - "Priority": "medium", |
252 | + "Priority": ["medium"], |
253 | "Discovered-by": "", |
254 | "Assigned-to": "", |
255 | "CVSS": [], |
256 | diff --git a/test/okay/patches-missing-2.json b/test/okay/patches-missing-2.json |
257 | index d057b6e..92fac9d 100644 |
258 | --- a/test/okay/patches-missing-2.json |
259 | +++ b/test/okay/patches-missing-2.json |
260 | @@ -11,7 +11,7 @@ |
261 | "Notes": [], |
262 | "Mitigation": "", |
263 | "Bugs": "", |
264 | - "Priority": "medium", |
265 | + "Priority": ["medium"], |
266 | "Discovered-by": "", |
267 | "Assigned-to": "", |
268 | "CVSS": [], |
269 | diff --git a/test/okay/patches-missing-3.json b/test/okay/patches-missing-3.json |
270 | index 950893d..b58408e 100644 |
271 | --- a/test/okay/patches-missing-3.json |
272 | +++ b/test/okay/patches-missing-3.json |
273 | @@ -13,7 +13,7 @@ |
274 | "Notes": [], |
275 | "Mitigation": "", |
276 | "Bugs": "", |
277 | - "Priority": "medium", |
278 | + "Priority": ["medium"], |
279 | "Discovered-by": "", |
280 | "Assigned-to": "", |
281 | "CVSS": [], |
282 | diff --git a/test/okay/patches-missing-4.json b/test/okay/patches-missing-4.json |
283 | index 6c03170..5ab7913 100644 |
284 | --- a/test/okay/patches-missing-4.json |
285 | +++ b/test/okay/patches-missing-4.json |
286 | @@ -13,7 +13,7 @@ |
287 | "Notes": [], |
288 | "Mitigation": "", |
289 | "Bugs": "", |
290 | - "Priority": "medium", |
291 | + "Priority": ["medium"], |
292 | "Discovered-by": "", |
293 | "Assigned-to": "", |
294 | "CVSS": [], |
295 | diff --git a/test/okay/priority-critical b/test/okay/priority-critical |
296 | index 5d20f02..78a81de 100644 |
297 | --- a/test/okay/priority-critical |
298 | +++ b/test/okay/priority-critical |
299 | @@ -11,6 +11,7 @@ Notes: |
300 | Mitigation: |
301 | Bugs: |
302 | Priority: critical |
303 | + reason for being critial |
304 | Discovered-by: |
305 | Assigned-to: |
306 | CVSS: |
307 | diff --git a/test/okay/priority-critical.json b/test/okay/priority-critical.json |
308 | index 5b99773..89cbce9 100644 |
309 | --- a/test/okay/priority-critical.json |
310 | +++ b/test/okay/priority-critical.json |
311 | @@ -13,7 +13,7 @@ |
312 | "Notes": [], |
313 | "Mitigation": "", |
314 | "Bugs": "", |
315 | - "Priority": "critical", |
316 | + "Priority": ["critical", "reason for being critial"], |
317 | "Discovered-by": "", |
318 | "Assigned-to": "", |
319 | "CVSS": [], |
320 | diff --git a/test/okay/priority-high b/test/okay/priority-high |
321 | index f97416a..5ec543f 100644 |
322 | --- a/test/okay/priority-high |
323 | +++ b/test/okay/priority-high |
324 | @@ -11,6 +11,7 @@ Notes: |
325 | Mitigation: |
326 | Bugs: |
327 | Priority: high |
328 | + reason for being high |
329 | Discovered-by: |
330 | Assigned-to: |
331 | CVSS: |
332 | diff --git a/test/okay/priority-high.json b/test/okay/priority-high.json |
333 | index 1c91a1f..f893e73 100644 |
334 | --- a/test/okay/priority-high.json |
335 | +++ b/test/okay/priority-high.json |
336 | @@ -13,7 +13,7 @@ |
337 | "Notes": [], |
338 | "Mitigation": "", |
339 | "Bugs": "", |
340 | - "Priority": "high", |
341 | + "Priority": ["high", "reason for being high"], |
342 | "Discovered-by": "", |
343 | "Assigned-to": "", |
344 | "CVSS": [], |
345 | diff --git a/test/okay/priority-low b/test/okay/priority-low |
346 | index 62d21c5..8c5050c 100644 |
347 | --- a/test/okay/priority-low |
348 | +++ b/test/okay/priority-low |
349 | @@ -11,6 +11,7 @@ Notes: |
350 | Mitigation: |
351 | Bugs: |
352 | Priority: low |
353 | + reason for being low |
354 | Discovered-by: |
355 | Assigned-to: |
356 | CVSS: |
357 | diff --git a/test/okay/priority-low.json b/test/okay/priority-low.json |
358 | index 76eb0f6..8eadf86 100644 |
359 | --- a/test/okay/priority-low.json |
360 | +++ b/test/okay/priority-low.json |
361 | @@ -13,7 +13,7 @@ |
362 | "Notes": [], |
363 | "Mitigation": "", |
364 | "Bugs": "", |
365 | - "Priority": "low", |
366 | + "Priority": ["low", "reason for being low"], |
367 | "Discovered-by": "", |
368 | "Assigned-to": "", |
369 | "CVSS": [], |
370 | diff --git a/test/okay/priority-medium.json b/test/okay/priority-medium.json |
371 | index acd1505..03aa9f2 100644 |
372 | --- a/test/okay/priority-medium.json |
373 | +++ b/test/okay/priority-medium.json |
374 | @@ -13,7 +13,7 @@ |
375 | "Notes": [], |
376 | "Mitigation": "", |
377 | "Bugs": "", |
378 | - "Priority": "medium", |
379 | + "Priority": ["medium"], |
380 | "Discovered-by": "", |
381 | "Assigned-to": "", |
382 | "CVSS": [], |
383 | diff --git a/test/okay/priority-negligible.json b/test/okay/priority-negligible.json |
384 | index 16783ce..5035758 100644 |
385 | --- a/test/okay/priority-negligible.json |
386 | +++ b/test/okay/priority-negligible.json |
387 | @@ -13,7 +13,7 @@ |
388 | "Notes": [], |
389 | "Mitigation": "", |
390 | "Bugs": "", |
391 | - "Priority": "negligible", |
392 | + "Priority": ["negligible"], |
393 | "Discovered-by": "", |
394 | "Assigned-to": "", |
395 | "CVSS": [], |
396 | diff --git a/test/okay/priority-untriaged.json b/test/okay/priority-untriaged.json |
397 | index ab2ece0..a596046 100644 |
398 | --- a/test/okay/priority-untriaged.json |
399 | +++ b/test/okay/priority-untriaged.json |
400 | @@ -13,7 +13,7 @@ |
401 | "Notes": [], |
402 | "Mitigation": "", |
403 | "Bugs": "", |
404 | - "Priority": "untriaged", |
405 | + "Priority": ["untriaged"], |
406 | "Discovered-by": "", |
407 | "Assigned-to": "", |
408 | "CVSS": [], |
A few general questions:
1. Should the name just be Reason instead of Priority-Reason to make it easier?
2. What if instead we extended the syntax to allow the reason to be listed directly underneath the priority, e.g.
Priority: low
classified as low since it is not a real vulnerability
as I think this is easier to read personally and it keeps the reason with the Priority
3. Or instead it could be a comment after the priority (but this would mean we couldn't easily do long Reason's) e.g.
Priority: low # classified as low since it is not a real vulnerability
4. Like Notes: do we want to capture who added the reason?
5. Do we also need to update all the boilerplates?
6. I think the check for this should be removed from cve_lib.py and instead added to check-syntax as this feels more like a policy check than a low-level format check
7. Can we please have a unit test in test_cve_lib.py?