Skip to content

Commit

Permalink
🔨 rework kubescape parser (#11229)
Browse files Browse the repository at this point in the history
* 🔨 rework kubescape parser

* update

* fix unittest, ruff

* update

* fix

* sha sum

* retrigger unittest

* Update dojo/tools/kubescape/parser.py

Co-authored-by: Charles Neill <[email protected]>

* review

* retrigger unittests

---------

Co-authored-by: Charles Neill <[email protected]>
  • Loading branch information
manuel-sommer and cneill authored Nov 16, 2024
1 parent cf452c8 commit 5168154
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 62 deletions.
2 changes: 1 addition & 1 deletion dojo/settings/.settings.dist.py.sha256sum
Original file line number Diff line number Diff line change
@@ -1 +1 @@
f09caa2d4e41f44b7cd6ecf2f1400817d4776e703bd039c8d857f1356382e1f3
f85484f23e59aabe591b30db10e0de05aaeeb9d8979d236d565dc8279e03e116
1 change: 1 addition & 0 deletions dojo/settings/settings.dist.py
Original file line number Diff line number Diff line change
Expand Up @@ -1760,6 +1760,7 @@ def saml2_attrib_map_format(dict):
"ELSA": "https://linux.oracle.com/errata/&&.html", # e.g. https://linux.oracle.com/errata/ELSA-2024-12714.html
"ELBA": "https://linux.oracle.com/errata/&&.html", # e.g. https://linux.oracle.com/errata/ELBA-2024-7457.html
"RXSA": "https://errata.rockylinux.org/", # e.g. https://errata.rockylinux.org/RXSA-2024:4928
"C-": "https://hub.armosec.io/docs/", # e.g. https://hub.armosec.io/docs/c-0085
"AVD": "https://avd.aquasec.com/misconfig/", # e.g. https://avd.aquasec.com/misconfig/avd-ksv-01010
"KHV": "https://avd.aquasec.com/misconfig/kubernetes/", # e.g. https://avd.aquasec.com/misconfig/kubernetes/khv045
"CAPEC": "https://capec.mitre.org/data/definitions/&&.html", # e.g. https://capec.mitre.org/data/definitions/157.html
Expand Down
2 changes: 1 addition & 1 deletion dojo/templatetags/display_tags.py
Original file line number Diff line number Diff line change
Expand Up @@ -780,7 +780,7 @@ def vulnerability_url(vulnerability_id):

for key in settings.VULNERABILITY_URLS:
if vulnerability_id.upper().startswith(key):
if key in ["AVD", "KHV"]:
if key in ["AVD", "KHV", "C-"]:
return settings.VULNERABILITY_URLS[key] + str(vulnerability_id.lower())
if "&&" in settings.VULNERABILITY_URLS[key]:
# Process specific keys specially if need
Expand Down
118 changes: 59 additions & 59 deletions dojo/tools/kubescape/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,65 +59,65 @@ def get_findings(self, filename, test):
controls = results[0].get("controls", [])

for control in controls:
# This condition is true if the result doesn't contain the status for each control (old format)
retrocompatibility_condition = "status" not in control or "status" not in control["status"]
if retrocompatibility_condition or control["status"]["status"] == "failed":
control_name = control["name"]
if resource_type and resource_name and control_name:
title = f"{control_name} - {resource_type} {resource_name}"
else:
title = f"{control_name} - {resourceid}"
controlID = control["controlID"]

# Find control details
controlSummary = self.find_control_summary_by_id(data, controlID)
if controlSummary is None:
severity = "Info"
mitigation = ""
else:
severity = self.severity_mapper(controlSummary.get("scoreFactor", 0))
# Define mitigation if available
if "mitigation" in controlSummary:
mitigation = controlSummary["mitigation"]
for rule in control["rules"]:
if rule["status"] == "passed":
continue
# This condition is true if the result doesn't contain the status for each control (old format)
retrocompatibility_condition = "status" not in control or "status" not in control["status"]
if retrocompatibility_condition or control["status"]["status"] == "failed":
control_name = control["name"]
if resource_type and resource_name and control_name:
title = f"{control_name} - {resource_type} {resource_name}"
else:
mitigation = ""
title = f"{control_name} - {resourceid}"
controlID = control["controlID"]

armoLink = f"https://hub.armosec.io/docs/{controlID.lower()}"
description = "**Summary:** " + f"The ressource '{resourceid}' has failed the control '{control_name}'." + "\n"
if controlSummary is not None and "description" in controlSummary:
description += "**Description:** " + controlSummary["description"] + "\n"

# Define category if available
if controlSummary is not None and "category" in controlSummary and "subCategory" in controlSummary["category"]:
category_name = controlSummary["category"]["name"]
category_subname = controlSummary["category"]["subCategory"]["name"]
category = f"{category_name} > {category_subname}"
description += "**Category:** " + category + "\n"
elif controlSummary is not None and "category" in controlSummary and "name" in controlSummary["category"]:
category = controlSummary["category"]["name"]
description += "**Category:** " + category + "\n"

description += "View control details here: " + self.__hyperlink(armoLink)

steps_to_reproduce = "The following rules have failed :" + "\n"
steps_to_reproduce += "\t**Rules:** " + str(json.dumps(control["rules"], indent=4)) + "\n"

steps_to_reproduce += "Resource object may contain evidence:" + "\n"
steps_to_reproduce += "\t**Resource object:** " + str(json.dumps(resource["object"], indent=4))

references = armoLink

find = Finding(
title=textwrap.shorten(title, 150),
test=test,
description=description,
mitigation=mitigation,
steps_to_reproduce=steps_to_reproduce,
references=references,
severity=severity,
component_name=resourceid,
static_finding=True,
dynamic_finding=False,
)
findings.append(find)
# Find control details
controlSummary = self.find_control_summary_by_id(data, controlID)
if controlSummary is None:
severity = "Info"
mitigation = ""
else:
severity = self.severity_mapper(controlSummary.get("scoreFactor", 0))
# Define mitigation if available
if "mitigation" in controlSummary:
mitigation = controlSummary["mitigation"]
else:
mitigation = ""

description = "**Summary:** " + f"The ressource '{resourceid}' has failed the control '{control_name}'." + "\n"
if controlSummary is not None and "description" in controlSummary:
description += "**Description:** " + controlSummary["description"] + "\n"

# Define category if available
if controlSummary is not None and "category" in controlSummary and "subCategory" in controlSummary["category"]:
category_name = controlSummary["category"]["name"]
category_subname = controlSummary["category"]["subCategory"]["name"]
category = f"{category_name} > {category_subname}"
description += "**Category:** " + category + "\n"
elif controlSummary is not None and "category" in controlSummary and "name" in controlSummary["category"]:
category = controlSummary["category"]["name"]
description += "**Category:** " + category + "\n"

steps_to_reproduce = "The following rules have failed :" + "\n"
steps_to_reproduce += "\t**Rules:** " + str(json.dumps(control["rules"], indent=4)) + "\n"
steps_to_reproduce += "Resource object may contain evidence:" + "\n"
steps_to_reproduce += "\t**Resource object:** " + str(json.dumps(resource["object"], indent=4))

find = Finding(
title=textwrap.shorten(title, 150),
test=test,
description=description,
mitigation=mitigation,
steps_to_reproduce=steps_to_reproduce,
references=f"https://hub.armosec.io/docs/{controlID.lower()}",
severity=severity,
component_name=resourceid,
static_finding=True,
dynamic_finding=False,
)
if controlID is not None:
find.unsaved_vulnerability_ids = []
find.unsaved_vulnerability_ids.append(controlID)
findings.append(find)
return findings
2 changes: 1 addition & 1 deletion unittests/tools/test_kubescape_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ def test_parse_file_has_many_findings(self):
with open(get_unit_tests_path() + "/scans/kubescape/many_findings.json", encoding="utf-8") as testfile:
parser = KubescapeParser()
findings = parser.get_findings(testfile, Test())
self.assertEqual(710, len(findings))
self.assertEqual(349, len(findings))

def test_parse_file_has_many_results(self):
with open(get_unit_tests_path() + "/scans/kubescape/results.json", encoding="utf-8") as testfile:
Expand Down

0 comments on commit 5168154

Please sign in to comment.