8484
8585def load_remediation_input (remediation_file ):
8686 with open (remediation_file , mode = 'r' , encoding = "utf-8" ) as infile :
87- reader = csv .reader (infile )
87+ dialect = csv .Sniffer ().sniff (infile .read (), delimiters = ';,' )
88+ infile .seek (0 )
89+ reader = csv .reader (infile , dialect )
8890 #return {rows[0]:[rows[1],rows[2]] for rows in reader}
8991 return {rows [0 ]:rows [1 :] for rows in reader }
9092
@@ -95,7 +97,7 @@ def remediation_is_valid(vuln, remediation_data):
9597
9698 if vulnerability_name in remediation_data .keys ():
9799 remediation = remediation_data [vulnerability_name ]
98- if (remediation_status == remediation [0 ] and remediation_comment == remediation [1 ]):
100+ if (remediation_status == remediation [0 ] and remediation_comment == remediation [1 ]. replace ( ' \\ n' , ' \n ' ) ):
99101 return None
100102 return remediation_data [vulnerability_name ]
101103 else :
@@ -127,11 +129,11 @@ def set_vulnerablity_remediation(hub, vuln, remediation_status, remediation_comm
127129 url = vuln ['_meta' ]['href' ]
128130 update = {}
129131 update ['remediationStatus' ] = remediation_status
130- update ['comment' ] = remediation_comment
132+ update ['comment' ] = remediation_comment . replace ( ' \\ n' , ' \n ' )
131133 response = hub .execute_put (url , data = update )
132134 return response
133135
134- def process_vulnerabilities (hub , vulnerable_components , remediation_data = None , exclusion_data = None , dry_run = False ):
136+ def process_vulnerabilities (hub , vulnerable_components , remediation_data = None , exclusion_data = None , dry_run = False , overwrite_existing = False ):
135137
136138 if (dry_run ):
137139 print (f"Opening dry run output file: { dry_run } " )
@@ -142,8 +144,8 @@ def process_vulnerabilities(hub, vulnerable_components, remediation_data=None, e
142144 print ('"Component Name","Component Version","CVE","Reason","Remeidation Status","HTTP response code"' )
143145
144146 for vuln in vulnerable_components ['items' ]:
145- if vuln ['vulnerabilityWithRemediation' ]['remediationStatus' ] == "NEW" :
146- remediation_action = None
147+ if overwrite_existing or vuln ['vulnerabilityWithRemediation' ]['remediationStatus' ] == "NEW" :
148+ remediation_action = None
147149 exclusion_action = None
148150
149151 if (remediation_data ):
@@ -164,8 +166,7 @@ def process_vulnerabilities(hub, vulnerable_components, remediation_data=None, e
164166
165167 if (remediation_action ):
166168 if (dry_run ):
167- remediation_action .insert (0 , vuln ['vulnerabilityWithRemediation' ]['vulnerabilityName' ])
168- csv_writer .writerow (remediation_action )
169+ csv_writer .writerow ([vuln ['vulnerabilityWithRemediation' ]['vulnerabilityName' ]] + remediation_action )
169170 else :
170171 resp = set_vulnerablity_remediation (hub , vuln , remediation_action [0 ],remediation_action [1 ])
171172 count += 1
@@ -218,6 +219,7 @@ def main(argv=None): # IGNORE:C0111
218219 parser .add_argument ("--cve-remediation-list-custom-field-label" , default = 'CVE Remediation List' , help = 'Label of Custom Field on Black Duck that contains remeidation list file name' )
219220 parser .add_argument ("--origin-exclusion-list-custom-field-label" , default = 'Origin Exclusion List' , help = 'Label of Custom Field on Black Duck that containts origin exclusion list file name' )
220221 parser .add_argument ('-V' , '--version' , action = 'version' , version = program_version_message )
222+ parser .add_argument ("--overwrite-existing" , dest = 'overwrite_existing' , action = "store_true" , help = 'By default only NEW vulnerabilities are remediated. Enabling this flag will update all vulnerabilities.' )
221223
222224 # Process arguments
223225 args = parser .parse_args ()
@@ -231,6 +233,7 @@ def main(argv=None): # IGNORE:C0111
231233 #dry_run = args.dry_run
232234 #dry_run_output = args.dry_run_output
233235 dry_run = args .dry_run
236+ overwrite_existing = args .overwrite_existing
234237 print (args .dry_run )
235238
236239 message = f"{ program_version_message } \n \n Project: { projectname } \n Version: { projectversion } \n Process origin exclusion list: { process_origin_exclulsion } \n Process CVE remediation list: { process_cve_remediation } "
@@ -271,16 +274,17 @@ def main(argv=None): # IGNORE:C0111
271274 exclusion_data = None
272275
273276
274- # Retrieve the vulnerabiltites for the project version
275- vulnerable_components = hub .get_vulnerable_bom_components (version )
276277
277- process_vulnerabilities (hub , vulnerable_components , remediation_data , exclusion_data , dry_run )
278-
278+ # Retrieve the vulnerabiltites for the project version. Newer API versions only allow 1000 items at most.
279+ vulnerable_components = hub .get_vulnerable_bom_components (version , 1000 )
280+
281+ process_vulnerabilities (hub , vulnerable_components , remediation_data , exclusion_data , dry_run , overwrite_existing )
282+
279283 return 0
280284 except Exception :
281285 ### handle keyboard interrupt ###
282286 traceback .print_exc ()
283287 return 0
284288
285289if __name__ == "__main__" :
286- sys .exit (main ())
290+ sys .exit (main ())
0 commit comments