Skip to content

Commit a0d5a03

Browse files
sysdig: support 2025 formats (#12810)
1 parent 0d8cdfa commit a0d5a03

4 files changed

Lines changed: 359 additions & 38 deletions

File tree

dojo/tools/sysdig_reports/parser.py

Lines changed: 89 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -24,58 +24,70 @@ def get_description_for_scan_types(self, scan_type):
2424

2525
def get_findings(self, filename, test):
2626
if filename is None:
27-
return ()
27+
return []
28+
2829
if filename.name.lower().endswith(".csv"):
2930
arr_data = self.load_csv(filename=filename)
3031
return self.parse_csv(arr_data=arr_data, test=test)
32+
3133
if filename.name.lower().endswith(".json"):
3234
scan_data = filename.read()
3335
try:
3436
data = json.loads(str(scan_data, "utf-8"))
3537
except Exception:
3638
data = json.loads(scan_data)
3739

38-
if "data" in data:
39-
return self.parse_json(data=data, test=test)
40+
# Handle both old and new JSON formats
41+
if "data" in data:
42+
# Old format: data is at root level
43+
return self.parse_json(data=data, test=test)
44+
45+
if "panels" in data and len(data["panels"]) > 0 and "data" in data["panels"][0]:
46+
# New 2025 format: data is nested in panels[0]
47+
return self.parse_json(data=data["panels"][0], test=test)
4048

41-
if "result" in data:
42-
msg = "JSON file is not in the expected format, it looks like a Sysdig CLI report."
43-
else:
44-
msg = "JSON file is not in the expected format, expected data element"
49+
if "result" in data:
50+
msg = "JSON file is not in the expected format, it looks like a Sysdig CLI report."
4551
raise ValueError(msg)
46-
return ()
52+
msg = "JSON file is not in the expected format, expected data element"
53+
raise ValueError(msg)
54+
55+
msg = "Expected CSV or JSON file"
56+
raise ValueError(msg)
4757

4858
def parse_json(self, data, test):
4959
vulnerability = data.get("data", None)
5060
if not vulnerability:
5161
return []
5262
findings = []
5363
for item in vulnerability:
54-
imageId = item.get("imageId", "")
55-
imagePullString = item.get("imagePullString", "")
56-
osName = item.get("osName", "")
57-
k8sClusterName = item.get("k8sClusterName", "")
58-
k8sNamespaceName = item.get("k8sNamespaceName", "")
59-
k8sWorkloadType = item.get("k8sWorkloadType", "")
60-
k8sWorkloadName = item.get("k8sWorkloadName", "")
61-
k8sPodContainerName = item.get("k8sPodContainerName", "")
62-
vulnName = item.get("vulnName", "")
63-
vulnSeverity = item.get("vulnSeverity", "")
64-
vulnLink = item.get("vulnLink", "")
65-
vulnCvssVersion = item.get("vulnCvssVersion", "")
66-
vulnCvssScore = item.get("vulnCvssScore", "")
67-
vulnCvssVector = item.get("vulnCvssVector", "")
68-
vulnDisclosureDate = item.get("vulnDisclosureDate", "")
69-
vulnSolutionDate = item.get("vulnSolutionDate", "")
70-
vulnExploitable = item.get("vulnExploitable", "")
71-
vulnFixAvailable = item.get("vulnFixAvailable", "")
72-
vulnFixVersion = item.get("vulnFixVersion", "")
73-
packageName = item.get("packageName", "")
74-
packageType = item.get("packageType", "")
75-
packagePath = item.get("packagePath", "")
76-
packageVersion = item.get("packageVersion", "")
77-
packageSuggestedFix = item.get("packageSuggestedFix", "")
78-
k8sPodCount = item.get("k8sPodCount", "")
64+
# Handle both old and new JSON field names
65+
# Old format uses camelCase, new format uses snake_case with different field names
66+
imageId = item.get("imageId", "") or item.get("container_image_id", "")
67+
imagePullString = item.get("imagePullString", "") or item.get("container_image", "")
68+
osName = item.get("osName", "") or item.get("container_image_distro", "")
69+
k8sClusterName = item.get("k8sClusterName", "") or item.get("kubernetes_cluster_name", "")
70+
k8sNamespaceName = item.get("k8sNamespaceName", "") or item.get("kubernetes_namespace_name", "")
71+
k8sWorkloadType = item.get("k8sWorkloadType", "") or item.get("kubernetes_workload_type", "")
72+
k8sWorkloadName = item.get("k8sWorkloadName", "") or item.get("kubernetes_workload_name", "")
73+
k8sPodContainerName = item.get("k8sPodContainerName", "") or item.get("kubernetes_pod_container_name", "")
74+
vulnName = item.get("vulnName", "") or item.get("vuln_id", "")
75+
vulnSeverity = item.get("vulnSeverity", "") or item.get("vuln_severity", "")
76+
vulnLink = item.get("vulnLink", "") or "" # Not present in new format
77+
vulnCvssVersion = item.get("vulnCvssVersion", "") or item.get("vuln_cvss_version", "")
78+
vulnCvssScore = item.get("vulnCvssScore", "") or item.get("vuln_cvss_score", "")
79+
vulnCvssVector = item.get("vulnCvssVector", "") or item.get("vuln_cvss_vector", "")
80+
vulnDisclosureDate = item.get("vulnDisclosureDate", "") or item.get("vuln_disclosure_date", "")
81+
vulnSolutionDate = item.get("vulnSolutionDate", "") or item.get("vuln_fix_available_date", "")
82+
vulnExploitable = item.get("vulnExploitable", "") or item.get("vuln_has_exploit", "")
83+
vulnFixAvailable = item.get("vulnFixAvailable", "") or item.get("vuln_fix_available", "")
84+
vulnFixVersion = item.get("vulnFixVersion", "") or item.get("vuln_fixed_in_version", "")
85+
packageName = item.get("packageName", "") or item.get("scan_package_name", "")
86+
packageType = item.get("packageType", "") or item.get("scan_package_type", "")
87+
packagePath = item.get("packagePath", "") or item.get("scan_package_path", "")
88+
packageVersion = item.get("packageVersion", "") or item.get("scan_package_version", "")
89+
packageSuggestedFix = item.get("packageSuggestedFix", "") or "" # Not present in new format
90+
k8sPodCount = item.get("k8sPodCount", "") or "" # Not present in new format
7991

8092
description = ""
8193
description += "imageId: " + imageId + "\n"
@@ -266,19 +278,22 @@ def load_csv(self, filename) -> SysdigData:
266278
msg = "Unknown CSV format: CVE ID column found, looks like a SysDig CLI Report"
267279
raise ValueError(msg)
268280

269-
if "vulnerability id" not in reader.fieldnames:
270-
msg = "Unknown CSV format: expected Vulnerability ID column"
281+
# Support both old and new CSV formats
282+
if "vulnerability id" not in reader.fieldnames and "vulnerability name" not in reader.fieldnames:
283+
msg = "Unknown CSV format: expected either 'Vulnerability ID' or 'Vulnerability Name' column"
271284
raise ValueError(msg)
272285

273286
arr_csv_data = []
274287

275288
for row in csvarray:
276289

277290
csv_data_record = SysdigData()
291+
292+
# Handle both old and new CSV formats
278293
if "vulnerability id" in reader.fieldnames:
279-
# Vulnerability Engine Format
294+
# Old format: Vulnerability Engine Format
280295
csv_data_record.vulnerability_id = row.get("vulnerability id", "")
281-
csv_data_record.severity = csv_data_record._map_severity(row.get("severity").upper())
296+
csv_data_record.severity = csv_data_record._map_severity(row.get("severity", "").upper())
282297
csv_data_record.package_name = row.get("package name", "")
283298
csv_data_record.package_version = row.get("package version", "")
284299
csv_data_record.package_type = row.get("package type", "")
@@ -310,6 +325,42 @@ def load_csv(self, filename) -> SysdigData:
310325
csv_data_record.cloud_provider_region = row.get("cloud provider region", "")
311326
csv_data_record.registry_vendor = row.get("registry vendor", "")
312327

313-
arr_csv_data.append(csv_data_record)
328+
elif "vulnerability name" in reader.fieldnames:
329+
# New 2025 format
330+
csv_data_record.vulnerability_id = row.get("vulnerability name", "")
331+
csv_data_record.severity = csv_data_record._map_severity(row.get("vulnerability severity", "").upper())
332+
csv_data_record.package_name = row.get("package name", "")
333+
csv_data_record.package_version = row.get("package version", "")
334+
csv_data_record.package_type = row.get("package type", "")
335+
csv_data_record.package_path = row.get("package path", "")
336+
csv_data_record.image = row.get("image name", "")
337+
csv_data_record.os_name = row.get("os name", "")
338+
csv_data_record.cvss_version = row.get("cvss version", "")
339+
csv_data_record.cvss_score = row.get("cvss score", "")
340+
csv_data_record.cvss_vector = row.get("cvss vector", "")
341+
# Map new 2025 column names to existing fields
342+
csv_data_record.vuln_link = "" # Not present in 2025 format
343+
csv_data_record.vuln_publish_date = row.get("disclosure date", "")
344+
csv_data_record.vuln_fix_date = row.get("fix available date", "")
345+
csv_data_record.vuln_fix_version = row.get("fix version", "")
346+
csv_data_record.public_exploit = row.get("public exploit", "")
347+
csv_data_record.k8s_cluster_name = row.get("kubernetes cluster name", "")
348+
csv_data_record.k8s_namespace_name = row.get("kubernetes namespace name", "")
349+
csv_data_record.k8s_workload_type = row.get("kubernetes workload type", "")
350+
csv_data_record.k8s_workload_name = row.get("kubernetes workload name", "")
351+
csv_data_record.k8s_container_name = row.get("kubernetes container name", "")
352+
csv_data_record.image_id = row.get("image id", "")
353+
csv_data_record.k8s_pod_count = "" # Not present in 2025 format
354+
csv_data_record.package_suggested_fix = "" # Not present in 2025 format
355+
csv_data_record.in_use = row.get("package in use", "").lower() == "true"
356+
csv_data_record.risk_accepted = row.get("risk accepted", "").lower() == "true"
357+
csv_data_record.registry_name = "" # Not present in 2025 format
358+
csv_data_record.registry_image_repository = "" # Not present in 2025 format
359+
csv_data_record.cloud_provider_name = "" # Not present in 2025 format
360+
csv_data_record.cloud_provider_account_id = "" # Not present in 2025 format
361+
csv_data_record.cloud_provider_region = "" # Not present in 2025 format
362+
csv_data_record.registry_vendor = "" # Not present in 2025 format
363+
364+
arr_csv_data.append(csv_data_record)
314365

315366
return arr_csv_data
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
Vulnerability Name,Vulnerability Severity,Package Name,Package Version,Package Type,Package Path,Image Name,OS Name,CVSS Version,CVSS Score,CVSS Vector,Disclosure Date,Fix Available Date,Fix Version,Public Exploit,Kubernetes Cluster Name,Kubernetes Namespace Name,Kubernetes Workload Type,Kubernetes Workload Name,Kubernetes Container Name,Image ID,Package In Use,Risk Accepted,CISA KEV Publish Date,CISA KEV Due Date,CISA KEV Known Ransomware,Fix Available
2+
CVE-2005-2541,Negligible,package name 1,0.0.0.1,OS,/path/path/file.abc,defectdojo/defectdojo-django:latest,debian 12.9,2,10,AV:N/AC:L/Au:N/C:C/I:C/A:C,2005-08-10T04:00:00Z,1970-01-01T00:00:00Z,,false,k8s name 1,defectdojo,Deployment,defectdojo-celery-worker,celery,sha256:a520752f350909c191db45a598a88fcca2fa5db17a340dee6b3d0e36f4122e11,false,false,,,,false
3+
CVE-2005-2541,Negligible,package name 2,0.0.0.2,OS,/path/path/file.abc,defectdojo/defectdojo-django:latest,debian 12.9,2,10,AV:N/AC:L/Au:N/C:C/I:C/A:C,2005-08-10T04:00:00Z,1970-01-01T00:00:00Z,,false,k8s name 2,defectdojo,Deployment,defectdojo-django,uwsgi,sha256:a520752f350909c191db45a598a88fcca2fa5db17a340dee6b3d0e36f4122e11,false,false,,,,false
4+
CVE-2005-2541,Negligible,package name 3,0.0.0.3,OS,/path/path/file.abc,docker.io/bitnami/redis:7.2.5-debian-12-r4,debian 12.6,2,10,AV:N/AC:L/Au:N/C:C/I:C/A:C,2005-08-10T04:00:00Z,1970-01-01T00:00:00Z,,false,k8s name 3,defectdojo,Deployment,defectdojo-redis-master,redis,sha256:a520752f350909c191db45a598a88fcca2fa5db17a340dee6b3d0e36f4122e11,false,false,,,,false
5+
CVE-2025-48379,Critical,package name 4,0.0.0.4,Python,/path/path/path/file.abc,defectdojo/defectdojo-django:latest,debian 12.9,3,9.8,CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H,2025-07-01T17:29:37Z,2025-07-01T09:15:58Z,11.3.0,false,k8s name 4,defectdojo,Deployment,defectdojo-celery-beat,celery,sha256:a520752f350909c191db45a598a88fcca2fa5db17a340dee6b3d0e36f4122e11,true,false,,,,true
6+
CVE-2025-6021,Critical,package name 5,0.0.0.5,OS,/path/path/file.abc,defectdojo/defectdojo-django:latest,debian 12.9,3,9.8,CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H,2025-06-12T13:15:25Z,1970-01-01T00:00:00Z,,false,k8s name 5,defectdojo,Deployment,defectdojo-django,uwsgi,sha256:a520752f350909c191db45a598a88fcca2fa5db17a340dee6b3d0e36f4122e11,false,false,,,,false
7+
CVE-2011-10007,Critical,package name 6,0.0.0.6,OS,/path/path/file.abc,docker.io/bitnami/redis:7.2.5-debian-12-r4,debian 12.6,3,9.8,CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H,2025-06-05T12:15:22Z,1970-01-01T00:00:00Z,0.34-4~deb12u1,false,k8s name 6,defectdojo,Deployment,defectdojo-redis-master,redis,sha256:a520752f350909c191db45a598a88fcca2fa5db17a340dee6b3d0e36f4122e11,false,false,,,,true

0 commit comments

Comments
 (0)