Skip to content

Commit

Permalink
Add legacy parsing method for qualys
Browse files Browse the repository at this point in the history
  • Loading branch information
Maffooch committed Apr 1, 2024
1 parent 582eb19 commit 97fde45
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 32 deletions.
4 changes: 4 additions & 0 deletions dojo/settings/settings.dist.py
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,9 @@
DD_ENABLE_AUDITLOG=(bool, True),
# Specifies whether the "first seen" date of a given report should be used over the "last seen" date
DD_USE_FIRST_SEEN=(bool, False),
# When set to True, use the older version of the qualys parser that is a more heavy handed in setting severity
# with the use of CVSS scores to potentially override the severity found in the report produced by the tool
DD_QUALYS_LEGACY_SEVERITY_PARSING=(bool, True),
)


Expand Down Expand Up @@ -1699,6 +1702,7 @@ def saml2_attrib_map_format(dict):
AUDITLOG_FLUSH_RETENTION_PERIOD = env('DD_AUDITLOG_FLUSH_RETENTION_PERIOD')
ENABLE_AUDITLOG = env('DD_ENABLE_AUDITLOG')
USE_FIRST_SEEN = env('DD_USE_FIRST_SEEN')
USE_QUALYS_LEGACY_SEVERITY_PARSING = env('DD_QUALYS_LEGACY_SEVERITY_PARSING')


# ------------------------------------------------------------------------------
Expand Down
33 changes: 25 additions & 8 deletions dojo/tools/qualys/csv_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,30 @@ def _clean_cve_data(cve_string: str) -> list:
return cve_list


def get_severity(value: str) -> str:
legacy_severity_lookup = {
"1": "Info",
"2": "Low",
"3": "Medium",
"4": "High",
"5": "Critical",
}
# Severity mapping taken from
# https://qualysguard.qg2.apps.qualys.com/portal-help/en/malware/knowledgebase/
qualys_severity_lookup = {
"1": "Low",
"2": "Low",
"3": "Medium",
"4": "High",
"5": "High",
}

if settings.USE_QUALYS_LEGACY_SEVERITY_PARSING:
return legacy_severity_lookup.get(value, "Info")
else:
return qualys_severity_lookup.get(value, "Info")


def build_findings_from_dict(report_findings: [dict]) -> [Finding]:
"""
Takes a list of Dictionaries built from CSV and creates a Finding object
Expand All @@ -117,13 +141,6 @@ def build_findings_from_dict(report_findings: [dict]) -> [Finding]:
Returns:
"""
severity_lookup = {
"1": "Info",
"2": "Low",
"3": "Medium",
"4": "High",
"5": "Critical",
}
dojo_findings = []
for report_finding in report_findings:
# Get endpoint meta
Expand Down Expand Up @@ -167,7 +184,7 @@ def build_findings_from_dict(report_findings: [dict]) -> [Finding]:
title=f"QID-{report_finding['QID']} | {report_finding['Title']}",
mitigation=report_finding["Solution"],
description=f"{report_finding['Threat']}\nResult Evidence: \n{report_finding.get('Threat', 'Not available')}",
severity=severity_lookup.get(report_finding["Severity"], "Info"),
severity=get_severity(report_finding["Severity"]),
impact=report_finding["Impact"],
date=date,
vuln_id_from_tool=report_finding["QID"],
Expand Down
61 changes: 37 additions & 24 deletions dojo/tools/qualys/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,42 @@
}


def get_severity(severity_value: int, cvss_value: float) -> str:
legacy_severity_lookup = {
1: "Informational",
2: "Low",
3: "Medium",
4: "High",
5: "Critical",
}
# Severity mapping taken from
# https://qualysguard.qg2.apps.qualys.com/portal-help/en/malware/knowledgebase/
qualys_severity_lookup = {
1: "Low",
2: "Low",
3: "Medium",
4: "High",
5: "High",
}

if settings.USE_QUALYS_LEGACY_SEVERITY_PARSING:
sev = "Informational"
if cvss_value is not None and cvss_value > 0:
if 0.1 <= float(cvss_value) <= 3.9:
sev = "Low"
elif 4.0 <= float(cvss_value) <= 6.9:
sev = "Medium"
elif 7.0 <= float(cvss_value) <= 8.9:
sev = "High"
elif float(cvss_value) >= 9.0:
sev = "Critical"
elif severity_value is not None:
sev = legacy_severity_lookup.get(severity_value, "Informational")
return sev
else:
return qualys_severity_lookup.get(severity_value, "Informational")


def htmltext(blob):
h = html2text.HTML2Text()
h.ignore_links = False
Expand Down Expand Up @@ -211,30 +247,7 @@ def parse_finding(host, tree):
# The CVE in Qualys report might not have a CVSS score, so findings are informational by default
# unless we can find map to a Severity OR a CVSS score from the
# findings detail.
sev = None
if _temp.get("CVSS_value") is not None and _temp["CVSS_value"] > 0:
if 0.1 <= float(_temp["CVSS_value"]) <= 3.9:
sev = "Low"
elif 4.0 <= float(_temp["CVSS_value"]) <= 6.9:
sev = "Medium"
elif 7.0 <= float(_temp["CVSS_value"]) <= 8.9:
sev = "High"
elif float(_temp["CVSS_value"]) >= 9.0:
sev = "Critical"
elif vuln_item.findtext("SEVERITY") is not None:
if int(vuln_item.findtext("SEVERITY")) == 1:
sev = "Informational"
elif int(vuln_item.findtext("SEVERITY")) == 2:
sev = "Low"
elif int(vuln_item.findtext("SEVERITY")) == 3:
sev = "Medium"
elif int(vuln_item.findtext("SEVERITY")) == 4:
sev = "High"
elif int(vuln_item.findtext("SEVERITY")) == 5:
sev = "Critical"
elif sev is None:
sev = "Informational"

sev = get_severity(vuln_item.findtext("SEVERITY"), _temp.get("CVSS_value", None))
finding = None
if _temp_cve_details:
refs = "\n".join(list(_cl.values()))
Expand Down

0 comments on commit 97fde45

Please sign in to comment.