Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mend SCA Parser update #11395

Open
wants to merge 48 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
f192eb6
Add unit test json files for Mend Platform - SAST Findings
testaccount90009 Dec 9, 2024
52e9388
Update test_mend_parser.py
testaccount90009 Dec 9, 2024
7d9b037
Fix newline eof
testaccount90009 Dec 9, 2024
69de822
Update parser.py
testaccount90009 Dec 9, 2024
f014e94
Update test_mend_parser.py
testaccount90009 Dec 9, 2024
6aa852e
Update test_mend_parser.py
testaccount90009 Dec 9, 2024
6ef3e18
Refactoring this for SCA only and SAST will be an additional PR - nee…
testaccount90009 Dec 9, 2024
bee60ea
Update parser.py
testaccount90009 Dec 9, 2024
893edc9
Update parser.py
testaccount90009 Dec 9, 2024
128698d
Update parser.py
testaccount90009 Dec 9, 2024
9290fae
fix loc 399 to 3999 for locations + add steps_to_reproduce for SCA Pl…
testaccount90009 Dec 10, 2024
99323d6
Fix spacing, remove trailing comma
testaccount90009 Dec 10, 2024
34d8364
Fix space
testaccount90009 Dec 10, 2024
9d50ad5
Removing redundancy
testaccount90009 Dec 10, 2024
122fbbc
Fix the join on locations for Platform SCA
testaccount90009 Dec 10, 2024
9ab5fbb
Removing redundancy component dependency type from description since …
testaccount90009 Dec 10, 2024
f179732
Make Impact more readible
testaccount90009 Dec 10, 2024
866ec7a
Update parser.py
testaccount90009 Dec 10, 2024
3e0e95f
Update format for unit test
testaccount90009 Dec 10, 2024
1357de4
Fix case on unit test
testaccount90009 Dec 10, 2024
ff0725c
Remove duplicate join to fix steps_to_reproduce formatting
testaccount90009 Dec 11, 2024
d4ac0e2
Fix join for locations and steps_to_reproduce
testaccount90009 Dec 11, 2024
51e7182
fix newline eof
testaccount90009 Dec 11, 2024
a1151e9
fix comma, remove redundant locations reference
testaccount90009 Dec 11, 2024
bc98f5d
Update parser.py
testaccount90009 Dec 12, 2024
104e452
Fix eof
testaccount90009 Dec 12, 2024
46cb936
Update parser.py
testaccount90009 Dec 12, 2024
5ecc580
fix ,
testaccount90009 Dec 12, 2024
0b8b2c3
Update parser.py
testaccount90009 Dec 12, 2024
582e7aa
Update parser.py
testaccount90009 Dec 12, 2024
b8c8e64
edit steps_to_reproduce locations found
testaccount90009 Dec 12, 2024
dd3cf09
Update parser.py
testaccount90009 Dec 12, 2024
a472fac
fix 500 internal server error bug, add else None to impact for edge case
testaccount90009 Dec 18, 2024
7e5fe44
fix typo
testaccount90009 Dec 18, 2024
7042699
adding cneil suggestion for truncating locations
testaccount90009 Dec 20, 2024
34ab714
implement suggestion from Mend engineers
testaccount90009 Dec 21, 2024
df287f7
fix new line
testaccount90009 Dec 21, 2024
7a935fe
Update parser.py
testaccount90009 Dec 21, 2024
7eda867
Update parser.py
testaccount90009 Dec 21, 2024
21f1bfa
fix indentation
testaccount90009 Dec 21, 2024
d4196e9
fix finding_info
testaccount90009 Dec 21, 2024
5ad78cb
attempt to fix conditional logic for only getting ACTIVE findingInfo …
testaccount90009 Dec 21, 2024
1d0b778
attempt to fix cve and title for new component logic
testaccount90009 Dec 21, 2024
ed9a18c
update unit test for new title check
testaccount90009 Dec 21, 2024
4c1e25c
fix whitespace before comma
testaccount90009 Dec 21, 2024
0670477
add unit test case for legacy title
testaccount90009 Dec 21, 2024
b7adf09
fix duplicate conditional - add into tree_node logic
testaccount90009 Dec 21, 2024
1c833af
add title logic back in
testaccount90009 Dec 21, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 37 additions & 24 deletions dojo/tools/mend/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ def _build_common_output(node, lib_name=None):
description = "No Description Available"
cvss3_score = None
mitigation = "N/A"
locations = []
if "component" in node:
description = (
"**Vulnerability Description**: "
Expand All @@ -56,18 +57,19 @@ def _build_common_output(node, lib_name=None):
+ "**Library Type**: "
+ node["component"].get("libraryType", "")
+ "\n"
+ "**Location Found**: "
+ node["component"].get("path", "")
+ "\n"
+ "**Direct or Transitive Dependency**: "
+ node["component"].get("dependencyType", "")
+ "\n"
)
lib_name = node["component"].get("name")
component_name = node["component"].get("artifactId")
component_version = node["component"].get("version")
impact = node["component"].get("dependencyType")
impact = (
"**Direct or Transitive Vulnerability**: "
+ node["component"].get("dependencyType", "")
+ "\n"
)
cvss3_score = node["vulnerability"].get("score", None)
component_path = node["component"].get("path", None)
if component_path:
locations.append(component_path)
if "topFix" in node:
try:
topfix_node = node.get("topFix")
Expand All @@ -82,7 +84,6 @@ def _build_common_output(node, lib_name=None):
)
except Exception:
logger.exception("Error handling topFix node.")

elif "library" in node:
node.get("project")
description = (
Expand Down Expand Up @@ -136,18 +137,6 @@ def _build_common_output(node, lib_name=None):
)
cwe = 1035 # default OWASP a9 until the report actually has them

# comment out the below for now - working on adding this into the above conditional statements since format can be slightly different
# mitigation = "N/A"
# if "topFix" in node:
# try:
# topfix_node = node.get("topFix")
# mitigation = "**Resolution** ({}): {}\n".format(
# topfix_node.get("date"),
# topfix_node.get("fixResolution"),
# )
# except Exception:
# logger.exception("Error handling topFix node.")

filepaths = []
if "sourceFiles" in node:
try:
Expand All @@ -159,7 +148,6 @@ def _build_common_output(node, lib_name=None):
"Error handling local paths for vulnerability.",
)

locations = []
if "locations" in node:
try:
locations_node = node.get("locations", [])
Expand All @@ -171,8 +159,31 @@ def _build_common_output(node, lib_name=None):
logger.exception(
"Error handling local paths for vulnerability.",
)
if locations:
# Join the locations into a single string
joined_locations = ", ".join(locations)

# If the length exceeds 3999 characters, trim it
if len(joined_locations) > 3999:
# Iterate over the locations and trim until the total length is <= 3999
total_length = 0
truncated_locations = []

for loc in locations:
loc_length = len(loc)
# Check if adding this location will exceed the limit
if total_length + loc_length + len(truncated_locations) <= 3996: # 3999 - len("...") = 3996
truncated_locations.append(loc)
total_length += loc_length
else:
# Stop if adding the next location will exceed the limit
break

# Add ellipsis at the end to indicate truncation
locations = truncated_locations
locations.append("...") # Add the ellipsis to the end of the locations list

filepaths = locations or filepaths
filepaths = filepaths

new_finding = Finding(
title=title,
Expand All @@ -188,7 +199,8 @@ def _build_common_output(node, lib_name=None):
dynamic_finding=True,
cvssv3=cvss3_vector,
cvssv3_score=float(cvss3_score) if cvss3_score is not None else None,
impact=impact,
impact=impact if impact is not None else None,
steps_to_reproduce="**Locations Found**: " + ", ".join(locations) if locations is not None else None,
testaccount90009 marked this conversation as resolved.
Show resolved Hide resolved
)
if cve:
new_finding.unsaved_vulnerability_ids = [cve]
Expand Down Expand Up @@ -238,7 +250,8 @@ def _build_common_output(node, lib_name=None):
tree_node = content["response"]
if tree_node:
for node in tree_node:
findings.append(_build_common_output(node))
if node.get("findingInfo", {}).get("status") == "ACTIVE":
findings.append(_build_common_output(node))

def create_finding_key(f: Finding) -> str:
# """Hashes the finding's description and title to retrieve a key for deduplication."""
Expand Down
8 changes: 5 additions & 3 deletions unittests/tools/test_mend_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ def test_parse_file_with_one_sca_vuln_finding(self):
findings = parser.get_findings(testfile, Test())
self.assertEqual(1, len(findings))
finding = list(findings)[0]
self.assertEqual("D:\\MendRepo\\test-product\\test-project\\test-project-subcomponent\\path\\to\\the\\Java\\commons-codec-1.6_donotuse.jar", finding.file_path)
self.assertEqual("**Locations Found**: D:\\MendRepo\\test-product\\test-project\\test-project-subcomponent\\path\\to\\the\\Java\\commons-codec-1.6_donotuse.jar", finding.steps_to_reproduce)
self.assertEqual("WS-2019-0379 | commons-codec-1.6.jar", finding.title)

def test_parse_file_with_no_vuln_has_no_findings_platform(self):
with open("unittests/scans/mend/mend-sca-platform-api3-no-findings.json", encoding="utf-8") as testfile:
Expand All @@ -60,9 +61,10 @@ def test_parse_file_with_one_vuln_has_one_findings_platform(self):
self.assertEqual("CVE-2024-51744", finding.unsaved_vulnerability_ids[0])
self.assertEqual("CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:L/I:N/A:N", finding.cvssv3)
self.assertEqual(3.1, finding.cvssv3_score)
self.assertEqual("CVE-2024-51744 | github.com/golang-JWT/jwt-v3.2.2+incompatible", finding.title)

def test_parse_file_with_multiple_vuln_has_multiple_finding_platform(self):
with open("unittests/scans/mend/mend-sca-platform-api3-eleven-findings.json", encoding="utf-8") as testfile:
with open("unittests/scans/mend/mend-sca-platform-api3-multiple-findings.json", encoding="utf-8") as testfile:
parser = MendParser()
findings = parser.get_findings(testfile, Test())
self.assertEqual(11, len(findings))
self.assertEqual(5, len(findings))
Loading