diff --git a/dojo/tools/clair/clair_parser.py b/dojo/tools/clair/clair_parser.py
new file mode 100644
index 00000000000..55fc94ad392
--- /dev/null
+++ b/dojo/tools/clair/clair_parser.py
@@ -0,0 +1,59 @@
+import logging
+from dojo.models import Finding
+logger = logging.getLogger(__name__)
+
+
+class ClairScan(object):
+ def get_items_clair(self, tree, test):
+ items = {}
+ for node in tree:
+ item = self.get_item_clair(node, test)
+ unique_key = str(node["vulnerability"]) + str(node["featurename"])
+ items[unique_key] = item
+ return list(items.values())
+
+ def get_item_clair(self, item_node, test):
+ if (
+ item_node["severity"] == "Negligible"
+ or item_node["severity"] == "Unknown"
+ ):
+ severity = "Info"
+ else:
+ severity = item_node["severity"]
+
+ finding = Finding(
+ title=item_node["vulnerability"]
+ + " - "
+ + "("
+ + item_node["featurename"]
+ + ", "
+ + item_node["featureversion"]
+ + ")",
+ test=test,
+ severity=severity,
+ description=item_node["description"]
+ + "\n Vulnerable feature: "
+ + item_node["featurename"]
+ + "\n Vulnerable Versions: "
+ + str(item_node["featureversion"])
+ + "\n Fixed by: "
+ + str(item_node["fixedby"])
+ + "\n Namespace: "
+ + str(item_node["namespace"])
+ + "\n CVE: "
+ + str(item_node["vulnerability"]),
+ mitigation=item_node["fixedby"],
+ references=item_node["link"],
+ component_name=item_node["featurename"],
+ component_version=item_node["featureversion"],
+ false_p=False,
+ duplicate=False,
+ out_of_scope=False,
+ mitigated=None,
+ static_finding=True,
+ dynamic_finding=False,
+ impact="No impact provided",
+ )
+ if item_node["vulnerability"]:
+ finding.unsaved_vulnerability_ids = [item_node["vulnerability"]]
+ return finding
diff --git a/dojo/tools/clair/clairklar_parser.py b/dojo/tools/clair/clairklar_parser.py
new file mode 100644
index 00000000000..5a24dbb05f9
--- /dev/null
+++ b/dojo/tools/clair/clairklar_parser.py
@@ -0,0 +1,102 @@
+import logging
+from dojo.models import Finding
+logger = logging.getLogger(__name__)
+
+
+class ClairKlarScan(object):
+ def get_items_klar(self, tree, test):
+ items = list()
+ clair_severities = [
+ "Unknown",
+ "Negligible",
+ "Low",
+ "Medium",
+ "High",
+ "Critical",
+ "Defcon1",
+ ]
+ for clair_severity in clair_severities:
+ items.extend(
+ self.set_items_for_severity(tree, test, clair_severity)
+ )
+ return items
+
+ def set_items_for_severity(self, tree, test, severity):
+ items = list()
+ tree_severity = tree.get(severity)
+ if tree_severity:
+ for data in self.get_items_clairklar(tree_severity, test):
+ items.append(data)
+ logger.debug("Appended findings for severity " + severity)
+ else:
+ logger.debug("No findings for severity " + severity)
+ return items
+
+ def get_items_clairklar(self, tree_severity, test):
+ items = {}
+ for node in tree_severity:
+ item = self.get_item_clairklar(node, test)
+ unique_key = str(node["Name"]) + str(node["FeatureName"])
+ items[unique_key] = item
+ return items.values()
+
+ def get_item_clairklar(self, item_node, test):
+ if item_node["Severity"] == "Negligible":
+ severity = "Info"
+ elif item_node["Severity"] == "Unknown":
+ severity = "Critical"
+ elif item_node["Severity"] == "Defcon1":
+ severity = "Critical"
+ else:
+ severity = item_node["Severity"]
+ description = ""
+ if "Description" in item_node:
+ description += item_node["Description"] + "\n
"
+ if "FeatureName" in item_node:
+ description += (
+ "Vulnerable feature: " + item_node["FeatureName"] + "\n
"
+ )
+ if "FeatureVersion" in item_node:
+ description += " Vulnerable Versions: " + str(
+ item_node["FeatureVersion"]
+ )
+
+ mitigation = ""
+ if "FixedBy" in item_node:
+ description = description + "\n Fixed by: " + str(item_node["FixedBy"])
+ mitigation = (
+ "Please use version "
+ + item_node["FixedBy"]
+ + " of library "
+ + item_node["FeatureName"]
+ )
+ else:
+ mitigation = "A patch could not been found"
+
+ link = ""
+ if "Link" in item_node:
+ link = item_node["Link"]
+
+ finding = Finding(
+ title=item_node["Name"]
+ + " - "
+ + "("
+ + item_node["FeatureName"]
+ + ", "
+ + item_node["FeatureVersion"]
+ + ")",
+ test=test,
+ severity=severity,
+ description=description,
+ mitigation=mitigation,
+ references=link,
+ false_p=False,
+ duplicate=False,
+ out_of_scope=False,
+ mitigated=None,
+ cwe=1035, # Vulnerable Third Party Component
+ static_finding=True,
+ dynamic_finding=False,
+ impact="No impact provided",
+ )
+ return finding
diff --git a/dojo/tools/clair/parser.py b/dojo/tools/clair/parser.py
index dd1aef59cfd..b0701de287f 100644
--- a/dojo/tools/clair/parser.py
+++ b/dojo/tools/clair/parser.py
@@ -1,7 +1,6 @@
import json
-import logging
-from dojo.models import Finding
-logger = logging.getLogger(__name__)
+from dojo.tools.clair.clair_parser import ClairScan
+from dojo.tools.clair.clairklar_parser import ClairKlarScan
class ClairParser(object):
@@ -18,23 +17,9 @@ def get_findings(self, json_output, test):
tree = self.parse_json(json_output)
if tree:
if self.scanner == "clair":
- return self.get_items_clair(tree, test)
+ return ClairScan().get_items_clair(tree, test)
elif self.scanner == "clairklar":
- items = list()
- clair_severities = [
- "Unknown",
- "Negligible",
- "Low",
- "Medium",
- "High",
- "Critical",
- "Defcon1",
- ]
- for clair_severity in clair_severities:
- items.extend(
- self.set_items_for_severity(tree, test, clair_severity)
- )
- return items
+ return ClairKlarScan().get_items_klar(tree, test)
else:
return list()
@@ -54,137 +39,3 @@ def parse_json(self, json_output):
except BaseException:
raise ValueError("Invalid format")
return subtree
-
- def set_items_for_severity(self, tree, test, severity):
- items = list()
- tree_severity = tree.get(severity)
- if tree_severity:
- for data in self.get_items_clairklar(tree_severity, test):
- items.append(data)
- logger.debug("Appended findings for severity " + severity)
- else:
- logger.debug("No findings for severity " + severity)
- return items
-
- def get_items_clair(self, tree, test):
- items = {}
- for node in tree:
- item = self.get_item_clair(node, test)
- unique_key = str(node["vulnerability"]) + str(node["featurename"])
- items[unique_key] = item
- return list(items.values())
-
- def get_item_clair(self, item_node, test):
- if (
- item_node["severity"] == "Negligible"
- or item_node["severity"] == "Unknown"
- ):
- severity = "Info"
- else:
- severity = item_node["severity"]
-
- finding = Finding(
- title=item_node["vulnerability"]
- + " - "
- + "("
- + item_node["featurename"]
- + ", "
- + item_node["featureversion"]
- + ")",
- test=test,
- severity=severity,
- description=item_node["description"]
- + "\n Vulnerable feature: "
- + item_node["featurename"]
- + "\n Vulnerable Versions: "
- + str(item_node["featureversion"])
- + "\n Fixed by: "
- + str(item_node["fixedby"])
- + "\n Namespace: "
- + str(item_node["namespace"])
- + "\n CVE: "
- + str(item_node["vulnerability"]),
- mitigation=item_node["fixedby"],
- references=item_node["link"],
- component_name=item_node["featurename"],
- component_version=item_node["featureversion"],
- false_p=False,
- duplicate=False,
- out_of_scope=False,
- mitigated=None,
- static_finding=True,
- dynamic_finding=False,
- impact="No impact provided",
- )
- if item_node["vulnerability"]:
- finding.unsaved_vulnerability_ids = [item_node["vulnerability"]]
- return finding
-
- def get_items_clairklar(self, tree_severity, test):
- items = {}
- for node in tree_severity:
- item = self.get_item_clairklar(node, test)
- unique_key = str(node["Name"]) + str(node["FeatureName"])
- items[unique_key] = item
- return items.values()
-
- def get_item_clairklar(self, item_node, test):
- if item_node["Severity"] == "Negligible":
- severity = "Info"
- elif item_node["Severity"] == "Unknown":
- severity = "Critical"
- elif item_node["Severity"] == "Defcon1":
- severity = "Critical"
- else:
- severity = item_node["Severity"]
- description = ""
- if "Description" in item_node:
- description += item_node["Description"] + "\n
"
- if "FeatureName" in item_node:
- description += (
- "Vulnerable feature: " + item_node["FeatureName"] + "\n
"
- )
- if "FeatureVersion" in item_node:
- description += " Vulnerable Versions: " + str(
- item_node["FeatureVersion"]
- )
-
- mitigation = ""
- if "FixedBy" in item_node:
- description = description + "\n Fixed by: " + str(item_node["FixedBy"])
- mitigation = (
- "Please use version "
- + item_node["FixedBy"]
- + " of library "
- + item_node["FeatureName"]
- )
- else:
- mitigation = "A patch could not been found"
-
- link = ""
- if "Link" in item_node:
- link = item_node["Link"]
-
- finding = Finding(
- title=item_node["Name"]
- + " - "
- + "("
- + item_node["FeatureName"]
- + ", "
- + item_node["FeatureVersion"]
- + ")",
- test=test,
- severity=severity,
- description=description,
- mitigation=mitigation,
- references=link,
- false_p=False,
- duplicate=False,
- out_of_scope=False,
- mitigated=None,
- cwe=1035, # Vulnerable Third Party Component
- static_finding=True,
- dynamic_finding=False,
- impact="No impact provided",
- )
- return finding