Merge ~sbeattie/ubuntu-cve-tracker/+git/ubuntu-cve-tracker:publish_cve-add_deletion_option into ubuntu-cve-tracker:master

Proposed by Steve Beattie
Status: Merged
Merged at revision: 0b134ded66c697e1bd5d53b8280b32401362b7ed
Proposed branch: ~sbeattie/ubuntu-cve-tracker/+git/ubuntu-cve-tracker:publish_cve-add_deletion_option
Merge into: ubuntu-cve-tracker:master
Diff against target: 78 lines (+41/-2)
1 file modified
scripts/publish-cves-to-website-api.py (+41/-2)
Reviewer Review Type Date Requested Status
Alex Murray Approve
Review via email: mp+453725@code.launchpad.net

Commit message

publish-cves-to-website-api.py: add capability to delete cves from website

Add command line option to allow deleting one or more CVEs. This
changes the behavior of the script subtly: it now does not require
any (CVE) paths to be passed as arguments; if none are given, no CVEs
will be updated.

Some example invocations:

Delete CVE-2023-42572:
  $ scripts/publish-cves-to-website-api.py --delete CVE-2023-42572

Delete CVE-2023-42572 and CVE-2024-42572, exiting early if the first CVE
is not present on the web endpoint:
  $ scripts/publish-cves-to-website-api.py --stop --delete CVE-2023-42572 --delete CVE-2024-42572

Delete CVE-2023-42572 and update active/CVE-2023-42752, exiting early if
CVE-2023-42572 is not present on the web endpoint; i.e. CVE-2023-42752
will not get updated:
  $ scripts/publish-cves-to-website-api.py --stop --delete CVE-2023-42572 active/CVE-2023-42752

Note that the backend cronjob that runs this script has not been
modified to take advantage of this option; as of now, deleting a CVE
from the website requires a manual invocation of the script. (And
while the json endpoint will be updated immediately, it's not clear
how long the squid proxy will hold the cached version, alas :/ ).

Refactoring out the CVE_regex also fixes a subtle bug; if there was
a CVE with an suffix ID greater than 7 digits, the script would have
skipped updating it.

Description of the change

Thanks to me propogating a typo in a kernel changelog, I needed to delete a CVE from the website API. Unfortunately, our tools are not smart enough to do that when they see a CVE file go missing from the git repo. This merge request adds the capability to the publish-cves-to-website-api.py to manually delete a CVE from the website with the added --delete option (can be applied multiple times to delete multiple CVEs).

To post a comment you must log in.
Revision history for this message
Alex Murray (alexmurray) wrote :

LGTM!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
diff --git a/scripts/publish-cves-to-website-api.py b/scripts/publish-cves-to-website-api.py
index 64ce483..3e9f494 100755
--- a/scripts/publish-cves-to-website-api.py
+++ b/scripts/publish-cves-to-website-api.py
@@ -17,6 +17,7 @@ from macaroonbakery import httpbakery
17#import http17#import http
18#http.client.HTTPConnection.debuglevel = 118#http.client.HTTPConnection.debuglevel = 1
1919
20CVE_regex_pattern = "CVE-\\d{4}-\\d{4,}$"
2021
21IGNORE_CACHE = os.path.expanduser("~/.publish-cves-ignore-cache")22IGNORE_CACHE = os.path.expanduser("~/.publish-cves-ignore-cache")
2223
@@ -81,6 +82,34 @@ def get_devel_codename(cve_releases):
81 return cve_devel_release82 return cve_devel_release
8283
8384
85def delete_single_cve(args, cve):
86 http_method = "DELETE"
87 endpoint = f"{args.endpoint}cves/{cve}.json"
88 if args.dry_run:
89 print(f"DEBUG: would send delete http request for: {endpoint}")
90 else:
91 if args.verbose:
92 print(f"INFO: sending delete http request for: {endpoint}")
93
94 response = authentication(method=http_method, url=endpoint, payload=None)
95 print(response, response.text[0:60])
96 if args.stop and not re.match(r"^<Response \[2..\]>$", str(response)):
97 sys.exit(1)
98
99
100def do_delete_cves(args, cve_list):
101 CVE_regex = re.compile(f"^{CVE_regex_pattern}$")
102
103 for cve in cve_list:
104 if not re.match(CVE_regex, cve):
105 print(
106 f"WARNING: skipping deletion of non-CVE '{cve}'",
107 file=sys.stderr
108 )
109 continue
110 delete_single_cve(args, cve)
111
112
84def post_single_cve(cve_filename):113def post_single_cve(cve_filename):
85 # Upload active and ignored (in Ubuntu)114 # Upload active and ignored (in Ubuntu)
86 cve_data = cve_lib.load_cve(cve_filename)115 cve_data = cve_lib.load_cve(cve_filename)
@@ -254,18 +283,28 @@ def main(argv=None):
254 help="API endpoint url.",283 help="API endpoint url.",
255 )284 )
256 parser.add_argument(285 parser.add_argument(
286 "--delete",
287 action="append",
288 type=str,
289 help="CVE(s) to delete from the web endpoint",
290 )
291 parser.add_argument(
257 "file_path",292 "file_path",
258 action="store",293 action="store",
259 type=str,294 type=str,
260 nargs="+",295 nargs="*",
261 help="[Required] The path of the CVE file(s) or folder(s)",296 help="[Required] The path of the CVE file(s) or folder(s)",
262 )297 )
298
263 args = parser.parse_args(argv)299 args = parser.parse_args(argv)
264300
301 if args.delete is not None:
302 do_delete_cves(args, args.delete)
303
265 ## if args:304 ## if args:
266 ## headers = {"Content-type": "application/json"}305 ## headers = {"Content-type": "application/json"}
267 cves = []306 cves = []
268 CVE_filename_regex = re.compile(".*/?CVE-\\d{4}-\\d{4,7}$" if args.filename_check else ".*")307 CVE_filename_regex = re.compile(f".*/?{CVE_regex_pattern}$" if args.filename_check else ".*")
269 NFU_filename_regex = re.compile(".*/not-for-us.txt$")308 NFU_filename_regex = re.compile(".*/not-for-us.txt$")
270 ignore_paths = ['experimental', 'subprojects', 'scripts']309 ignore_paths = ['experimental', 'subprojects', 'scripts']
271 cache_not_for_us_cve_ids = list()310 cache_not_for_us_cve_ids = list()

Subscribers

People subscribed via source and target branches