26
26
Each processing step can be turned on or off. At least one step must be run. Default
27
27
is to run both.
28
28
29
- The script get's it CVE and orign lists from CSV files. The CSV filenames are loaded
29
+ The script can get's its CVE and orign lists from CSV files. The CSV filenames are loaded
30
30
from Custom Fields in the Black Duck project. This allows different groups of projects to
31
31
use different remeidation settings. If a CVE remediation status should apply globally
32
32
to all projects, Black Duck's global remediation feature should be used.
33
33
34
+ The script can also get the CSV filenames from the command line arguments.
35
+
34
36
Here is an example of the CSV data for the CVE list:
35
37
36
38
"CVE-2016-1840","IGNORED","Applies only to Apple OS"
81
83
82
84
83
85
def load_remediation_input (remediation_file ):
84
- with open (remediation_file , mode = 'r' ) as infile :
86
+ with open (remediation_file , mode = 'r' , encoding = "utf-8" ) as infile :
85
87
reader = csv .reader (infile )
86
88
return {rows [0 ]:[rows [1 ],rows [2 ]] for rows in reader }
87
89
88
90
def remediation_is_valid (vuln , remediation_data ):
89
91
vulnerability_name = vuln ['vulnerabilityWithRemediation' ]['vulnerabilityName' ]
90
- # remediation_status = vuln['vulnerabilityWithRemediation']['remediationStatus']
91
- # remediation_comment = vuln['vulnerabilityWithRemediation'].get('remediationComment','')
92
+ remediation_status = vuln ['vulnerabilityWithRemediation' ]['remediationStatus' ]
93
+ remediation_comment = vuln ['vulnerabilityWithRemediation' ].get ('remediationComment' ,'' )
94
+
92
95
if vulnerability_name in remediation_data .keys ():
96
+ remediation = remediation_data [vulnerability_name ]
97
+ if (remediation_status == remediation [0 ] and remediation_comment == remediation [1 ]):
98
+ return None
93
99
return remediation_data [vulnerability_name ]
94
100
else :
95
101
return None
@@ -114,9 +120,19 @@ def find_custom_field_value (custom_fields, custom_field_label):
114
120
return None
115
121
return None
116
122
123
+
124
+
125
+ def set_vulnerablity_remediation (hub , vuln , remediation_status , remediation_comment ):
126
+ url = vuln ['_meta' ]['href' ]
127
+ update = {}
128
+ update ['remediationStatus' ] = remediation_status
129
+ update ['comment' ] = remediation_comment
130
+ response = hub .execute_put (url , data = update )
131
+ return response
132
+
117
133
def process_vulnerabilities (hub , vulnerable_components , remediation_data = None , exclusion_data = None ):
118
134
count = 0
119
- print ('"Component Name","Component Version","Component OriginID"," CVE","Reason","Remeidation Status","HTTP response code"' )
135
+ print ('"Component Name","Component Version","CVE","Reason","Remeidation Status","HTTP response code"' )
120
136
121
137
for vuln in vulnerable_components ['items' ]:
122
138
if vuln ['vulnerabilityWithRemediation' ]['remediationStatus' ] == "NEW" :
@@ -125,6 +141,8 @@ def process_vulnerabilities(hub, vulnerable_components, remediation_data=None, e
125
141
126
142
if (exclusion_data ):
127
143
exclusion_action = origin_is_excluded (vuln , exclusion_data )
144
+ else :
145
+ exclusion_action = None
128
146
129
147
# If vuln has both a remdiation action and an origin exclusion action, set remdiation status
130
148
# to the remdiation action. Append the exclusion action's comment to the overall comment.
@@ -137,13 +155,14 @@ def process_vulnerabilities(hub, vulnerable_components, remediation_data=None, e
137
155
reason = 'origin-exclusion'
138
156
139
157
if (remediation_action ):
140
- resp = hub . set_vulnerablity_remediation (vuln , remediation_action [0 ],remediation_action [1 ])
158
+ resp = set_vulnerablity_remediation (hub , vuln , remediation_action [0 ],remediation_action [1 ])
141
159
count += 1
142
- print ('\" {}\" ,\" {}\" ,\" {}\" ,\" {}\" ,\" {}\" ,\" {}\" , \" {} \" ' .
160
+ print ('\" {}\" ,\" {}\" ,\" {}\" ,\" {}\" ,\" {}\" ,\" {}\" ' .
143
161
format (vuln ['componentName' ], vuln ['componentVersionName' ],
144
- vuln ['componentVersionOriginId' ],
145
162
vuln ['vulnerabilityWithRemediation' ]['vulnerabilityName' ],
146
163
reason , remediation_action [0 ], resp .status_code ))
164
+
165
+
147
166
print (f'Remediated { count } vulnerabilities.' )
148
167
149
168
def main (argv = None ): # IGNORE:C0111
@@ -178,7 +197,9 @@ def main(argv=None): # IGNORE:C0111
178
197
parser = ArgumentParser (description = program_license , formatter_class = RawDescriptionHelpFormatter )
179
198
parser .add_argument ("projectname" , help = "Project nname" )
180
199
parser .add_argument ("projectversion" , help = "Project vesrsion" )
181
- parser .add_argument ("--no-process-cve-remediation-list" , dest = 'process_cve_remediation_list' , action = 'store_false' , help = "Disbable processing CVE-Remediation-list" )
200
+ parser .add_argument ("--remediation-list" , dest = "local_remediation_list" , default = None , help = "Filename of cve remediation list csv file" )
201
+ parser .add_argument ("--origin-exclusion-list" , dest = "local_origin_exclusion_list" , default = None , help = "Filename of origin exclusion list csv file" )
202
+ parser .add_argument ("--no-process-cve-remediation-list" , dest = 'process_cve_remediation_list' , action = 'store_false' , help = "Disable processing CVE-Remediation-list" )
182
203
parser .add_argument ("--no-process-origin-exclusion-list" , dest = 'process_origin_exclusion_list' , action = 'store_false' , help = "Disable processing Origin-Exclusion-List" )
183
204
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' )
184
205
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' )
@@ -189,6 +210,8 @@ def main(argv=None): # IGNORE:C0111
189
210
190
211
projectname = args .projectname
191
212
projectversion = args .projectversion
213
+ local_cve_remediation_file = args .local_remediation_list
214
+ local_origin_exclusion_file = args .local_origin_exclusion_list
192
215
process_cve_remediation = args .process_cve_remediation_list
193
216
process_origin_exclulsion = args .process_origin_exclusion_list
194
217
@@ -203,21 +226,32 @@ def main(argv=None): # IGNORE:C0111
203
226
hub = HubInstance ()
204
227
project = hub .get_project_by_name (projectname )
205
228
version = hub .get_project_version_by_name (projectname , projectversion )
206
- custom_fields = hub .get_project_custom_fields (project )
229
+
230
+ custom_fields = hub .get_cf_values (project )
207
231
208
232
if (process_cve_remediation ):
209
- cve_remediation_file = find_custom_field_value (custom_fields , args .cve_remediation_list_custom_field_label )
210
- print (f' Opening: { args .cve_remediation_list_custom_field_label } :{ cve_remediation_file } ' )
233
+ if (local_cve_remediation_file ):
234
+ cve_remediation_file = local_cve_remediation_file
235
+ print (f' Opening CVE remediation file: { cve_remediation_file } ' )
236
+ else :
237
+ cve_remediation_file = find_custom_field_value (custom_fields , args .cve_remediation_list_custom_field_label )
238
+ print (f' Opening: { args .cve_remediation_list_custom_field_label } :{ cve_remediation_file } ' )
239
+
211
240
remediation_data = load_remediation_input (cve_remediation_file )
212
241
else :
213
242
remediation_data = None
214
243
215
244
if (process_origin_exclulsion ):
216
- exclusion_list_file = find_custom_field_value (custom_fields , args .origin_exclusion_list_custom_field_label )
217
- print (f' Opening: { args .origin_exclusion_list_custom_field_label } :{ exclusion_list_file } ' )
245
+ if local_origin_exclusion_file :
246
+ exclusion_list_file = local_origin_exclusion_file
247
+ print (f' Opening origin exclusion list: { exclusion_list_file } ' )
248
+ else :
249
+ exclusion_list_file = find_custom_field_value (custom_fields , args .origin_exclusion_list_custom_field_label )
250
+ print (f' Opening: { args .origin_exclusion_list_custom_field_label } :{ exclusion_list_file } ' )
218
251
exclusion_data = load_remediation_input (exclusion_list_file )
219
252
else :
220
253
exclusion_data = None
254
+
221
255
222
256
# Retrieve the vulnerabiltites for the project version
223
257
vulnerable_components = hub .get_vulnerable_bom_components (version )
0 commit comments