Merge ~sbeattie/ubuntu-cve-tracker/+git/ubuntu-cve-tracker:check-cves_ignore_cache into ubuntu-cve-tracker:master

Proposed by Steve Beattie
Status: Merged
Merged at revision: fbb11d1762fcbfd1d2114b2d745736d7108eb165
Proposed branch: ~sbeattie/ubuntu-cve-tracker/+git/ubuntu-cve-tracker:check-cves_ignore_cache
Merge into: ubuntu-cve-tracker:master
Diff against target: 106 lines (+46/-7)
2 files modified
scripts/check-cves (+9/-7)
scripts/check_cves/ignored_cache.py (+37/-0)
Reviewer Review Type Date Requested Status
Alex Murray Approve
Seth Arnold Approve
Review via email: mp+422708@code.launchpad.net

Commit message

[WIP] check-cves: add a cache of 5 last ignored reasons

Often times when performing triage I bounce between CVEs of a few
different products from the same vendor that end up being ignored. It's
useful to have roughly a cache of five or so entries, plus the debian
reason if available plus the heuristic guess.

Implement a small cache of previously used reasons for ignoring a cve.
It keeps the ordering the same as before, with the cache entries added
last, orted in most recently used order.

Using this results in things looking like:

   Debian CVE Tracker: NOT-FOR-US: Node sds

  A]dd (or R]epeat), I]gnore forever, S]kip for now, or Q]uit? [ignore]
  Reason to be ignored?
     a) Node sds
     b) sds from
     c) BlogEngine.NET
     d) InHand Networks InRouter302
     e) OpenClinica
     f) Intel(R) NUCs
     g) Check Point Enterprise Endpoint

Signed-off-by: Steve Beattie <email address hidden>
TODO: unit tests. Sorry.

To post a comment you must log in.
Revision history for this message
Paulo Flabiano Smorigo (pfsmorigo) wrote :

Need unit tests, otherwise LGTM :P

Revision history for this message
Seth Arnold (seth-arnold) wrote :

Nice :)

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

Would it be possible to also add this in the "experimental" mode as well?

Revision history for this message
Steve Beattie (sbeattie) wrote :

On Wed, May 18, 2022 at 01:11:48AM -0000, Alex Murray wrote:
> Would it be possible to also add this in the "experimental" mode as well?

I'm open to the idea, but I'm not sure how. In interactive mode,
whatever reason you give to ignore a cve is added to the cache (limited
to 5 entries), and the next time you attempt to ignore a CVE, it shows
you the last five you entered.

Since the experimental mode is non-interactive and thus all proposed
interactions are pre-computed, I'm not sure how to do something similar.

Now, there are some ways we could improve both interactive and
non-interactive, given that we have a gigantic saved history of entries
from people in the not-for-us.txt file.

For interactive mode, I'd like to make full use of readline's
capabilities with possibly two history files[1], one for ignored reasons,
and one for packages entered, so that similar to bash and other
shells, you could search through history for an appropriate entry
(and also to make interactive editing better).

There's probably more processing we could do for the non-interactive
version.

[1] unfortunately, libreadline only supports one global history per
    process, so when switching between adding a CVE and ignoring a CVE
    or vice versa, we'd need to flush the history and reload the saved
    history from the other save file.

--
Steve Beattie
<email address hidden>

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

Bah of course, this doesn't really make sense in the non-interactive case - sorry I wasn't thinking this through properly. That is a good idea re combing not-for-us.txt but that sounds like something for a future piece of work.

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

This was merged back in fbb11d1762fcbfd1d2114b2d745736d7108eb165

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/scripts/check-cves b/scripts/check-cves
2index 7f061f2..975b1cd 100755
3--- a/scripts/check-cves
4+++ b/scripts/check-cves
5@@ -8,7 +8,7 @@
6 # Author: Jamie Strandboge <jamie@ubuntu.com>
7 # Author: Marc Deslauriers <marc.deslauriers@ubuntu.com>
8 # Author: Steve Beattie <sbeattie@ubuntu.com>
9-# Copyright (C) 2005-2021 Canonical Ltd.
10+# Copyright (C) 2005-2022 Canonical Ltd.
11 #
12 # This script is distributed under the terms and conditions of the GNU General
13 # Public License, Version 2 or later. See http://www.gnu.org/copyleft/gpl.html
14@@ -38,6 +38,7 @@ import progressbar
15
16 import cve_lib
17 import source_map
18+from check_cves.ignored_cache import IgnoredCache
19
20 # load settings, if any
21 cve_lib.read_config()
22@@ -550,6 +551,7 @@ def cvss_source_from_filename(name):
23 return source
24 return 'unknown'
25
26+
27 class CVEHandler(xml.sax.handler.ContentHandler):
28 """SAX handler for processing mitre's CVE database XML."""
29
30@@ -574,7 +576,7 @@ class CVEHandler(xml.sax.handler.ContentHandler):
31 self.cve_seen = set()
32 self.cve_list = []
33 self.cve_data = dict()
34- self.saved_ignore_reason = ""
35+ self.saved_ignore_cache = IgnoredCache()
36 self.saved_package = ""
37 self.saved_cve = ""
38 self.debian = None
39@@ -1127,11 +1129,11 @@ class CVEHandler(xml.sax.handler.ContentHandler):
40 prompts = []
41
42 # Show debian reason first, then automatically determined
43- # reason, then saved reason. This makes more sense
44+ # reason, then saved reasons. This makes more sense
45 # than sorting the reasons and is more predictable
46- for choice in [reason,
47- self.get_ignore_suggestion(self.cve_data[cve]['desc']),
48- self.saved_ignore_reason]:
49+ choices = [reason, self.get_ignore_suggestion(self.cve_data[cve]['desc'])]
50+ choices.extend(self.saved_ignore_cache.get())
51+ for choice in choices:
52 if choice != "" and choice not in prompts:
53 prompts.append(choice)
54
55@@ -1153,7 +1155,7 @@ class CVEHandler(xml.sax.handler.ContentHandler):
56 elif len(info) < 3: # Fat fingers protection
57 print('\nError: Reason must be at least 3 characters long!\n')
58 info = ""
59- self.saved_ignore_reason = info
60+ self.saved_ignore_cache.insert(info)
61 self.ignore_cve(cve, info)
62
63 elif info.startswith('s'):
64diff --git a/scripts/check_cves/ignored_cache.py b/scripts/check_cves/ignored_cache.py
65new file mode 100644
66index 0000000..6130994
67--- /dev/null
68+++ b/scripts/check_cves/ignored_cache.py
69@@ -0,0 +1,37 @@
70+#!/usr/bin/env python3
71+# -*- coding: utf-8 -*-
72+#
73+# Copyright (C) 2022 Canonical Ltd.
74+#
75+# Implements a simple cache for recent reasons for ignoring CVE
76+# entries, as used by check-cves
77+
78+
79+class IgnoredCache():
80+ # Keeps a list of ignored entries with a maximum length
81+
82+ _ignored = list()
83+
84+ def __init__(self, initial_list=None, max_len=5):
85+ if initial_list:
86+ self._ignored = initial_list
87+ self.max_len = max_len
88+ self._prune_cache()
89+
90+ # ensure list is less than or equal to the maximum length, and prune
91+ # if not
92+ def _prune_cache(self):
93+ if len(self._ignored) > self.max_len:
94+ self._ignored = self._ignored[:self.max_len]
95+
96+ def insert(self, reason):
97+ # if the reason already exists, remove it so it can be
98+ # reinserted at the head of the list
99+ if reason in self._ignored:
100+ self._ignored.remove(reason)
101+
102+ self._ignored.insert(0, reason)
103+ self._prune_cache()
104+
105+ def get(self):
106+ return self._ignored

Subscribers

People subscribed via source and target branches