devsecops-engine-tools 1.101.1__py3-none-any.whl → 1.102.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of devsecops-engine-tools might be problematic. Click here for more details.
- devsecops_engine_tools/engine_core/src/applications/runner_engine_core.py +19 -4
- devsecops_engine_tools/engine_core/src/domain/model/finding.py +9 -1
- devsecops_engine_tools/engine_core/src/domain/usecases/break_build.py +11 -7
- devsecops_engine_tools/engine_core/src/infrastructure/driven_adapters/azure/azure_devops.py +3 -1
- devsecops_engine_tools/engine_core/src/infrastructure/driven_adapters/defect_dojo/defect_dojo.py +88 -74
- devsecops_engine_tools/engine_core/src/infrastructure/driven_adapters/github/github_actions.py +3 -1
- devsecops_engine_tools/engine_core/src/infrastructure/driven_adapters/printer_pretty_table/printer_pretty_table.py +14 -7
- devsecops_engine_tools/engine_core/src/infrastructure/driven_adapters/runtime_local/runtime_local.py +1 -0
- devsecops_engine_tools/engine_sast/engine_code/src/applications/runner_engine_code.py +17 -1
- devsecops_engine_tools/engine_sast/engine_code/src/domain/model/gateways/tool_gateway.py +24 -11
- devsecops_engine_tools/engine_sast/engine_code/src/domain/usecases/code_scan.py +100 -37
- devsecops_engine_tools/engine_sast/engine_code/src/infrastructure/driven_adapters/bearer/bearer_deserealizator.py +9 -4
- devsecops_engine_tools/engine_sast/engine_code/src/infrastructure/driven_adapters/kiuwan/__init__.py +0 -0
- devsecops_engine_tools/engine_sast/engine_code/src/infrastructure/driven_adapters/kiuwan/kiuwan_deserealizator.py +59 -0
- devsecops_engine_tools/engine_sast/engine_code/src/infrastructure/driven_adapters/kiuwan/kiuwan_tool.py +537 -0
- devsecops_engine_tools/engine_sast/engine_secret/src/infrastructure/driven_adapters/gitleaks/gitleaks_tool.py +1 -1
- devsecops_engine_tools/engine_utilities/azuredevops/models/AzurePredefinedVariables.py +3 -0
- devsecops_engine_tools/engine_utilities/github/models/GithubPredefinedVariables.py +3 -0
- devsecops_engine_tools/version.py +1 -1
- {devsecops_engine_tools-1.101.1.dist-info → devsecops_engine_tools-1.102.0.dist-info}/METADATA +1 -1
- {devsecops_engine_tools-1.101.1.dist-info → devsecops_engine_tools-1.102.0.dist-info}/RECORD +24 -21
- {devsecops_engine_tools-1.101.1.dist-info → devsecops_engine_tools-1.102.0.dist-info}/WHEEL +0 -0
- {devsecops_engine_tools-1.101.1.dist-info → devsecops_engine_tools-1.102.0.dist-info}/entry_points.txt +0 -0
- {devsecops_engine_tools-1.101.1.dist-info → devsecops_engine_tools-1.102.0.dist-info}/top_level.txt +0 -0
|
@@ -35,7 +35,6 @@ from devsecops_engine_tools.engine_utilities.utils.logger_info import MyLogger
|
|
|
35
35
|
from devsecops_engine_tools.engine_utilities import settings
|
|
36
36
|
from devsecops_engine_tools.version import version
|
|
37
37
|
|
|
38
|
-
|
|
39
38
|
logger = MyLogger.__call__(**settings.SETTING_LOGGER).get_logger()
|
|
40
39
|
|
|
41
40
|
|
|
@@ -109,6 +108,7 @@ def get_inputs_from_cli(args):
|
|
|
109
108
|
"trivy",
|
|
110
109
|
"xray",
|
|
111
110
|
"dependency_check",
|
|
111
|
+
"kiuwan",
|
|
112
112
|
],
|
|
113
113
|
type=str,
|
|
114
114
|
required=False,
|
|
@@ -199,6 +199,12 @@ def get_inputs_from_cli(args):
|
|
|
199
199
|
required=False,
|
|
200
200
|
help="Token for downloading external checks from engine_iac or engine_secret if is necessary. Ej: github_token:token, github_app:private_key, ssh:privatekey:pass",
|
|
201
201
|
)
|
|
202
|
+
parser.add_argument(
|
|
203
|
+
"--token_engine_code",
|
|
204
|
+
type=str,
|
|
205
|
+
required=False,
|
|
206
|
+
help="Password for connecting with the kiuwan platform. In order to get a kiuwan pass, go to the platform and select the pass of the account selected for the engine."
|
|
207
|
+
)
|
|
202
208
|
parser.add_argument(
|
|
203
209
|
"--xray_mode",
|
|
204
210
|
choices=["scan", "audit","build-scan"],
|
|
@@ -226,13 +232,20 @@ def get_inputs_from_cli(args):
|
|
|
226
232
|
default="false",
|
|
227
233
|
help="Enable or disable context creation. Applies to engine_iac, engine_container and engine_dependencies. Default is false."
|
|
228
234
|
)
|
|
235
|
+
parser.add_argument(
|
|
236
|
+
"-repo",
|
|
237
|
+
"--repo_name",
|
|
238
|
+
type=str,
|
|
239
|
+
required=False,
|
|
240
|
+
help="Repository name, used when the repository name should not be taken from environment variable. Apply to kiuwan"
|
|
241
|
+
)
|
|
229
242
|
|
|
230
243
|
TOOLS = {
|
|
231
244
|
"engine_iac": ["checkov", "kics", "kubescape"],
|
|
232
245
|
"engine_secret": ["trufflehog", "gitleaks"],
|
|
233
246
|
"engine_container": ["prisma", "trivy"],
|
|
234
247
|
"engine_dependencies": ["xray", "dependency_check", "trivy"],
|
|
235
|
-
"engine_code": ["bearer"],
|
|
248
|
+
"engine_code": ["bearer", "kiuwan"],
|
|
236
249
|
"engine_dast": ["nuclei"],
|
|
237
250
|
"engine_risk": None,
|
|
238
251
|
}
|
|
@@ -264,10 +277,12 @@ def get_inputs_from_cli(args):
|
|
|
264
277
|
"token_engine_container": args.token_engine_container,
|
|
265
278
|
"token_engine_dependencies": args.token_engine_dependencies,
|
|
266
279
|
"token_external_checks": args.token_external_checks,
|
|
280
|
+
"token_engine_code": args.token_engine_code,
|
|
267
281
|
"xray_mode": args.xray_mode,
|
|
268
282
|
"image_to_scan": args.image_to_scan,
|
|
269
283
|
"dast_file_path": args.dast_file_path,
|
|
270
|
-
"context": args.context
|
|
284
|
+
"context": args.context,
|
|
285
|
+
"repo_name": args.repo_name
|
|
271
286
|
}
|
|
272
287
|
|
|
273
288
|
|
|
@@ -317,4 +332,4 @@ def application_core():
|
|
|
317
332
|
|
|
318
333
|
|
|
319
334
|
if __name__ == "__main__":
|
|
320
|
-
application_core()
|
|
335
|
+
application_core()
|
|
@@ -17,4 +17,12 @@ class Finding:
|
|
|
17
17
|
module: str
|
|
18
18
|
category: Category
|
|
19
19
|
requirements: str
|
|
20
|
-
tool: str
|
|
20
|
+
tool: str
|
|
21
|
+
|
|
22
|
+
@dataclass
|
|
23
|
+
class EngineCodeFinding(Finding):
|
|
24
|
+
analysis_url: str
|
|
25
|
+
analysis_code: str
|
|
26
|
+
label: str
|
|
27
|
+
application_business_value: str
|
|
28
|
+
defect_type: str
|
|
@@ -50,16 +50,16 @@ class BreakBuild:
|
|
|
50
50
|
|
|
51
51
|
findings_excluded, findings_without_exclusions = self._filter_findings(findings_list, exclusions)
|
|
52
52
|
scan_result["findings_excluded"] = [self._map_finding_excluded(item) for item in findings_excluded]
|
|
53
|
-
|
|
53
|
+
|
|
54
54
|
vulnerabilities = [v for v in findings_without_exclusions if v.category == Category.VULNERABILITY]
|
|
55
55
|
compliances = [v for v in findings_without_exclusions if v.category == Category.COMPLIANCE]
|
|
56
56
|
|
|
57
57
|
vulnerability_counts = self._count_severities(vulnerabilities)
|
|
58
58
|
compliance_counts = self._count_severities(compliances)
|
|
59
59
|
|
|
60
|
-
self._handle_vulnerabilities(vulnerability_counts, vulnerabilities, threshold, warning_release, scan_result)
|
|
60
|
+
self._handle_vulnerabilities(vulnerability_counts, vulnerabilities, threshold, warning_release, scan_result, args)
|
|
61
61
|
self._handle_cve_policy(vulnerabilities, threshold)
|
|
62
|
-
self._handle_compliances(compliance_counts, compliances, threshold, warning_release, scan_result)
|
|
62
|
+
self._handle_compliances(compliance_counts, compliances, threshold, warning_release, scan_result, args)
|
|
63
63
|
self._handle_exclusions(findings_excluded, exclusions)
|
|
64
64
|
else:
|
|
65
65
|
print(devops_platform_gateway.message("succeeded", "There are no findings"))
|
|
@@ -109,7 +109,7 @@ class BreakBuild:
|
|
|
109
109
|
return {
|
|
110
110
|
"id": item.id,
|
|
111
111
|
"severity": item.severity,
|
|
112
|
-
"category": item.category
|
|
112
|
+
"category": item.category,
|
|
113
113
|
}
|
|
114
114
|
|
|
115
115
|
def _count_severities(self, findings_list):
|
|
@@ -125,7 +125,7 @@ class BreakBuild:
|
|
|
125
125
|
counts[severity] += 1
|
|
126
126
|
return counts
|
|
127
127
|
|
|
128
|
-
def _handle_vulnerabilities(self, counts, vulnerabilities_list, threshold, warning_release, scan_result):
|
|
128
|
+
def _handle_vulnerabilities(self, counts, vulnerabilities_list, threshold, warning_release, scan_result, args):
|
|
129
129
|
devops_platform_gateway = self.devops_platform_gateway
|
|
130
130
|
printer_table_gateway = self.printer_table_gateway
|
|
131
131
|
print()
|
|
@@ -142,6 +142,8 @@ class BreakBuild:
|
|
|
142
142
|
counts["low"] >= threshold.vulnerability.low):
|
|
143
143
|
|
|
144
144
|
print("Below are all vulnerabilities detected.")
|
|
145
|
+
if vulnerabilities_list and args.get("tool", None) == "kiuwan":
|
|
146
|
+
print(f"Analysis url: {vulnerabilities_list[0].analysis_url}")
|
|
145
147
|
printer_table_gateway.print_table_findings(vulnerabilities_list)
|
|
146
148
|
print(devops_platform_gateway.message(
|
|
147
149
|
"error",
|
|
@@ -194,13 +196,15 @@ class BreakBuild:
|
|
|
194
196
|
))
|
|
195
197
|
print(devops_platform_gateway.result_pipeline("failed"))
|
|
196
198
|
|
|
197
|
-
def _handle_compliances(self, counts, compliances_list, threshold, warning_release, scan_result):
|
|
199
|
+
def _handle_compliances(self, counts, compliances_list, threshold, warning_release, scan_result, args):
|
|
198
200
|
devops_platform_gateway = self.devops_platform_gateway
|
|
199
201
|
printer_table_gateway = self.printer_table_gateway
|
|
200
202
|
print()
|
|
201
203
|
|
|
202
204
|
if compliances_list:
|
|
203
205
|
print("Below are all compliances issues detected.")
|
|
206
|
+
if compliances_list and args.get("tool", None) == "kiuwan":
|
|
207
|
+
print(f"Analysis url: {compliances_list[0].analysis_url}")
|
|
204
208
|
printer_table_gateway.print_table_findings(compliances_list)
|
|
205
209
|
status = "succeeded"
|
|
206
210
|
if counts["critical"] >= threshold.compliance.critical:
|
|
@@ -251,4 +255,4 @@ class BreakBuild:
|
|
|
251
255
|
printer_table_gateway.print_table_exclusions(exclusions_list)
|
|
252
256
|
|
|
253
257
|
for reason, total in Counter(x["reason"] for x in exclusions_list).items():
|
|
254
|
-
print("{0} findings count: {1}".format(reason, total))
|
|
258
|
+
print("{0} findings count: {1}".format(reason, total))
|
|
@@ -8,6 +8,7 @@ from devsecops_engine_tools.engine_utilities.azuredevops.models.AzurePredefinedV
|
|
|
8
8
|
ReleaseVariables,
|
|
9
9
|
AgentVariables,
|
|
10
10
|
VMVariables,
|
|
11
|
+
ApplicationVariables,
|
|
11
12
|
)
|
|
12
13
|
from devsecops_engine_tools.engine_utilities.azuredevops.infrastructure.azure_devops_api import (
|
|
13
14
|
AzureDevopsApi,
|
|
@@ -117,8 +118,9 @@ class AzureDevops(DevopsPlatformGateway):
|
|
|
117
118
|
"vm_product_type_name": VMVariables.Vm_Product_Type_Name,
|
|
118
119
|
"vm_product_name": VMVariables.Vm_Product_Name,
|
|
119
120
|
"vm_product_description": VMVariables.Vm_Product_Description,
|
|
121
|
+
"build_task": ApplicationVariables.Application_Build_Task,
|
|
120
122
|
}
|
|
121
123
|
try:
|
|
122
124
|
return variable_map.get(variable).value()
|
|
123
125
|
except ValueError:
|
|
124
|
-
return None
|
|
126
|
+
return None
|
devsecops_engine_tools/engine_core/src/infrastructure/driven_adapters/defect_dojo/defect_dojo.py
CHANGED
|
@@ -40,7 +40,6 @@ import concurrent.futures
|
|
|
40
40
|
|
|
41
41
|
logger = MyLogger.__call__(**settings.SETTING_LOGGER).get_logger()
|
|
42
42
|
|
|
43
|
-
|
|
44
43
|
@dataclass
|
|
45
44
|
class DefectDojoPlatform(VulnerabilityManagementGateway):
|
|
46
45
|
|
|
@@ -70,6 +69,7 @@ class DefectDojoPlatform(VulnerabilityManagementGateway):
|
|
|
70
69
|
"SONARQUBE": "SonarQube API Import",
|
|
71
70
|
"GITLEAKS": "Gitleaks Scan",
|
|
72
71
|
"NUCLEI": "Nuclei Scan",
|
|
72
|
+
"KIUWAN": "Kiuwan Scan"
|
|
73
73
|
}
|
|
74
74
|
|
|
75
75
|
def send_vulnerability_management(
|
|
@@ -88,6 +88,7 @@ class DefectDojoPlatform(VulnerabilityManagementGateway):
|
|
|
88
88
|
else vulnerability_management.secret_tool["token_cmdb"]
|
|
89
89
|
)
|
|
90
90
|
|
|
91
|
+
tags = []
|
|
91
92
|
if any(
|
|
92
93
|
branch in str(vulnerability_management.branch_tag)
|
|
93
94
|
for branch in vulnerability_management.config_tool[
|
|
@@ -95,12 +96,14 @@ class DefectDojoPlatform(VulnerabilityManagementGateway):
|
|
|
95
96
|
]["BRANCH_FILTER"]
|
|
96
97
|
) or (vulnerability_management.dict_args["module"] == "engine_secret"):
|
|
97
98
|
tags = [vulnerability_management.dict_args["module"]]
|
|
99
|
+
|
|
98
100
|
if vulnerability_management.dict_args["module"] == "engine_iac":
|
|
99
101
|
tags = [
|
|
100
102
|
f"{vulnerability_management.dict_args['module']}_{'_'.join(vulnerability_management.dict_args['platform'])}"
|
|
101
103
|
]
|
|
102
104
|
if vulnerability_management.input_core.scope_service != vulnerability_management.input_core.scope_pipeline:
|
|
103
105
|
tags.append(vulnerability_management.input_core.scope_service.replace(f"{vulnerability_management.input_core.scope_pipeline}_", ""))
|
|
106
|
+
|
|
104
107
|
if (
|
|
105
108
|
vulnerability_management.dict_args["module"] == "engine_container"
|
|
106
109
|
and sum(
|
|
@@ -122,47 +125,46 @@ class DefectDojoPlatform(VulnerabilityManagementGateway):
|
|
|
122
125
|
f"{vulnerability_management.dict_args['module']}_{tag_suffix}"
|
|
123
126
|
]
|
|
124
127
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
request = self._build_request_importscan(
|
|
130
|
-
vulnerability_management,
|
|
131
|
-
token_cmdb,
|
|
132
|
-
token_dd,
|
|
133
|
-
tags,
|
|
134
|
-
use_cmdb,
|
|
135
|
-
)
|
|
128
|
+
use_cmdb = vulnerability_management.config_tool[
|
|
129
|
+
"VULNERABILITY_MANAGER"
|
|
130
|
+
]["DEFECT_DOJO"]["CMDB"]["USE_CMDB"]
|
|
136
131
|
|
|
137
|
-
|
|
138
|
-
|
|
132
|
+
request = self._build_request_importscan(
|
|
133
|
+
vulnerability_management,
|
|
134
|
+
token_cmdb,
|
|
135
|
+
token_dd,
|
|
136
|
+
tags,
|
|
137
|
+
use_cmdb,
|
|
138
|
+
)
|
|
139
139
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
140
|
+
def request_func():
|
|
141
|
+
return DefectDojo.send_import_scan(request)
|
|
142
|
+
|
|
143
|
+
response = Utils().retries_requests(
|
|
144
|
+
request_func,
|
|
145
|
+
vulnerability_management.config_tool["VULNERABILITY_MANAGER"][
|
|
146
|
+
"DEFECT_DOJO"
|
|
147
|
+
]["MAX_RETRIES_QUERY"],
|
|
148
|
+
retry_delay=5,
|
|
149
|
+
)
|
|
147
150
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
url_parts = response.url.split("//")
|
|
154
|
-
test_string = "//".join([url_parts[0] + "/", url_parts[1]])
|
|
155
|
-
print(
|
|
156
|
-
"Report sent to vulnerability management: ",
|
|
157
|
-
f"{test_string}?tags={vulnerability_management.dict_args['module']}",
|
|
151
|
+
if hasattr(response, "url"):
|
|
152
|
+
if vulnerability_management.config_tool.get("VULNERABILITY_MANAGER").get("DEFECT_DOJO").get("PRINT_DOMAIN"):
|
|
153
|
+
response.url = response.url.replace(
|
|
154
|
+
vulnerability_management.config_tool["VULNERABILITY_MANAGER"]["DEFECT_DOJO"]["HOST_DEFECT_DOJO"],
|
|
155
|
+
vulnerability_management.config_tool["VULNERABILITY_MANAGER"]["DEFECT_DOJO"]["PRINT_DOMAIN"]
|
|
158
156
|
)
|
|
159
|
-
|
|
160
|
-
|
|
157
|
+
url_parts = response.url.split("//")
|
|
158
|
+
test_string = "//".join([url_parts[0] + "/", url_parts[1]])
|
|
159
|
+
print(
|
|
160
|
+
"Report sent to vulnerability management: ",
|
|
161
|
+
f"{test_string}?tags={vulnerability_management.dict_args['module']}",
|
|
162
|
+
)
|
|
163
|
+
else:
|
|
164
|
+
raise ExceptionVulnerabilityManagement(response)
|
|
161
165
|
except Exception as ex:
|
|
162
166
|
raise ExceptionVulnerabilityManagement(
|
|
163
|
-
"Error sending report to vulnerability management with the following error: {
|
|
164
|
-
ex
|
|
165
|
-
)
|
|
167
|
+
f"Error sending report to vulnerability management with the following error: {str(ex)}"
|
|
166
168
|
)
|
|
167
169
|
|
|
168
170
|
def get_product_type_pipeline(self, service, dict_args, secret_tool, config_tool):
|
|
@@ -198,10 +200,11 @@ class DefectDojoPlatform(VulnerabilityManagementGateway):
|
|
|
198
200
|
|
|
199
201
|
except Exception as ex:
|
|
200
202
|
raise ExceptionVulnerabilityManagement(
|
|
201
|
-
"Error getting product type with the following error: {
|
|
203
|
+
f"Error getting product type with the following error: {str(ex)}"
|
|
202
204
|
)
|
|
203
205
|
|
|
204
206
|
def get_findings_excepted(self, service, dict_args, secret_tool, config_tool):
|
|
207
|
+
logger.info("Starting get_findings_excepted")
|
|
205
208
|
try:
|
|
206
209
|
session_manager = self._get_session_manager(
|
|
207
210
|
dict_args, secret_tool, config_tool
|
|
@@ -213,7 +216,6 @@ class DefectDojoPlatform(VulnerabilityManagementGateway):
|
|
|
213
216
|
dd_max_retries = config_tool["VULNERABILITY_MANAGER"]["DEFECT_DOJO"][
|
|
214
217
|
"MAX_RETRIES_QUERY"
|
|
215
218
|
]
|
|
216
|
-
|
|
217
219
|
tool = dict_args["module"]
|
|
218
220
|
|
|
219
221
|
risk_accepted_query_params = {
|
|
@@ -302,18 +304,18 @@ class DefectDojoPlatform(VulnerabilityManagementGateway):
|
|
|
302
304
|
white_list=white_list,
|
|
303
305
|
)
|
|
304
306
|
|
|
305
|
-
|
|
307
|
+
result = (
|
|
306
308
|
list(exclusions_risk_accepted)
|
|
307
309
|
+ list(exclusions_false_positive)
|
|
308
310
|
+ list(exclusions_out_of_scope)
|
|
309
311
|
+ list(exclusions_transfer_finding)
|
|
310
312
|
+ list(exclusions_white_list)
|
|
311
313
|
)
|
|
314
|
+
return result
|
|
315
|
+
|
|
312
316
|
except Exception as ex:
|
|
313
317
|
raise ExceptionFindingsExcepted(
|
|
314
|
-
"Error getting excepted findings with the following error: {
|
|
315
|
-
ex
|
|
316
|
-
)
|
|
318
|
+
f"Error getting excepted findings with the following error: {str(ex)}"
|
|
317
319
|
)
|
|
318
320
|
|
|
319
321
|
def get_all(self, service, dict_args, secret_tool, config_tool):
|
|
@@ -368,7 +370,7 @@ class DefectDojoPlatform(VulnerabilityManagementGateway):
|
|
|
368
370
|
|
|
369
371
|
except Exception as ex:
|
|
370
372
|
raise ExceptionGettingFindings(
|
|
371
|
-
"Error getting all findings with the following error: {
|
|
373
|
+
f"Error getting all findings with the following error: {str(ex)}"
|
|
372
374
|
)
|
|
373
375
|
|
|
374
376
|
def get_active_engagements(
|
|
@@ -411,7 +413,7 @@ class DefectDojoPlatform(VulnerabilityManagementGateway):
|
|
|
411
413
|
|
|
412
414
|
except Exception as ex:
|
|
413
415
|
raise ExceptionGettingEngagements(
|
|
414
|
-
"Error getting engagements with the following error: {
|
|
416
|
+
f"Error getting engagements with the following error: {str(ex)}"
|
|
415
417
|
)
|
|
416
418
|
|
|
417
419
|
def send_sbom_components(
|
|
@@ -429,7 +431,7 @@ class DefectDojoPlatform(VulnerabilityManagementGateway):
|
|
|
429
431
|
)
|
|
430
432
|
|
|
431
433
|
with concurrent.futures.ThreadPoolExecutor(max_workers=25) as executor:
|
|
432
|
-
|
|
434
|
+
futures = [
|
|
433
435
|
executor.submit(
|
|
434
436
|
self._process_component,
|
|
435
437
|
sbom_component,
|
|
@@ -438,12 +440,11 @@ class DefectDojoPlatform(VulnerabilityManagementGateway):
|
|
|
438
440
|
)
|
|
439
441
|
for sbom_component in sbom_components
|
|
440
442
|
]
|
|
443
|
+
concurrent.futures.wait(futures)
|
|
441
444
|
|
|
442
445
|
except Exception as ex:
|
|
443
446
|
raise ExceptionVulnerabilityManagement(
|
|
444
|
-
"Error sending components sbom to vulnerability management with the following error: {
|
|
445
|
-
ex
|
|
446
|
-
)
|
|
447
|
+
f"Error sending components sbom to vulnerability management with the following error: {str(ex)}"
|
|
447
448
|
)
|
|
448
449
|
|
|
449
450
|
def get_black_list(self, dict_args, secret_tool, config_tool):
|
|
@@ -462,10 +463,12 @@ class DefectDojoPlatform(VulnerabilityManagementGateway):
|
|
|
462
463
|
},
|
|
463
464
|
)
|
|
464
465
|
|
|
465
|
-
|
|
466
|
+
result = [entry.unique_id_from_tool for entry in exclusions_black_list]
|
|
467
|
+
return result
|
|
468
|
+
|
|
466
469
|
except Exception as ex:
|
|
467
470
|
raise ExceptionVulnerabilityManagement(
|
|
468
|
-
"Error getting black list with the following error: {
|
|
471
|
+
f"Error getting black list with the following error: {str(ex)}"
|
|
469
472
|
)
|
|
470
473
|
|
|
471
474
|
def _build_request_importscan(
|
|
@@ -478,6 +481,7 @@ class DefectDojoPlatform(VulnerabilityManagementGateway):
|
|
|
478
481
|
):
|
|
479
482
|
tool_scm_conf_mapping = vulnerability_management.config_tool["VULNERABILITY_MANAGER"]["DEFECT_DOJO"]["TOOL_SCM_MAPPING"]
|
|
480
483
|
tool_sonar_conf_mapping = vulnerability_management.config_tool["VULNERABILITY_MANAGER"]["DEFECT_DOJO"]["TOOL_SONAR_MAPPING"]
|
|
484
|
+
|
|
481
485
|
common_fields = {
|
|
482
486
|
"scan_type": self.scan_type_mapping[vulnerability_management.scan_type],
|
|
483
487
|
"file": vulnerability_management.input_core.path_file_results,
|
|
@@ -532,7 +536,7 @@ class DefectDojoPlatform(VulnerabilityManagementGateway):
|
|
|
532
536
|
cmdb_mapping = vulnerability_management.config_tool[
|
|
533
537
|
"VULNERABILITY_MANAGER"
|
|
534
538
|
]["DEFECT_DOJO"]["CMDB"]["CMDB_MAPPING"]
|
|
535
|
-
|
|
539
|
+
request = Connect.cmdb(
|
|
536
540
|
generate_auth_cmdb=vulnerability_management.config_tool["VULNERABILITY_MANAGER"]["DEFECT_DOJO"]["CMDB"]["GENERATE_AUTH_CMDB"],
|
|
537
541
|
auth_cmdb_request_response=vulnerability_management.config_tool[
|
|
538
542
|
"VULNERABILITY_MANAGER"
|
|
@@ -556,7 +560,7 @@ class DefectDojoPlatform(VulnerabilityManagementGateway):
|
|
|
556
560
|
**common_fields,
|
|
557
561
|
)
|
|
558
562
|
else:
|
|
559
|
-
request
|
|
563
|
+
request = ImportScanSerializer().load(
|
|
560
564
|
{
|
|
561
565
|
"product_type_name": vulnerability_management.vm_product_type_name,
|
|
562
566
|
"product_name": vulnerability_management.vm_product_name,
|
|
@@ -565,7 +569,8 @@ class DefectDojoPlatform(VulnerabilityManagementGateway):
|
|
|
565
569
|
**common_fields,
|
|
566
570
|
}
|
|
567
571
|
)
|
|
568
|
-
|
|
572
|
+
|
|
573
|
+
return request
|
|
569
574
|
|
|
570
575
|
def _process_component(self, component_sbom, session_manager, engagement):
|
|
571
576
|
request = {
|
|
@@ -586,10 +591,11 @@ class DefectDojoPlatform(VulnerabilityManagementGateway):
|
|
|
586
591
|
token_dd = dict_args.get("token_vulnerability_management") or secret_tool.get(
|
|
587
592
|
"token_defect_dojo"
|
|
588
593
|
)
|
|
589
|
-
|
|
594
|
+
session_manager = SessionManager(
|
|
590
595
|
token_dd,
|
|
591
596
|
config_tool["VULNERABILITY_MANAGER"]["DEFECT_DOJO"]["HOST_DEFECT_DOJO"],
|
|
592
597
|
)
|
|
598
|
+
return session_manager
|
|
593
599
|
|
|
594
600
|
def _get_report_exclusions(self, total_findings, date_fn, host_dd, **kwargs):
|
|
595
601
|
exclusions = []
|
|
@@ -665,8 +671,8 @@ class DefectDojoPlatform(VulnerabilityManagementGateway):
|
|
|
665
671
|
findings = self._get_findings(
|
|
666
672
|
session_manager, service, max_retries, query_params
|
|
667
673
|
)
|
|
668
|
-
|
|
669
|
-
|
|
674
|
+
|
|
675
|
+
result = map(
|
|
670
676
|
partial(
|
|
671
677
|
self._create_exclusion,
|
|
672
678
|
date_fn=date_fn,
|
|
@@ -676,6 +682,7 @@ class DefectDojoPlatform(VulnerabilityManagementGateway):
|
|
|
676
682
|
),
|
|
677
683
|
findings,
|
|
678
684
|
)
|
|
685
|
+
return result
|
|
679
686
|
|
|
680
687
|
def _get_findings(self, session_manager, service, max_retries, query_params):
|
|
681
688
|
def request_func():
|
|
@@ -683,7 +690,8 @@ class DefectDojoPlatform(VulnerabilityManagementGateway):
|
|
|
683
690
|
session=session_manager, service=service, **query_params
|
|
684
691
|
).results
|
|
685
692
|
|
|
686
|
-
|
|
693
|
+
findings = Utils().retries_requests(request_func, max_retries, retry_delay=5)
|
|
694
|
+
return findings
|
|
687
695
|
|
|
688
696
|
def _get_finding_exclusion(self, session_manager, max_retries, query_params):
|
|
689
697
|
def request_func():
|
|
@@ -691,31 +699,33 @@ class DefectDojoPlatform(VulnerabilityManagementGateway):
|
|
|
691
699
|
session=session_manager, **query_params
|
|
692
700
|
).results
|
|
693
701
|
|
|
694
|
-
|
|
702
|
+
exclusions = Utils().retries_requests(request_func, max_retries, retry_delay=5)
|
|
703
|
+
return exclusions
|
|
695
704
|
|
|
696
705
|
def _date_reason_based(self, finding, date_fn, reason, tool, **kwargs):
|
|
697
706
|
def get_vuln_id(finding, tool):
|
|
698
707
|
if tool == "engine_risk":
|
|
699
|
-
|
|
708
|
+
vuln_id = (
|
|
700
709
|
finding.id[0]["vulnerability_id"]
|
|
701
710
|
if finding.id
|
|
702
711
|
else finding.vuln_id_from_tool
|
|
703
712
|
)
|
|
704
713
|
else:
|
|
705
|
-
|
|
714
|
+
vuln_id = (
|
|
706
715
|
finding.vulnerability_ids[0]["vulnerability_id"]
|
|
707
716
|
if finding.vulnerability_ids
|
|
708
717
|
else finding.vuln_id_from_tool
|
|
709
718
|
)
|
|
719
|
+
return vuln_id
|
|
710
720
|
|
|
711
721
|
def get_dates_from_whitelist(vuln_id, white_list):
|
|
712
722
|
matching_finding = next(
|
|
713
723
|
filter(lambda x: x.unique_id_from_tool == vuln_id, white_list), None
|
|
714
724
|
)
|
|
715
725
|
if matching_finding:
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
726
|
+
create_date = date_fn(matching_finding.create_date)
|
|
727
|
+
expiration_date = date_fn(matching_finding.expiration_date)
|
|
728
|
+
return create_date, expiration_date
|
|
719
729
|
return date_fn(None), date_fn(None)
|
|
720
730
|
|
|
721
731
|
reason_to_dates = {
|
|
@@ -749,8 +759,7 @@ class DefectDojoPlatform(VulnerabilityManagementGateway):
|
|
|
749
759
|
create_date, expired_date = self._date_reason_based(
|
|
750
760
|
finding, date_fn, reason, tool, **kwargs
|
|
751
761
|
)
|
|
752
|
-
|
|
753
|
-
return Exclusions(
|
|
762
|
+
exclusion = Exclusions(
|
|
754
763
|
id=(
|
|
755
764
|
finding.vuln_id_from_tool
|
|
756
765
|
if finding.vuln_id_from_tool
|
|
@@ -766,6 +775,7 @@ class DefectDojoPlatform(VulnerabilityManagementGateway):
|
|
|
766
775
|
severity=finding.severity.lower(),
|
|
767
776
|
reason=reason,
|
|
768
777
|
)
|
|
778
|
+
return exclusion
|
|
769
779
|
|
|
770
780
|
def _create_report_exclusion(
|
|
771
781
|
self, finding, date_fn, tool, reason, host_dd, **kwargs
|
|
@@ -773,8 +783,7 @@ class DefectDojoPlatform(VulnerabilityManagementGateway):
|
|
|
773
783
|
create_date, expired_date = self._date_reason_based(
|
|
774
784
|
finding, date_fn, reason, tool, **kwargs
|
|
775
785
|
)
|
|
776
|
-
|
|
777
|
-
return Exclusions(
|
|
786
|
+
exclusion = Exclusions(
|
|
778
787
|
id=(
|
|
779
788
|
finding.vuln_id_from_tool
|
|
780
789
|
if finding.vuln_id_from_tool
|
|
@@ -790,9 +799,10 @@ class DefectDojoPlatform(VulnerabilityManagementGateway):
|
|
|
790
799
|
service=finding.service,
|
|
791
800
|
tags=finding.tags,
|
|
792
801
|
)
|
|
802
|
+
return exclusion
|
|
793
803
|
|
|
794
804
|
def _create_report(self, finding, host_dd):
|
|
795
|
-
|
|
805
|
+
report = Report(
|
|
796
806
|
vm_id=str(finding.id),
|
|
797
807
|
vm_id_url=f"{host_dd}/finding/{finding.id}",
|
|
798
808
|
id=finding.vulnerability_ids,
|
|
@@ -824,29 +834,33 @@ class DefectDojoPlatform(VulnerabilityManagementGateway):
|
|
|
824
834
|
service=finding.service,
|
|
825
835
|
unique_id_from_tool=finding.unique_id_from_tool,
|
|
826
836
|
)
|
|
837
|
+
return report
|
|
827
838
|
|
|
828
839
|
def _format_date_to_dd_format(self, date_string):
|
|
829
|
-
|
|
840
|
+
result = (
|
|
830
841
|
format_date(date_string.split("T")[0], "%Y-%m-%d", "%d%m%Y")
|
|
831
842
|
if date_string
|
|
832
843
|
else None
|
|
833
844
|
)
|
|
845
|
+
return result
|
|
834
846
|
|
|
835
847
|
def _get_where(self, finding, tool):
|
|
836
848
|
if tool == "engine_dependencies":
|
|
837
|
-
|
|
849
|
+
result = (
|
|
838
850
|
finding.component_name.replace("_", ":")
|
|
839
851
|
+ ":"
|
|
840
852
|
+ finding.component_version
|
|
841
853
|
)
|
|
842
854
|
elif tool == "engine_container":
|
|
843
|
-
|
|
855
|
+
result = finding.component_name + ":" + finding.component_version
|
|
844
856
|
elif tool == "engine_dast":
|
|
845
|
-
|
|
857
|
+
result = finding.endpoints
|
|
846
858
|
elif tool == "engine_risk":
|
|
847
859
|
for tag in finding.tags:
|
|
848
|
-
|
|
849
|
-
|
|
860
|
+
result = self._get_where(finding, tag)
|
|
861
|
+
return result
|
|
862
|
+
result = finding.file_path
|
|
850
863
|
else:
|
|
864
|
+
|
|
851
865
|
return finding.file_path
|
|
852
866
|
|
devsecops_engine_tools/engine_core/src/infrastructure/driven_adapters/github/github_actions.py
CHANGED
|
@@ -7,7 +7,8 @@ from devsecops_engine_tools.engine_utilities.github.models.GithubPredefinedVaria
|
|
|
7
7
|
SystemVariables,
|
|
8
8
|
ReleaseVariables,
|
|
9
9
|
AgentVariables,
|
|
10
|
-
VMVariables
|
|
10
|
+
VMVariables,
|
|
11
|
+
ApplicationVariables
|
|
11
12
|
)
|
|
12
13
|
from devsecops_engine_tools.engine_utilities.github.infrastructure.github_api import (
|
|
13
14
|
GithubApi,
|
|
@@ -94,6 +95,7 @@ class GithubActions(DevopsPlatformGateway):
|
|
|
94
95
|
"vm_product_type_name": VMVariables.Vm_Product_Type_Name,
|
|
95
96
|
"vm_product_name": VMVariables.Vm_Product_Name,
|
|
96
97
|
"vm_product_description": VMVariables.Vm_Product_Description,
|
|
98
|
+
"build_task": ApplicationVariables.Application_Build_Task,
|
|
97
99
|
}
|
|
98
100
|
try:
|
|
99
101
|
return variable_map.get(variable).value()
|
|
@@ -19,7 +19,7 @@ from prettytable import PrettyTable, DOUBLE_BORDER
|
|
|
19
19
|
class PrinterPrettyTable(PrinterTableGateway):
|
|
20
20
|
def _create_table(self, headers, finding_list):
|
|
21
21
|
table = PrettyTable(headers)
|
|
22
|
-
|
|
22
|
+
|
|
23
23
|
for finding in finding_list:
|
|
24
24
|
row_data = [
|
|
25
25
|
finding.severity,
|
|
@@ -31,7 +31,9 @@ class PrinterPrettyTable(PrinterTableGateway):
|
|
|
31
31
|
finding.module == "engine_dependencies"
|
|
32
32
|
):
|
|
33
33
|
row_data.append(finding.requirements)
|
|
34
|
-
|
|
34
|
+
elif finding.module == "engine_code":
|
|
35
|
+
row_data.append(finding.cvss)
|
|
36
|
+
row_data.append(finding.defect_type)
|
|
35
37
|
table.add_row(row_data)
|
|
36
38
|
|
|
37
39
|
severity_order = {"critical": 0, "high": 1, "medium": 2, "low": 3, "unknown": 4}
|
|
@@ -50,12 +52,17 @@ class PrinterPrettyTable(PrinterTableGateway):
|
|
|
50
52
|
def print_table_findings(self, finding_list: "list[Finding]"):
|
|
51
53
|
if (
|
|
52
54
|
finding_list
|
|
53
|
-
and (
|
|
54
|
-
|
|
55
|
+
and (
|
|
56
|
+
(finding_list[0].module == "engine_container")
|
|
57
|
+
or (finding_list[0].module == "engine_dependencies")
|
|
58
|
+
)
|
|
55
59
|
):
|
|
56
|
-
headers = ["Severity", "ID", "Description", "Where"]
|
|
57
|
-
else:
|
|
58
60
|
headers = ["Severity", "ID", "Description", "Where", "Fixed in"]
|
|
61
|
+
elif finding_list and finding_list[0].module == "engine_code":
|
|
62
|
+
headers = ["Severity", "ID", "Description", "Where", "Rule", "Defect Type"]
|
|
63
|
+
|
|
64
|
+
else:
|
|
65
|
+
headers = ["Severity", "ID", "Description", "Where"]
|
|
59
66
|
|
|
60
67
|
sorted_table = self._create_table(headers, finding_list)
|
|
61
68
|
|
|
@@ -165,4 +172,4 @@ class PrinterPrettyTable(PrinterTableGateway):
|
|
|
165
172
|
new_value = "\n".join(values)
|
|
166
173
|
else:
|
|
167
174
|
new_value = f"{values[0]}"
|
|
168
|
-
return new_value
|
|
175
|
+
return new_value
|
devsecops_engine_tools/engine_core/src/infrastructure/driven_adapters/runtime_local/runtime_local.py
CHANGED
|
@@ -76,5 +76,6 @@ class RuntimeLocal(DevopsPlatformGateway):
|
|
|
76
76
|
"vm_product_type_name" : "DET_VM_PRODUCT_TYPE_NAME",
|
|
77
77
|
"vm_product_name" : "DET_VM_PRODUCT_NAME",
|
|
78
78
|
"vm_product_description" : "DET_VM_PRODUCT_DESCRIPTION",
|
|
79
|
+
"build_task": "DET_APPLICATION_BUILD_TASK",
|
|
79
80
|
}
|
|
80
81
|
return os.environ.get(env_variables[variable], None)
|