84
84
85
85
def load_remediation_input (remediation_file ):
86
86
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 )
88
90
#return {rows[0]:[rows[1],rows[2]] for rows in reader}
89
91
return {rows [0 ]:rows [1 :] for rows in reader }
90
92
@@ -95,7 +97,7 @@ def remediation_is_valid(vuln, remediation_data):
95
97
96
98
if vulnerability_name in remediation_data .keys ():
97
99
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 ' ) ):
99
101
return None
100
102
return remediation_data [vulnerability_name ]
101
103
else :
@@ -127,11 +129,11 @@ def set_vulnerablity_remediation(hub, vuln, remediation_status, remediation_comm
127
129
url = vuln ['_meta' ]['href' ]
128
130
update = {}
129
131
update ['remediationStatus' ] = remediation_status
130
- update ['comment' ] = remediation_comment
132
+ update ['comment' ] = remediation_comment . replace ( ' \\ n' , ' \n ' )
131
133
response = hub .execute_put (url , data = update )
132
134
return response
133
135
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 ):
135
137
136
138
if (dry_run ):
137
139
print (f"Opening dry run output file: { dry_run } " )
@@ -142,8 +144,8 @@ def process_vulnerabilities(hub, vulnerable_components, remediation_data=None, e
142
144
print ('"Component Name","Component Version","CVE","Reason","Remeidation Status","HTTP response code"' )
143
145
144
146
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
147
149
exclusion_action = None
148
150
149
151
if (remediation_data ):
@@ -164,8 +166,7 @@ def process_vulnerabilities(hub, vulnerable_components, remediation_data=None, e
164
166
165
167
if (remediation_action ):
166
168
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 )
169
170
else :
170
171
resp = set_vulnerablity_remediation (hub , vuln , remediation_action [0 ],remediation_action [1 ])
171
172
count += 1
@@ -218,6 +219,7 @@ def main(argv=None): # IGNORE:C0111
218
219
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' )
219
220
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' )
220
221
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.' )
221
223
222
224
# Process arguments
223
225
args = parser .parse_args ()
@@ -231,6 +233,7 @@ def main(argv=None): # IGNORE:C0111
231
233
#dry_run = args.dry_run
232
234
#dry_run_output = args.dry_run_output
233
235
dry_run = args .dry_run
236
+ overwrite_existing = args .overwrite_existing
234
237
print (args .dry_run )
235
238
236
239
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
271
274
exclusion_data = None
272
275
273
276
274
- # Retrieve the vulnerabiltites for the project version
275
- vulnerable_components = hub .get_vulnerable_bom_components (version )
276
277
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
+
279
283
return 0
280
284
except Exception :
281
285
### handle keyboard interrupt ###
282
286
traceback .print_exc ()
283
287
return 0
284
288
285
289
if __name__ == "__main__" :
286
- sys .exit (main ())
290
+ sys .exit (main ())
0 commit comments