Add feature to check if a CVE has an open launchpad
This change enables the capability to track if a CVE to be fixed already has an open launchpad in starlingx: https://bugs.launchpad.net/starlingx/ This will help the security team to focus on the CVEs that do not have a launchpad already open, reducing the overhead of analysis of CVEs already presented to the development team. Story:2006971 Change-Id: I494f0221cb52a4bf7ace20d75e067b17c719d749 Signed-off-by: VictorRodriguez <vm.rod25@gmail.com>
This commit is contained in:
parent
2722d6ffbe
commit
063e29fe2e
@ -12,6 +12,7 @@ Create documentation as pydoc -w cve_policy_filter
|
||||
import json
|
||||
import sys
|
||||
import os
|
||||
from lp import find_lp_assigned
|
||||
|
||||
def print_html_report(cves_report, title):
|
||||
"""
|
||||
@ -25,6 +26,7 @@ def print_html_report(cves_report, title):
|
||||
template = template_env.get_template(template_file)
|
||||
heads = ["cve_id", "status", "cvss2Score", "av", "ac", "au", "ai"]
|
||||
output_text = template.render(cves_to_fix=cves_report["cves_to_fix"],\
|
||||
cves_to_fix_lp=cves_report["cves_to_fix_lp"],\
|
||||
cves_to_track=cves_report["cves_to_track"],\
|
||||
cves_w_errors=cves_report["cves_w_errors"],\
|
||||
cves_to_omit=cves_report["cves_to_omit"],\
|
||||
@ -40,7 +42,7 @@ def print_report(cves_report, title):
|
||||
Print the txt STDOUT report
|
||||
"""
|
||||
print("\n%s report:" % (title))
|
||||
print("\nValid CVEs to take action immediately: %d\n" \
|
||||
print("\nCVEs to fix w/o a launchpad assigned: %d\n" \
|
||||
% (len(cves_report["cves_to_fix"])))
|
||||
for cve in cves_report["cves_to_fix"]:
|
||||
print("\n")
|
||||
@ -57,6 +59,15 @@ def print_report(cves_report, title):
|
||||
if cve["sourcelink"]:
|
||||
print(cve["sourcelink"])
|
||||
|
||||
print("\nCVEs to fix w/ a launchpad assigned: %d \n" \
|
||||
% (len(cves_report["cves_to_fix_lp"])))
|
||||
for cve in cves_report["cves_to_fix_lp"]:
|
||||
cve_line = []
|
||||
for key, value in cve.items():
|
||||
if key != "summary":
|
||||
cve_line.append(key + ":" + str(value))
|
||||
print(cve_line)
|
||||
|
||||
print("\nCVEs to track for incoming fix: %d \n" \
|
||||
% (len(cves_report["cves_to_track"])))
|
||||
for cve in cves_report["cves_to_track"]:
|
||||
@ -128,6 +139,7 @@ def main():
|
||||
cves = []
|
||||
cves_valid = []
|
||||
cves_to_fix = []
|
||||
cves_to_fix_lp = []
|
||||
cves_to_track = []
|
||||
cves_w_errors = []
|
||||
cves_to_omit = []
|
||||
@ -197,13 +209,17 @@ def main():
|
||||
and ("N" in cve["au"] or "S" in cve["au"])
|
||||
and ("P" in cve["ai"] or "C" in cve["ai"])):
|
||||
if cve["status"] == "fixed":
|
||||
cves_to_fix.append(cve)
|
||||
if find_lp_assigned(cve["id"]):
|
||||
cves_to_fix_lp.append(cve)
|
||||
else:
|
||||
cves_to_fix.append(cve)
|
||||
else:
|
||||
cves_to_track.append(cve)
|
||||
else:
|
||||
cves_to_omit.append(cve)
|
||||
|
||||
cves_report["cves_to_fix"] = cves_to_fix
|
||||
cves_report["cves_to_fix_lp"] = cves_to_fix_lp
|
||||
cves_report["cves_to_track"] = cves_to_track
|
||||
cves_report["cves_w_errors"] = cves_w_errors
|
||||
cves_report["cves_to_omit"] = cves_to_omit
|
||||
|
92
cve_support/lp.py
Normal file
92
cve_support/lp.py
Normal file
@ -0,0 +1,92 @@
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
# Copyright (C) 2019 Intel Corporation
|
||||
#
|
||||
|
||||
"""
|
||||
Implement system to detect if CVEs has launchpad assigned
|
||||
"""
|
||||
import json
|
||||
import os
|
||||
from os import path
|
||||
from launchpadlib.launchpad import Launchpad
|
||||
|
||||
|
||||
# Filter the open bugs
|
||||
STATUSES = [
|
||||
'New',
|
||||
'Incomplete',
|
||||
'Confirmed',
|
||||
'Triaged',
|
||||
'In Progress',
|
||||
'Fix Committed',
|
||||
'Fix Released',
|
||||
]
|
||||
|
||||
CACHEDIR = path.join('/tmp', os.environ['USER'], '.launchpadlib/cache')
|
||||
CVES_FILE = path.join(CACHEDIR, 'cves_open.json')
|
||||
DATA = []
|
||||
|
||||
|
||||
def search_upstrem_lps():
|
||||
"""
|
||||
Search for launchpads open with CVE or cve in title
|
||||
"""
|
||||
launchpad = Launchpad.login_anonymously\
|
||||
('lplib.cookbook.json_fetcher', 'production',
|
||||
CACHEDIR, version='devel')
|
||||
project = launchpad.projects['starlingx']
|
||||
tasks = project.searchTasks(status=STATUSES)
|
||||
for task in tasks:
|
||||
bug = task.bug
|
||||
if ("cve" in bug.title.lower()):
|
||||
bug_dic = {}
|
||||
bug_dic['id'] = bug.id
|
||||
bug_dic['title'] = bug.title
|
||||
bug_dic['link'] = bug.self_link
|
||||
DATA.append(bug_dic)
|
||||
|
||||
with open(CVES_FILE, 'w') as outfile:
|
||||
json.dump(DATA, outfile)
|
||||
|
||||
def find_lp_assigned(cve_id):
|
||||
"""
|
||||
Check if a launchpad for CVE exist in DATA
|
||||
DATA must came from file or from upstream launchpad DB
|
||||
"""
|
||||
global DATA
|
||||
|
||||
if not DATA:
|
||||
if path.isfile(CVES_FILE):
|
||||
DATA = json.load(open(CVES_FILE, "r"))
|
||||
else:
|
||||
search_upstrem_lps()
|
||||
|
||||
for bug in DATA:
|
||||
if cve_id in bug["title"]:
|
||||
return bug
|
||||
|
||||
return None
|
||||
|
||||
def main():
|
||||
|
||||
"""
|
||||
Sanity test
|
||||
"""
|
||||
cve_ids = ["CVE-2019-0160",\
|
||||
"CVE-2019-11810",\
|
||||
"CVE-2019-11811",\
|
||||
"CVE-2018-15686",\
|
||||
"CVE-2019-10126"]
|
||||
|
||||
for cve_id in cve_ids:
|
||||
bug = find_lp_assigned(cve_id)
|
||||
if bug:
|
||||
print("\n")
|
||||
print(bug)
|
||||
else:
|
||||
print("\n%s has no LP assigned\n" % (cve_id))
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
@ -1,9 +1,9 @@
|
||||
<head></head>
|
||||
<body>
|
||||
<h1>Security report from vuls scan from {{title}}</h1>
|
||||
<h2>Valid CVEs to take action immediately: {{cves_to_fix | length}}</h2>
|
||||
<h2>CVEs to fix w/o a launchpad assigned: {{cves_to_fix | length}}</h2>
|
||||
<table>
|
||||
{% if cves_to_fix|length > 1 %}
|
||||
{% if cves_to_fix|length >= 1 %}
|
||||
<tr>
|
||||
{% for head in heads %}
|
||||
<th>{{head}}</th>
|
||||
@ -23,9 +23,31 @@
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
</table>
|
||||
<h2>CVEs to fix w/ a launchpad assigend: {{cves_to_fix_lp | length}}</h2>
|
||||
<table>
|
||||
{% if cves_to_fix_lp|length >= 1 %}
|
||||
<tr>
|
||||
{% for head in heads %}
|
||||
<th>{{head}}</th>
|
||||
{% endfor %}
|
||||
</tr>
|
||||
|
||||
{% for cve in cves_to_fix_lp %}
|
||||
<tr>
|
||||
<td>{{cve["id"]}}</td>
|
||||
<td>{{cve["status"]}}</td>
|
||||
<td>{{cve["cvss2Score"]}}</td>
|
||||
<td>{{cve["av"]}}</td>
|
||||
<td>{{cve["ac"]}}</td>
|
||||
<td>{{cve["au"]}}</td>
|
||||
<td>{{cve["ai"]}}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
</table>
|
||||
<h2> CVEs to track for incoming fix: {{cves_to_track | length}}</h2>
|
||||
<table>
|
||||
{% if cves_to_track|length > 1 %}
|
||||
{% if cves_to_track|length >= 1 %}
|
||||
<tr>
|
||||
{% for head in heads %}
|
||||
<th>{{head}}</th>
|
||||
@ -47,7 +69,7 @@
|
||||
</table>
|
||||
<h2> CVEs to omit: {{cves_to_omit | length}}</h2>
|
||||
<table>
|
||||
{% if cves_to_omit|length > 1 %}
|
||||
{% if cves_to_omit|length >= 1 %}
|
||||
<tr>
|
||||
{% for head in heads %}
|
||||
<th>{{head}}</th>
|
||||
@ -70,7 +92,7 @@
|
||||
|
||||
<h2>ERROR: CVEs that have no cvss2Score or cvss2Vector:{{cves_w_errors | length}}</h2>
|
||||
<table>
|
||||
{% if cves_w_errors|length > 1 %}
|
||||
{% if cves_w_errors|length >= 1 %}
|
||||
{% for cve in cves_to_track %}
|
||||
<tr>
|
||||
<td>{{cve["id"]}}</td>
|
||||
|
Loading…
x
Reference in New Issue
Block a user