Skip to content

Commit 7a7a402

Browse files
Jino-TMaffoochclaude
authored
AWS Inspector 2 Line number bug + other changes (#14616)
* Fixed line number bug and added multiple fields to Package Vulnerability finding type * changed startLine and endLine to keep descriptions consistent with past imports * Add LocationData.dependency() support for package vulnerability findings Populate unsaved_locations with dependency location data from vulnerablePackages, gated behind V3_FEATURE_LOCATIONS. Also fix process_endpoints to extend rather than overwrite unsaved_locations so dependency locations are preserved. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Remove validate_locations call from metadata test The test fixture contains Lambda ARNs with "$LATEST" which produces invalid hostnames for endpoint validation. Endpoint validation is already covered by the other parser tests. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Gate LocationData test assertions behind V3_FEATURE_LOCATIONS Finding.unsaved_locations only exists when V3_FEATURE_LOCATIONS is enabled, so the dependency location assertions must be conditional. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Fix import sorting for ruff linting Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Cody Maffucci <46459665+Maffooch@users.noreply.github.com> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 8d66b07 commit 7a7a402

3 files changed

Lines changed: 3414 additions & 9 deletions

File tree

dojo/tools/aws_inspector2/parser.py

Lines changed: 38 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import contextlib
12
import json
23
from datetime import UTC, datetime
34

@@ -114,6 +115,7 @@ def get_cvss_details(self, finding: Finding, raw_finding: dict) -> Finding:
114115

115116
def get_package_vulnerability(self, finding: Finding, raw_finding: dict) -> Finding:
116117
vulnerability_details = raw_finding.get("packageVulnerabilityDetails", {})
118+
vulnerable_packages = vulnerability_details.get("vulnerablePackages", [])
117119
vulnerability_packages_descriptions = "\n".join(
118120
[
119121
(
@@ -123,14 +125,40 @@ def get_package_vulnerability(self, finding: Finding, raw_finding: dict) -> Find
123125
f"\tfixed version: {vulnerability_package.get('fixedInVersion', 'N/A')}\n"
124126
f"\tremediation: {vulnerability_package.get('remediation', 'N/A')}\n"
125127
)
126-
for vulnerability_package in vulnerability_details.get("vulnerablePackages", [])
128+
for vulnerability_package in vulnerable_packages
127129
],
128130
)
129131
if (vulnerability_id := vulnerability_details.get("vulnerabilityId", None)) is not None:
130132
finding.unsaved_vulnerability_ids = [vulnerability_id]
131133
vulnerability_source = vulnerability_details.get("source")
132134
vulnerability_source_url = vulnerability_details.get("sourceUrl")
133-
# populate fields
135+
# component name/version/file_path from the first vulnerable package
136+
if vulnerable_packages:
137+
finding.component_name = vulnerable_packages[0].get("name")
138+
finding.component_version = vulnerable_packages[0].get("version")
139+
finding.file_path = vulnerable_packages[0].get("filePath")
140+
if settings.V3_FEATURE_LOCATIONS and finding.component_name:
141+
finding.unsaved_locations.append(
142+
LocationData.dependency(
143+
name=finding.component_name,
144+
version=finding.component_version or "",
145+
file_path=finding.file_path or "",
146+
),
147+
)
148+
# reference URLs from the advisory
149+
reference_urls = vulnerability_details.get("referenceUrls", [])
150+
if reference_urls:
151+
finding.references = "\n".join(reference_urls)
152+
# publish date from when the vendor first created the advisory
153+
if vendor_created_at := vulnerability_details.get("vendorCreatedAt"):
154+
with contextlib.suppress(ValueError):
155+
finding.publish_date = date_parser.parse(vendor_created_at).date()
156+
# CVSS v3 base score from the vendor-supplied CVSS entries
157+
for cvss_entry in vulnerability_details.get("cvss", []):
158+
if str(cvss_entry.get("version", "")).startswith("3") and cvss_entry.get("baseScore") is not None:
159+
finding.cvssv3_score = float(cvss_entry["baseScore"])
160+
break
161+
# populate description fields
134162
if vulnerability_source is not None and vulnerability_source_url is not None:
135163
finding.url = vulnerability_source_url
136164
finding.description += (
@@ -149,8 +177,8 @@ def get_code_vulnerability(self, finding: Finding, raw_finding: dict) -> Finding
149177
file_path_info = raw_finding.get("filePath", {})
150178
file_name = file_path_info.get("fileName", "N/A")
151179
file_path = file_path_info.get("filePath", "N/A")
152-
start_line = file_path_info.get("startLine", "N/A")
153-
end_line = file_path_info.get("endLine", "N/A")
180+
start_line = file_path_info.get("startLine", None)
181+
end_line = file_path_info.get("endLine", None)
154182
detector_tags = ", ".join(raw_finding.get("detectorTags", []))
155183
reference_urls = ", ".join(raw_finding.get("referenceUrls", []))
156184
rule_id = raw_finding.get("ruleId", "N/A")
@@ -162,6 +190,10 @@ def get_code_vulnerability(self, finding: Finding, raw_finding: dict) -> Finding
162190
finding.sast_source_file_path = f"{file_path}{file_name}"
163191
finding.line = start_line
164192
finding.sast_source_line = start_line
193+
if start_line is None:
194+
start_line = "N/A"
195+
if end_line is None:
196+
end_line = "N/A"
165197
finding.description += (
166198
"\n**Additional info**\n"
167199
f"CWEs: {string_cwes}\n"
@@ -270,9 +302,9 @@ def process_endpoints(self, finding: Finding, raw_finding: dict) -> Finding:
270302
endpoints.append(Endpoint(host=endpoint_host))
271303
finding.impact = "\n".join(impact)
272304
if settings.V3_FEATURE_LOCATIONS:
273-
finding.unsaved_locations = endpoints
305+
finding.unsaved_locations.extend(endpoints)
274306
else:
275307
# TODO: Delete this after the move to Locations
276-
finding.unsaved_endpoints = endpoints
308+
finding.unsaved_endpoints.extend(endpoints)
277309

278310
return finding

0 commit comments

Comments
 (0)