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
1diff --git a/scripts/publish-cves-to-website-api.py b/scripts/publish-cves-to-website-api.py
2index 64ce483..3e9f494 100755
3--- a/scripts/publish-cves-to-website-api.py
4+++ b/scripts/publish-cves-to-website-api.py
5@@ -17,6 +17,7 @@ from macaroonbakery import httpbakery
6 #import http
7 #http.client.HTTPConnection.debuglevel = 1
8
9+CVE_regex_pattern = "CVE-\\d{4}-\\d{4,}$"
10
11 IGNORE_CACHE = os.path.expanduser("~/.publish-cves-ignore-cache")
12
13@@ -81,6 +82,34 @@ def get_devel_codename(cve_releases):
14 return cve_devel_release
15
16
17+def delete_single_cve(args, cve):
18+ http_method = "DELETE"
19+ endpoint = f"{args.endpoint}cves/{cve}.json"
20+ if args.dry_run:
21+ print(f"DEBUG: would send delete http request for: {endpoint}")
22+ else:
23+ if args.verbose:
24+ print(f"INFO: sending delete http request for: {endpoint}")
25+
26+ response = authentication(method=http_method, url=endpoint, payload=None)
27+ print(response, response.text[0:60])
28+ if args.stop and not re.match(r"^<Response \[2..\]>$", str(response)):
29+ sys.exit(1)
30+
31+
32+def do_delete_cves(args, cve_list):
33+ CVE_regex = re.compile(f"^{CVE_regex_pattern}$")
34+
35+ for cve in cve_list:
36+ if not re.match(CVE_regex, cve):
37+ print(
38+ f"WARNING: skipping deletion of non-CVE '{cve}'",
39+ file=sys.stderr
40+ )
41+ continue
42+ delete_single_cve(args, cve)
43+
44+
45 def post_single_cve(cve_filename):
46 # Upload active and ignored (in Ubuntu)
47 cve_data = cve_lib.load_cve(cve_filename)
48@@ -254,18 +283,28 @@ def main(argv=None):
49 help="API endpoint url.",
50 )
51 parser.add_argument(
52+ "--delete",
53+ action="append",
54+ type=str,
55+ help="CVE(s) to delete from the web endpoint",
56+ )
57+ parser.add_argument(
58 "file_path",
59 action="store",
60 type=str,
61- nargs="+",
62+ nargs="*",
63 help="[Required] The path of the CVE file(s) or folder(s)",
64 )
65+
66 args = parser.parse_args(argv)
67
68+ if args.delete is not None:
69+ do_delete_cves(args, args.delete)
70+
71 ## if args:
72 ## headers = {"Content-type": "application/json"}
73 cves = []
74- CVE_filename_regex = re.compile(".*/?CVE-\\d{4}-\\d{4,7}$" if args.filename_check else ".*")
75+ CVE_filename_regex = re.compile(f".*/?{CVE_regex_pattern}$" if args.filename_check else ".*")
76 NFU_filename_regex = re.compile(".*/not-for-us.txt$")
77 ignore_paths = ['experimental', 'subprojects', 'scripts']
78 cache_not_for_us_cve_ids = list()

Subscribers

People subscribed via source and target branches