1+ import contextlib
12import json
23from 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,32 @@ def get_package_vulnerability(self, finding: Finding, raw_finding: dict) -> Find
123125 f"\t fixed version: { vulnerability_package .get ('fixedInVersion' , 'N/A' )} \n "
124126 f"\t remediation: { 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+ # reference URLs from the advisory
141+ reference_urls = vulnerability_details .get ("referenceUrls" , [])
142+ if reference_urls :
143+ finding .references = "\n " .join (reference_urls )
144+ # publish date from when the vendor first created the advisory
145+ if vendor_created_at := vulnerability_details .get ("vendorCreatedAt" ):
146+ with contextlib .suppress (ValueError ):
147+ finding .publish_date = date_parser .parse (vendor_created_at ).date ()
148+ # CVSS v3 base score from the vendor-supplied CVSS entries
149+ for cvss_entry in vulnerability_details .get ("cvss" , []):
150+ if str (cvss_entry .get ("version" , "" )).startswith ("3" ) and cvss_entry .get ("baseScore" ) is not None :
151+ finding .cvssv3_score = float (cvss_entry ["baseScore" ])
152+ break
153+ # populate description fields
134154 if vulnerability_source is not None and vulnerability_source_url is not None :
135155 finding .url = vulnerability_source_url
136156 finding .description += (
@@ -149,8 +169,8 @@ def get_code_vulnerability(self, finding: Finding, raw_finding: dict) -> Finding
149169 file_path_info = raw_finding .get ("filePath" , {})
150170 file_name = file_path_info .get ("fileName" , "N/A" )
151171 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" )
172+ start_line = file_path_info .get ("startLine" , None )
173+ end_line = file_path_info .get ("endLine" , None )
154174 detector_tags = ", " .join (raw_finding .get ("detectorTags" , []))
155175 reference_urls = ", " .join (raw_finding .get ("referenceUrls" , []))
156176 rule_id = raw_finding .get ("ruleId" , "N/A" )
0 commit comments