cve_policy_filter.py supports CVSSV2 and CVSSV3 vulnerability report generation
Added new files for CVSSv3 scan report generation Added new files: new file: cve_policy_filter.py new file: template_v3.txt Change-Id: I93978825f973435eb34a0c8e6b3d18e1ac580595 Signed-off-by: Sanjay K Mukherjee <sanjay.k.mukherjee@intel.com>
This commit is contained in:
parent
bbf8b0402a
commit
8be170ef57
|
@ -14,6 +14,16 @@ import sys
|
||||||
import os
|
import os
|
||||||
from lp import find_lp_assigned
|
from lp import find_lp_assigned
|
||||||
|
|
||||||
|
cves_valid = []
|
||||||
|
cves_to_fix = []
|
||||||
|
cves_to_fix_lp = []
|
||||||
|
cves_to_track = []
|
||||||
|
cves_w_errors = []
|
||||||
|
cves_wont_fix = []
|
||||||
|
cves_to_omit = []
|
||||||
|
cves_report = {}
|
||||||
|
|
||||||
|
|
||||||
def print_html_report(cves_report, title):
|
def print_html_report(cves_report, title):
|
||||||
"""
|
"""
|
||||||
Print the html report
|
Print the html report
|
||||||
|
@ -22,9 +32,14 @@ def print_html_report(cves_report, title):
|
||||||
|
|
||||||
template_loader = jinja2.FileSystemLoader(searchpath="./")
|
template_loader = jinja2.FileSystemLoader(searchpath="./")
|
||||||
template_env = jinja2.Environment(loader=template_loader)
|
template_env = jinja2.Environment(loader=template_loader)
|
||||||
template_file = "template.txt"
|
if CVSS_VER == "cvssv3":
|
||||||
|
template_file = "template_v3.txt"
|
||||||
|
heads = ["cve_id", "status", "cvss3Score", "av", "ac", "ui","a"]
|
||||||
|
else:
|
||||||
|
template_file = "template.txt"
|
||||||
|
heads = ["cve_id", "status", "cvss2Score", "av", "ac", "au", "ai"]
|
||||||
|
|
||||||
template = template_env.get_template(template_file)
|
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"],\
|
output_text = template.render(cves_to_fix=cves_report["cves_to_fix"],\
|
||||||
cves_to_fix_lp=cves_report["cves_to_fix_lp"],\
|
cves_to_fix_lp=cves_report["cves_to_fix_lp"],\
|
||||||
cves_to_track=cves_report["cves_to_track"],\
|
cves_to_track=cves_report["cves_to_track"],\
|
||||||
|
@ -49,10 +64,16 @@ def print_report(cves_report, title):
|
||||||
print("\n")
|
print("\n")
|
||||||
print(cve["id"])
|
print(cve["id"])
|
||||||
print("status : " + cve["status"])
|
print("status : " + cve["status"])
|
||||||
print("cvss2Score : " + str(cve["cvss2Score"]))
|
if CVSS_VER == "cvssv3":
|
||||||
|
print("cvss3Score : " + str(cve["cvss3Score"]))
|
||||||
|
else:
|
||||||
|
print("cvss2Score : " + str(cve["cvss2Score"]))
|
||||||
print("Attack Vector: " + cve["av"])
|
print("Attack Vector: " + cve["av"])
|
||||||
print("Access Complexity : " + cve["ac"])
|
print("Access Complexity : " + cve["ac"])
|
||||||
print("Authentication: " + cve["au"])
|
if CVSS_VER == "cvssv3":
|
||||||
|
print("User Interaction: " + cve["ui"])
|
||||||
|
else:
|
||||||
|
print("Authentication: " + cve["au"])
|
||||||
print("Availability Impact :" + cve["ai"])
|
print("Availability Impact :" + cve["ai"])
|
||||||
print("Affected packages:")
|
print("Affected packages:")
|
||||||
print(cve["affectedpackages"])
|
print(cve["affectedpackages"])
|
||||||
|
@ -88,8 +109,12 @@ def print_report(cves_report, title):
|
||||||
print(cve_line)
|
print(cve_line)
|
||||||
|
|
||||||
|
|
||||||
print("\nERROR: CVEs that have no cvss2Score or cvss2Vector: %d \n" \
|
if CVSS_VER == "cvssv3":
|
||||||
% (len(cves_report["cves_w_errors"])))
|
print("\nERROR: CVEs that have no cvss3Score or cvss3Vector: %d \n" \
|
||||||
|
% (len(cves_report["cves_w_errors"])))
|
||||||
|
else:
|
||||||
|
print("\nERROR: CVEs that have no cvss2Score or cvss2Vector: %d \n" \
|
||||||
|
% (len(cves_report["cves_w_errors"])))
|
||||||
for cve in cves_report["cves_w_errors"]:
|
for cve in cves_report["cves_w_errors"]:
|
||||||
print(cve)
|
print(cve)
|
||||||
|
|
||||||
|
@ -130,49 +155,112 @@ def get_affectedpackages(data, cve_id):
|
||||||
allfixed = "unfixed"
|
allfixed = "unfixed"
|
||||||
return affectedpackages_list, allfixed
|
return affectedpackages_list, allfixed
|
||||||
|
|
||||||
def main():
|
def update_report():
|
||||||
|
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_wont_fix"] = cves_wont_fix
|
||||||
|
cves_report["cves_to_omit"] = cves_to_omit
|
||||||
|
|
||||||
|
def cvssv3_pb_alg():
|
||||||
"""
|
"""
|
||||||
main function
|
Patchback algo for CVSSV3 report
|
||||||
Rules to consider a CVE valid for STX from:
|
|
||||||
https://wiki.openstack.org/wiki/StarlingX/Security/CVE_Support_Policy
|
|
||||||
"""
|
"""
|
||||||
data = {}
|
for cve in cves_valid:
|
||||||
cves = []
|
if (cve["cvss3Score"] >= 7.8
|
||||||
cves_valid = []
|
and cve["av"] == "N"
|
||||||
cves_to_fix = []
|
and cve["ac"] == "L"
|
||||||
cves_to_fix_lp = []
|
and cve["ui"] == "R"
|
||||||
cves_to_track = []
|
and cve["ai"] != "N"):
|
||||||
cves_w_errors = []
|
if cve["status"] == "fixed":
|
||||||
cves_wont_fix = []
|
bug = find_lp_assigned(cve["id"])
|
||||||
cves_to_omit = []
|
if (bug):
|
||||||
cves_report = {}
|
print(bug["status"])
|
||||||
|
if (bug["status"] == "Invalid" or bug["status"] == "Won't Fix"):
|
||||||
|
cves_wont_fix.append(cve)
|
||||||
|
else:
|
||||||
|
cves_to_fix_lp.append(cve)
|
||||||
|
else:
|
||||||
|
cves_to_fix.append(cve)
|
||||||
|
else:
|
||||||
|
cves_to_track.append(cve)
|
||||||
|
else:
|
||||||
|
cves_to_omit.append(cve)
|
||||||
|
|
||||||
if len(sys.argv) < 3:
|
update_report()
|
||||||
print("\nERROR : Missing arguments, the expected arguments are:")
|
|
||||||
print("\n %s <result.json> <title>\n" % (sys.argv[0]))
|
|
||||||
print("\n result.json = json file generated from: vuls report -format-json")
|
|
||||||
print("\n")
|
|
||||||
sys.exit(0)
|
|
||||||
|
|
||||||
if os.path.isfile(sys.argv[1]):
|
|
||||||
results_json = sys.argv[1]
|
|
||||||
else:
|
|
||||||
print("%s is not a file" % sys.argv[1])
|
|
||||||
sys.exit(0)
|
|
||||||
|
|
||||||
title = sys.argv[2]
|
def cvssv2_pb_alg():
|
||||||
|
"""
|
||||||
|
Patchback algo for CVSSV2 report
|
||||||
|
"""
|
||||||
|
for cve in cves_valid:
|
||||||
|
if (cve["cvss2Score"] >= 7.0
|
||||||
|
and cve["av"] == "N"
|
||||||
|
and cve["ac"] == "L"
|
||||||
|
and ("N" in cve["au"] or "S" in cve["au"])
|
||||||
|
and ("P" in cve["ai"] or "C" in cve["ai"])):
|
||||||
|
if cve["status"] == "fixed":
|
||||||
|
bug = find_lp_assigned(cve["id"])
|
||||||
|
if (bug):
|
||||||
|
print(bug["status"])
|
||||||
|
if (bug["status"] == "Invalid" or bug["status"] == "Won't Fix"):
|
||||||
|
cves_wont_fix.append(cve)
|
||||||
|
else:
|
||||||
|
cves_to_fix_lp.append(cve)
|
||||||
|
else:
|
||||||
|
cves_to_fix.append(cve)
|
||||||
|
else:
|
||||||
|
cves_to_track.append(cve)
|
||||||
|
else:
|
||||||
|
cves_to_omit.append(cve)
|
||||||
|
|
||||||
try:
|
update_report()
|
||||||
with open(results_json) as json_file:
|
|
||||||
data = json.load(json_file)
|
|
||||||
except ValueError as error:
|
|
||||||
print(error)
|
|
||||||
|
|
||||||
for element in data["scannedCves"]:
|
def cvssv3_parse_n_report(cves,title,data):
|
||||||
cve = {}
|
"""
|
||||||
cve["id"] = str(element.strip())
|
Parse and generate report for CVSSV3
|
||||||
cves.append(cve)
|
"""
|
||||||
|
for cve in cves:
|
||||||
|
cve_id = cve["id"]
|
||||||
|
affectedpackages_list = []
|
||||||
|
allfixed = "fixed"
|
||||||
|
try:
|
||||||
|
nvd2_score = data["scannedCves"][cve_id]["cveContents"]["nvd"]["cvss3Score"]
|
||||||
|
cvss3vector = data["scannedCves"][cve_id]["cveContents"]["nvd"]["cvss3Vector"]
|
||||||
|
except KeyError:
|
||||||
|
cves_w_errors.append(cve)
|
||||||
|
else:
|
||||||
|
cve["cvss3Score"] = nvd2_score
|
||||||
|
for element in cvss3vector.split("/"):
|
||||||
|
if "AV:" in element:
|
||||||
|
_av = element.split(":")[1]
|
||||||
|
if "AC:" in element:
|
||||||
|
_ac = element.split(":")[1]
|
||||||
|
if "A:" in element:
|
||||||
|
_ai = element.split(":")[1]
|
||||||
|
if "UI:" in element:
|
||||||
|
_ui = element.split(":")[1]
|
||||||
|
print(cve)
|
||||||
|
cve["av"] = str(_av)
|
||||||
|
cve["ac"] = str(_ac)
|
||||||
|
cve["ai"] = str(_ai)
|
||||||
|
cve["ui"] = str(_ui)
|
||||||
|
cve["summary"] = get_summary(data, cve_id)
|
||||||
|
cve["sourcelink"] = get_source_link(data, cve_id)
|
||||||
|
affectedpackages_list, allfixed = get_affectedpackages(data, cve_id)
|
||||||
|
cve["affectedpackages"] = affectedpackages_list
|
||||||
|
cve["status"] = allfixed
|
||||||
|
cves_valid.append(cve)
|
||||||
|
cvssv3_pb_alg()
|
||||||
|
print_report(cves_report, title)
|
||||||
|
print_html_report(cves_report, title)
|
||||||
|
|
||||||
|
def cvssv2_parse_n_report(cves,title,data):
|
||||||
|
"""
|
||||||
|
Parse and generate report for CVSSV2
|
||||||
|
"""
|
||||||
for cve in cves:
|
for cve in cves:
|
||||||
cve_id = cve["id"]
|
cve_id = cve["id"]
|
||||||
affectedpackages_list = []
|
affectedpackages_list = []
|
||||||
|
@ -203,37 +291,55 @@ def main():
|
||||||
cve["affectedpackages"] = affectedpackages_list
|
cve["affectedpackages"] = affectedpackages_list
|
||||||
cve["status"] = allfixed
|
cve["status"] = allfixed
|
||||||
cves_valid.append(cve)
|
cves_valid.append(cve)
|
||||||
|
cvssv2_pb_alg()
|
||||||
for cve in cves_valid:
|
|
||||||
if (cve["cvss2Score"] >= 7.0
|
|
||||||
and cve["av"] == "N"
|
|
||||||
and cve["ac"] == "L"
|
|
||||||
and ("N" in cve["au"] or "S" in cve["au"])
|
|
||||||
and ("P" in cve["ai"] or "C" in cve["ai"])):
|
|
||||||
if cve["status"] == "fixed":
|
|
||||||
bug = find_lp_assigned(cve["id"])
|
|
||||||
if (bug):
|
|
||||||
print(bug["status"])
|
|
||||||
if (bug["status"] == "Invalid" or bug["status"] == "Won't Fix"):
|
|
||||||
cves_wont_fix.append(cve)
|
|
||||||
else:
|
|
||||||
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_wont_fix"] = cves_wont_fix
|
|
||||||
cves_report["cves_to_omit"] = cves_to_omit
|
|
||||||
|
|
||||||
print_report(cves_report, title)
|
print_report(cves_report, title)
|
||||||
print_html_report(cves_report, title)
|
print_html_report(cves_report, title)
|
||||||
|
|
||||||
|
def main():
|
||||||
|
"""
|
||||||
|
main function
|
||||||
|
Rules to consider a CVE valid for STX from:
|
||||||
|
https://wiki.openstack.org/wiki/StarlingX/Security/CVE_Support_Policy
|
||||||
|
"""
|
||||||
|
data = {}
|
||||||
|
cves = []
|
||||||
|
|
||||||
|
|
||||||
|
if len(sys.argv) < 4:
|
||||||
|
print("\nERROR : Missing arguments, the expected arguments are:")
|
||||||
|
print("\n %s <result.json> <title> [cvssv3|cvssv2]\n" % (sys.argv[0]))
|
||||||
|
print("\n result.json = json file generated from: vuls report -format-json")
|
||||||
|
print("\n")
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
if os.path.isfile(sys.argv[1]):
|
||||||
|
results_json = sys.argv[1]
|
||||||
|
else:
|
||||||
|
print("%s is not a file" % sys.argv[1])
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
title = sys.argv[2]
|
||||||
|
|
||||||
|
try:
|
||||||
|
with open(results_json) as json_file:
|
||||||
|
data = json.load(json_file)
|
||||||
|
except ValueError as error:
|
||||||
|
print(error)
|
||||||
|
|
||||||
|
for element in data["scannedCves"]:
|
||||||
|
cve = {}
|
||||||
|
cve["id"] = str(element.strip())
|
||||||
|
cves.append(cve)
|
||||||
|
global CVSS_VER
|
||||||
|
CVSS_VER=sys.argv[3].lower()
|
||||||
|
if CVSS_VER =="cvssv3":
|
||||||
|
cvssv3_parse_n_report(cves,title,data)
|
||||||
|
elif CVSS_VER == "cvssv2":
|
||||||
|
cvssv2_parse_n_report(cves,title,data)
|
||||||
|
else:
|
||||||
|
print("\n argument not matching \n enter [cvssv3|cvssv2] ")
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main()
|
main()
|
||||||
|
|
|
@ -0,0 +1,127 @@
|
||||||
|
<head></head>
|
||||||
|
<body>
|
||||||
|
<h1>Security report from vuls scan from {{title}}</h1>
|
||||||
|
<h2>CVEs to fix w/o a launchpad assigned: {{cves_to_fix | length}}</h2>
|
||||||
|
<table>
|
||||||
|
{% if cves_to_fix|length >= 1 %}
|
||||||
|
<tr>
|
||||||
|
{% for head in heads %}
|
||||||
|
<th>{{head}}</th>
|
||||||
|
{% endfor %}
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
{% for cve in cves_to_fix %}
|
||||||
|
<tr>
|
||||||
|
<td>{{cve["id"]}}</td>
|
||||||
|
<td>{{cve["status"]}}</td>
|
||||||
|
<td>{{cve["cvss3Score"]}}</td>
|
||||||
|
<td>{{cve["av"]}}</td>
|
||||||
|
<td>{{cve["ac"]}}</td>
|
||||||
|
<td>{{cve["ui"]}}</td>
|
||||||
|
<td>{{cve["ai"]}}</td>
|
||||||
|
</tr>
|
||||||
|
{% 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["cvss3Score"]}}</td>
|
||||||
|
<td>{{cve["av"]}}</td>
|
||||||
|
<td>{{cve["ac"]}}</td>
|
||||||
|
<td>{{cve["ui"]}}</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 %}
|
||||||
|
<tr>
|
||||||
|
{% for head in heads %}
|
||||||
|
<th>{{head}}</th>
|
||||||
|
{% endfor %}
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
{% for cve in cves_to_track %}
|
||||||
|
<tr>
|
||||||
|
<td>{{cve["id"]}}</td>
|
||||||
|
<td>{{cve["status"]}}</td>
|
||||||
|
<td>{{cve["cvss3Score"]}}</td>
|
||||||
|
<td>{{cve["av"]}}</td>
|
||||||
|
<td>{{cve["ac"]}}</td>
|
||||||
|
<td>{{cve["ui"]}}</td>
|
||||||
|
<td>{{cve["ai"]}}</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
</table>
|
||||||
|
<h2> CVEs that are Invalid or Won't Fix: {{cves_wont_fix | length}}</h2>
|
||||||
|
<table>
|
||||||
|
{% if cves_wont_fix|length >= 1 %}
|
||||||
|
<tr>
|
||||||
|
{% for head in heads %}
|
||||||
|
<th>{{head}}</th>
|
||||||
|
{% endfor %}
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
{% for cve in cves_wont_fix %}
|
||||||
|
<tr>
|
||||||
|
<td>{{cve["id"]}}</td>
|
||||||
|
<td>{{cve["status"]}}</td>
|
||||||
|
<td>{{cve["cvss3Score"]}}</td>
|
||||||
|
<td>{{cve["av"]}}</td>
|
||||||
|
<td>{{cve["ac"]}}</td>
|
||||||
|
<td>{{cve["ui"]}}</td>
|
||||||
|
<td>{{cve["ai"]}}</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<h2> CVEs to omit: {{cves_to_omit | length}}</h2>
|
||||||
|
<table>
|
||||||
|
{% if cves_to_omit|length >= 1 %}
|
||||||
|
<tr>
|
||||||
|
{% for head in heads %}
|
||||||
|
<th>{{head}}</th>
|
||||||
|
{% endfor %}
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
{% for cve in cves_to_omit %}
|
||||||
|
<tr>
|
||||||
|
<td>{{cve["id"]}}</td>
|
||||||
|
<td>{{cve["status"]}}</td>
|
||||||
|
<td>{{cve["cvss3Score"]}}</td>
|
||||||
|
<td>{{cve["av"]}}</td>
|
||||||
|
<td>{{cve["ac"]}}</td>
|
||||||
|
<td>{{cve["ui"]}}</td>
|
||||||
|
<td>{{cve["ai"]}}</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<h2>ERROR: CVEs that have no cvss3Score or cvss2Vector:{{cves_w_errors | length}}</h2>
|
||||||
|
<table>
|
||||||
|
{% if cves_w_errors|length >= 1 %}
|
||||||
|
{% for cve in cves_w_errors %}
|
||||||
|
<tr>
|
||||||
|
<td>{{cve["id"]}}</td>
|
||||||
|
<td>{{cve["status"]}}</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
</table>
|
||||||
|
</body>
|
Loading…
Reference in New Issue