1
1
2
+ import datetime
2
3
import json
3
4
import logging
4
5
5
6
from dateutil import parser
6
7
from defusedxml import ElementTree
8
+
7
9
from dojo .models import Finding
8
10
from dojo .utils import add_language
9
11
@@ -267,8 +269,8 @@ def getQueryElements(self, query):
267
269
categories = query .get ('categories' )
268
270
return name , cwe , categories , queryId
269
271
270
- # Map checkmarx report state to active/inactive status
271
272
def isActive (self , state ):
273
+ """Map checkmarx report state to active/inactive status"""
272
274
# To verify, Confirmed, Urgent, Proposed not exploitable
273
275
activeStates = ["0" , "2" , "3" , "4" ]
274
276
return state in activeStates
@@ -285,37 +287,100 @@ def get_findings(self, file, test):
285
287
else :
286
288
return self ._get_findings_xml (file , test )
287
289
290
+ def _parse_date (self , value ):
291
+ if isinstance (value , str ):
292
+ return parser .parse (value )
293
+ elif isinstance (value , dict ) and isinstance (value .get ("seconds" ), int ):
294
+ return datetime .datetime .utcfromtimestamp (value .get ("seconds" ))
295
+ else :
296
+ return None
297
+
288
298
def _get_findings_json (self , file , test ):
289
299
""""""
290
300
data = json .load (file )
291
301
findings = []
292
302
results = data .get ("scanResults" , [])
293
303
for result_type in results :
294
- for language in results [result_type ].get ("languages" ):
295
- for query in language .get ("queries" , []):
296
- descriptiondetails = query .get ("description" , "" )
297
- group = ""
298
- title = query .get ("queryName" ).replace ("_" , " " )
299
- if query .get ('groupName' ):
300
- group = query .get ('groupName' ).replace ('_' , ' ' )
301
- for vulnerability in query .get ("vulnerabilities" , []):
304
+ # manage sca part
305
+ if result_type == "sast" :
306
+ for language in results [result_type ].get ("languages" , []):
307
+ for query in language .get ("queries" , []):
308
+ descriptiondetails = query .get ("description" , "" )
309
+ group = ""
310
+ title = query .get ("queryName" ).replace ("_" , " " )
311
+ if query .get ('groupName' ):
312
+ group = query .get ('groupName' ).replace ('_' , ' ' )
313
+ for vulnerability in query .get ("vulnerabilities" , []):
314
+ finding = Finding (
315
+ description = descriptiondetails ,
316
+ title = title ,
317
+ date = self ._parse_date (vulnerability .get ("firstFoundDate" )),
318
+ severity = vulnerability .get ("severity" ).title (),
319
+ active = (vulnerability .get ("status" ) != "Not exploitable" ),
320
+ verified = (vulnerability .get ("status" ) != "To verify" ),
321
+ test = test ,
322
+ cwe = vulnerability .get ("cweId" ),
323
+ static_finding = True ,
324
+ )
325
+ if vulnerability .get ("id" ):
326
+ finding .unique_id_from_tool = vulnerability .get ("id" )
327
+ else :
328
+ finding .unique_id_from_tool = str (vulnerability .get ("similarityId" ))
329
+ # get the last node and set some values
330
+ if vulnerability .get ('nodes' ):
331
+ last_node = vulnerability ['nodes' ][- 1 ]
332
+ finding .file_path = last_node .get ("fileName" )
333
+ finding .line = last_node .get ("line" )
334
+ finding .unsaved_tags = [result_type ]
335
+ findings .append (finding )
336
+ if result_type == "sca" :
337
+ for package in results [result_type ].get ("packages" , []):
338
+ component_name = package .get ("name" ).split ("-" )[- 2 ]
339
+ component_version = package .get ("name" ).split ("-" )[- 1 ]
340
+ for vulnerability in package .get ('vulnerabilities' , []):
341
+ cve = vulnerability .get ('cveId' )
302
342
finding = Finding (
303
- description = descriptiondetails ,
304
- title = title ,
305
- date = parser . parse (vulnerability .get ("firstFoundDate" )),
343
+ title = f' { component_name } : { component_version } | { cve } ' ,
344
+ description = vulnerability . get ( "description" ) ,
345
+ date = self . _parse_date (vulnerability .get ("firstFoundDate" )),
306
346
severity = vulnerability .get ("severity" ).title (),
307
347
active = (vulnerability .get ("status" ) != "Not exploitable" ),
308
- verified = (vulnerability .get ("status" ) != "To verify" ),
348
+ verified = (vulnerability .get ("state" ) != "To verify" ),
349
+ component_name = component_name ,
350
+ component_version = component_version ,
309
351
test = test ,
310
- cwe = vulnerability .get ("cweId" ),
311
- static_finding = (result_type == "sast" ),
312
- unique_id_from_tool = vulnerability .get ("id" ),
352
+ cwe = int (vulnerability .get ("cwe" , 0 )),
353
+ static_finding = True ,
313
354
)
314
- # get the last node and set some values
315
- if vulnerability .get ('nodes' ):
316
- last_node = vulnerability ['nodes' ][- 1 ]
317
- finding .file_path = last_node .get ("fileName" )
318
- finding .line = last_node .get ("line" )
355
+ if vulnerability .get ("cveId" ):
356
+ finding .unsaved_vulnerability_ids = [vulnerability .get ("cveId" )]
357
+ if vulnerability .get ("id" ):
358
+ finding .unique_id_from_tool = vulnerability .get ("id" )
359
+ else :
360
+ finding .unique_id_from_tool = str (vulnerability .get ("similarityId" ))
319
361
finding .unsaved_tags = [result_type ]
320
362
findings .append (finding )
363
+ if result_type == "kics" :
364
+ for kics_type in results [result_type ].get ("results" , []):
365
+ name = kics_type .get ('name' )
366
+ for vulnerability in kics_type .get ('vulnerabilities' , []):
367
+ finding = Finding (
368
+ title = f'{ name } | { vulnerability .get ("issueType" )} ' ,
369
+ description = vulnerability .get ("description" ),
370
+ date = self ._parse_date (vulnerability .get ("firstFoundDate" )),
371
+ severity = vulnerability .get ("severity" ).title (),
372
+ active = (vulnerability .get ("status" ) != "Not exploitable" ),
373
+ verified = (vulnerability .get ("state" ) != "To verify" ),
374
+ file_path = vulnerability .get ("fileName" ),
375
+ line = vulnerability .get ("line" , 0 ),
376
+ severity_justification = vulnerability .get ("actualValue" ),
377
+ test = test ,
378
+ static_finding = True ,
379
+ )
380
+ if vulnerability .get ("id" ):
381
+ finding .unique_id_from_tool = vulnerability .get ("id" )
382
+ else :
383
+ finding .unique_id_from_tool = str (vulnerability .get ("similarityId" ))
384
+ finding .unsaved_tags = [result_type , name ]
385
+ findings .append (finding )
321
386
return findings
0 commit comments