From 4d2a03a600fb9c9f4f82bb8d2d9c93e286a286e0 Mon Sep 17 00:00:00 2001 From: Pavel Nakonechnyi Date: Mon, 6 May 2024 10:54:18 +0200 Subject: [PATCH] t --- dojo/tools/neuvector/parser.py | 3 - dojo/tools/neuvector_compliance/parser.py | 81 ++++++++++++++++++++++- 2 files changed, 78 insertions(+), 6 deletions(-) diff --git a/dojo/tools/neuvector/parser.py b/dojo/tools/neuvector/parser.py index 12a664d2b29..b7a7c7d9118 100644 --- a/dojo/tools/neuvector/parser.py +++ b/dojo/tools/neuvector/parser.py @@ -55,9 +55,6 @@ def get_items(self, tree, test): item = get_asset_item(node, test) unique_key = node.get("name") + str(node.get("severity")) items[unique_key] = item - - # asset-style collection with compliance issues of several assets - # if "compliance_issues" in tree: return list(items.values()) diff --git a/dojo/tools/neuvector_compliance/parser.py b/dojo/tools/neuvector_compliance/parser.py index 74e5e515fd1..90e30e4c854 100644 --- a/dojo/tools/neuvector_compliance/parser.py +++ b/dojo/tools/neuvector_compliance/parser.py @@ -1,7 +1,7 @@ import hashlib import json -from dojo.models import Finding +from dojo.models import Endpoint,Finding NEUVECTOR_SCAN_NAME = "NeuVector (compliance)" @@ -35,10 +35,10 @@ def get_items(tree, test): # endpoints like /v1/scan/workload/{id}. otherwize, it is an export from # /v1/host/{id}/compliance or similar. thus, we need to support items in a # bit different leafs. - testsTree = None + testsTree = [] if "report" in tree: testsTree = tree.get("report").get("checks", []) - else: + elif "items" in tree: testsTree = tree.get("items", []) for node in testsTree: @@ -51,6 +51,23 @@ def get_items(tree, test): ) unique_key = hashlib.md5(unique_key.encode("utf-8")).hexdigest() items[unique_key] = item + + # asset-style collection with compliance issues of several assets + testsAssetsTree = [] + if "compliance_issues" in tree: + testsAssetsTree = tree.get("compliance_issues", []) + for node in testsAssetsTree: + item = get_asset_item(node, test) + unique_key = ( + node.get("name") + + node.get("category") + + node.get("type") + + node.get("level") + + node.get("profile") + ) + unique_key = hashlib.md5(unique_key.encode("utf-8")).hexdigest() + items[unique_key] = item + return list(items.values()) @@ -117,6 +134,64 @@ def get_item(node, test): return finding +def get_asset_item(comp_issue, test): + name = comp_issue.get("name") + test_description = comp_issue.get("description").rstrip() + + test_severity = comp_issue.get("level") + + mitigation = comp_issue.get("remediation", "").rstrip() + + category = comp_issue.get("category") + + test_profile = comp_issue.get("profile", "profile unknown") + + full_description = "

{} ({}), {}:

".format( + name, category, test_profile + ) + full_description += "

{}

".format(test_description) + full_description += "

Audit: {}

".format(test_severity) + full_description += "

Mitigation:

" + full_description += "

{}

".format(mitigation) + + tags = comp_issue.get("tags", []) + if len(tags) > 0: + full_description += "

Tags:

" + for t in tags: + full_description += "

{}

".format(str(t).rstrip()) + + messages = comp_issue.get("message", []) + if len(messages) > 0: + full_description += "

Messages:

" + for m in messages: + full_description += "

{}

".format(str(m).rstrip()) + + finding = Finding( + title="{name} - {desc}".format(name, desc=test_description), + test=test, + description=full_description, + severity=convert_severity(test_severity), + mitigation=mitigation, + vuln_id_from_tool="{category}_{name}".format(category, name), + impact="", + static_finding=True, + dynamic_finding=False, + ) + + finding.unsaved_vulnerability_ids = [] + + finding.unsaved_endpoints = [] + + nodes = comp_issue.get("nodes", []) + for node in nodes: + endpoint = Endpoint( + host=node.get("display_name", ""), + ) + finding.unsaved_endpoints.append(endpoint) + + return finding + + # see neuvector/share/clus_apis.go def convert_severity(severity): if severity.lower() == "high":