devsecops-engine-tools 1.25.1__py3-none-any.whl → 1.26.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 +6 -0
- devsecops_engine_tools/engine_core/src/domain/model/component.py +7 -0
- devsecops_engine_tools/engine_core/src/domain/model/gateway/sbom_manager.py +11 -0
- devsecops_engine_tools/engine_core/src/domain/model/gateway/vulnerability_management_gateway.py +6 -0
- devsecops_engine_tools/engine_core/src/domain/usecases/handle_scan.py +125 -112
- devsecops_engine_tools/engine_core/src/infrastructure/driven_adapters/defect_dojo/defect_dojo.py +73 -14
- devsecops_engine_tools/engine_core/src/infrastructure/driven_adapters/syft/__init__.py +0 -0
- devsecops_engine_tools/engine_core/src/infrastructure/driven_adapters/syft/syft.py +122 -0
- devsecops_engine_tools/engine_core/src/infrastructure/entry_points/entry_point_core.py +3 -1
- devsecops_engine_tools/engine_sast/engine_iac/src/domain/usecases/iac_scan.py +1 -1
- devsecops_engine_tools/engine_sast/engine_iac/src/infrastructure/driven_adapters/checkov/checkov_tool.py +0 -3
- devsecops_engine_tools/engine_sca/engine_container/src/domain/model/gateways/tool_gateway.py +1 -1
- devsecops_engine_tools/engine_sca/engine_container/src/domain/usecases/container_sca_scan.py +17 -7
- devsecops_engine_tools/engine_sca/engine_container/src/infrastructure/driven_adapters/prisma_cloud/prisma_cloud_manager_scan.py +53 -3
- devsecops_engine_tools/engine_sca/engine_container/src/infrastructure/driven_adapters/trivy_tool/trivy_manager_scan.py +48 -12
- devsecops_engine_tools/engine_sca/engine_container/src/infrastructure/entry_points/entry_point_tool.py +5 -4
- devsecops_engine_tools/engine_sca/engine_dependencies/src/applications/runner_dependencies_scan.py +6 -3
- devsecops_engine_tools/engine_sca/engine_dependencies/src/infrastructure/entry_points/entry_point_tool.py +31 -4
- devsecops_engine_tools/engine_utilities/defect_dojo/__init__.py +2 -1
- devsecops_engine_tools/engine_utilities/defect_dojo/applications/component.py +29 -0
- devsecops_engine_tools/engine_utilities/defect_dojo/domain/models/component.py +20 -0
- devsecops_engine_tools/engine_utilities/defect_dojo/domain/user_case/component.py +11 -0
- devsecops_engine_tools/engine_utilities/defect_dojo/infraestructure/driver_adapters/component.py +52 -0
- devsecops_engine_tools/engine_utilities/sbom/__init__.py +0 -0
- devsecops_engine_tools/engine_utilities/sbom/deserealizator.py +24 -0
- devsecops_engine_tools/engine_utilities/sonarqube/src/infrastructure/entry_points/entry_point_report_sonar.py +32 -16
- devsecops_engine_tools/engine_utilities/utils/session_manager.py +4 -1
- devsecops_engine_tools/version.py +1 -1
- {devsecops_engine_tools-1.25.1.dist-info → devsecops_engine_tools-1.26.0.dist-info}/METADATA +1 -1
- {devsecops_engine_tools-1.25.1.dist-info → devsecops_engine_tools-1.26.0.dist-info}/RECORD +33 -23
- {devsecops_engine_tools-1.25.1.dist-info → devsecops_engine_tools-1.26.0.dist-info}/WHEEL +0 -0
- {devsecops_engine_tools-1.25.1.dist-info → devsecops_engine_tools-1.26.0.dist-info}/entry_points.txt +0 -0
- {devsecops_engine_tools-1.25.1.dist-info → devsecops_engine_tools-1.26.0.dist-info}/top_level.txt +0 -0
|
@@ -22,6 +22,7 @@ from devsecops_engine_tools.engine_core.src.infrastructure.driven_adapters.aws.s
|
|
|
22
22
|
from devsecops_engine_tools.engine_core.src.infrastructure.driven_adapters.printer_pretty_table.printer_pretty_table import (
|
|
23
23
|
PrinterPrettyTable,
|
|
24
24
|
)
|
|
25
|
+
from devsecops_engine_tools.engine_core.src.infrastructure.driven_adapters.syft.syft import Syft
|
|
25
26
|
import sys
|
|
26
27
|
import argparse
|
|
27
28
|
from devsecops_engine_tools.engine_utilities.utils.logger_info import MyLogger
|
|
@@ -115,6 +116,7 @@ def get_inputs_from_cli(args):
|
|
|
115
116
|
choices=["true", "false"],
|
|
116
117
|
type=str,
|
|
117
118
|
required=False,
|
|
119
|
+
default="false",
|
|
118
120
|
help="Use Secrets Manager to get the tokens",
|
|
119
121
|
)
|
|
120
122
|
parser.add_argument(
|
|
@@ -122,6 +124,7 @@ def get_inputs_from_cli(args):
|
|
|
122
124
|
choices=["true", "false"],
|
|
123
125
|
type=str,
|
|
124
126
|
required=False,
|
|
127
|
+
default="false",
|
|
125
128
|
help="Use Vulnerability Management to send the vulnerabilities to the platform",
|
|
126
129
|
)
|
|
127
130
|
parser.add_argument(
|
|
@@ -129,6 +132,7 @@ def get_inputs_from_cli(args):
|
|
|
129
132
|
choices=["true", "false"],
|
|
130
133
|
type=str,
|
|
131
134
|
required=False,
|
|
135
|
+
default="false",
|
|
132
136
|
help="Enable or Disable the send metrics to the driven adapter metrics",
|
|
133
137
|
)
|
|
134
138
|
parser.add_argument(
|
|
@@ -202,6 +206,7 @@ def application_core():
|
|
|
202
206
|
}.get(args["platform_devops"])
|
|
203
207
|
metrics_manager_gateway = S3Manager()
|
|
204
208
|
printer_table_gateway = PrinterPrettyTable()
|
|
209
|
+
sbom_tool_gateway = Syft()
|
|
205
210
|
|
|
206
211
|
init_engine_core(
|
|
207
212
|
vulnerability_management_gateway,
|
|
@@ -209,6 +214,7 @@ def application_core():
|
|
|
209
214
|
devops_platform_gateway,
|
|
210
215
|
printer_table_gateway,
|
|
211
216
|
metrics_manager_gateway,
|
|
217
|
+
sbom_tool_gateway,
|
|
212
218
|
args,
|
|
213
219
|
)
|
|
214
220
|
except Exception as e:
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
from abc import ABCMeta, abstractmethod
|
|
2
|
+
from devsecops_engine_tools.engine_core.src.domain.model.component import (
|
|
3
|
+
Component,
|
|
4
|
+
)
|
|
5
|
+
|
|
6
|
+
class SbomManagerGateway(metaclass=ABCMeta):
|
|
7
|
+
@abstractmethod
|
|
8
|
+
def get_components(
|
|
9
|
+
self, artifact, config, service_name
|
|
10
|
+
) -> "list[Component]":
|
|
11
|
+
"get_components"
|
devsecops_engine_tools/engine_core/src/domain/model/gateway/vulnerability_management_gateway.py
CHANGED
|
@@ -31,3 +31,9 @@ class VulnerabilityManagementGateway(metaclass=ABCMeta):
|
|
|
31
31
|
self, engagement_name, dict_args, secret_tool, config_tool
|
|
32
32
|
):
|
|
33
33
|
"get_active_engagements"
|
|
34
|
+
|
|
35
|
+
@abstractmethod
|
|
36
|
+
def send_sbom_components(
|
|
37
|
+
self, sbom_components, service, dict_args, secret_tool, config_tool
|
|
38
|
+
):
|
|
39
|
+
"send_sbom_components"
|
|
@@ -19,6 +19,9 @@ from devsecops_engine_tools.engine_core.src.domain.model.gateway.devops_platform
|
|
|
19
19
|
from devsecops_engine_tools.engine_core.src.domain.model.vulnerability_management import (
|
|
20
20
|
VulnerabilityManagement,
|
|
21
21
|
)
|
|
22
|
+
from devsecops_engine_tools.engine_core.src.domain.model.gateway.sbom_manager import (
|
|
23
|
+
SbomManagerGateway,
|
|
24
|
+
)
|
|
22
25
|
from devsecops_engine_tools.engine_core.src.domain.model.input_core import InputCore
|
|
23
26
|
from devsecops_engine_tools.engine_core.src.domain.model.level_vulnerability import (
|
|
24
27
|
LevelVulnerability,
|
|
@@ -51,83 +54,12 @@ class HandleScan:
|
|
|
51
54
|
vulnerability_management: VulnerabilityManagementGateway,
|
|
52
55
|
secrets_manager_gateway: SecretsManagerGateway,
|
|
53
56
|
devops_platform_gateway: DevopsPlatformGateway,
|
|
57
|
+
sbom_tool_gateway: SbomManagerGateway,
|
|
54
58
|
):
|
|
55
59
|
self.vulnerability_management = vulnerability_management
|
|
56
60
|
self.secrets_manager_gateway = secrets_manager_gateway
|
|
57
61
|
self.devops_platform_gateway = devops_platform_gateway
|
|
58
|
-
|
|
59
|
-
def _define_threshold_quality_vuln(
|
|
60
|
-
self, input_core: InputCore, dict_args, secret_tool, config_tool
|
|
61
|
-
):
|
|
62
|
-
quality_vulnerability_management = (
|
|
63
|
-
input_core.threshold_defined.quality_vulnerability_management
|
|
64
|
-
)
|
|
65
|
-
if quality_vulnerability_management:
|
|
66
|
-
product_type = self.vulnerability_management.get_product_type_service(
|
|
67
|
-
input_core.scope_pipeline, dict_args, secret_tool, config_tool
|
|
68
|
-
)
|
|
69
|
-
if product_type:
|
|
70
|
-
pt_name = product_type.name
|
|
71
|
-
apply_qualitypt = next(
|
|
72
|
-
filter(
|
|
73
|
-
lambda qapt: pt_name in qapt,
|
|
74
|
-
quality_vulnerability_management["PTS"],
|
|
75
|
-
),
|
|
76
|
-
None,
|
|
77
|
-
)
|
|
78
|
-
if apply_qualitypt:
|
|
79
|
-
pt_info = apply_qualitypt[pt_name]
|
|
80
|
-
pt_profile = pt_info["PROFILE"]
|
|
81
|
-
pt_apps = pt_info["APPS"]
|
|
82
|
-
|
|
83
|
-
input_core.threshold_defined.vulnerability = (
|
|
84
|
-
LevelVulnerability(quality_vulnerability_management[pt_profile])
|
|
85
|
-
if pt_apps == "ALL"
|
|
86
|
-
or any(map(lambda pd: pd in input_core.scope_pipeline, pt_apps))
|
|
87
|
-
else input_core.threshold_defined.vulnerability
|
|
88
|
-
)
|
|
89
|
-
|
|
90
|
-
def _use_vulnerability_management(
|
|
91
|
-
self, config_tool, input_core, dict_args, secret_tool, env
|
|
92
|
-
):
|
|
93
|
-
try:
|
|
94
|
-
self.vulnerability_management.send_vulnerability_management(
|
|
95
|
-
VulnerabilityManagement(
|
|
96
|
-
config_tool[dict_args["tool"].upper()]["TOOL"],
|
|
97
|
-
input_core,
|
|
98
|
-
dict_args,
|
|
99
|
-
secret_tool,
|
|
100
|
-
config_tool,
|
|
101
|
-
self.devops_platform_gateway.get_source_code_management_uri(),
|
|
102
|
-
self.devops_platform_gateway.get_base_compact_remote_config_url(
|
|
103
|
-
dict_args["remote_config_repo"]
|
|
104
|
-
),
|
|
105
|
-
self.devops_platform_gateway.get_variable("access_token"),
|
|
106
|
-
self.devops_platform_gateway.get_variable("build_execution_id"),
|
|
107
|
-
self.devops_platform_gateway.get_variable("build_id"),
|
|
108
|
-
self.devops_platform_gateway.get_variable("branch_tag"),
|
|
109
|
-
self.devops_platform_gateway.get_variable("commit_hash"),
|
|
110
|
-
env,
|
|
111
|
-
)
|
|
112
|
-
)
|
|
113
|
-
|
|
114
|
-
self._define_threshold_quality_vuln(
|
|
115
|
-
input_core, dict_args, secret_tool, config_tool
|
|
116
|
-
)
|
|
117
|
-
|
|
118
|
-
except ExceptionVulnerabilityManagement as ex1:
|
|
119
|
-
logger.error(str(ex1))
|
|
120
|
-
try:
|
|
121
|
-
input_core.totalized_exclusions.extend(
|
|
122
|
-
self.vulnerability_management.get_findings_excepted(
|
|
123
|
-
input_core.scope_pipeline,
|
|
124
|
-
dict_args,
|
|
125
|
-
secret_tool,
|
|
126
|
-
config_tool,
|
|
127
|
-
)
|
|
128
|
-
)
|
|
129
|
-
except ExceptionFindingsExcepted as ex2:
|
|
130
|
-
logger.error(str(ex2))
|
|
62
|
+
self.sbom_tool_gateway = sbom_tool_gateway
|
|
131
63
|
|
|
132
64
|
def process(self, dict_args: any, config_tool: any):
|
|
133
65
|
secret_tool = None
|
|
@@ -145,28 +77,25 @@ class HandleScan:
|
|
|
145
77
|
self.devops_platform_gateway,
|
|
146
78
|
env,
|
|
147
79
|
)
|
|
148
|
-
|
|
149
|
-
dict_args
|
|
150
|
-
|
|
151
|
-
):
|
|
152
|
-
self._use_vulnerability_management(
|
|
153
|
-
config_tool, input_core, dict_args, secret_tool, env
|
|
154
|
-
)
|
|
80
|
+
self._use_vulnerability_management(
|
|
81
|
+
config_tool, input_core, dict_args, secret_tool, env
|
|
82
|
+
)
|
|
155
83
|
return findings_list, input_core
|
|
156
84
|
elif "engine_container" in dict_args["tool"]:
|
|
157
|
-
findings_list, input_core = runner_engine_container(
|
|
85
|
+
findings_list, input_core, sbom_components = runner_engine_container(
|
|
158
86
|
dict_args,
|
|
159
87
|
config_tool["ENGINE_CONTAINER"]["TOOL"],
|
|
160
88
|
secret_tool,
|
|
161
89
|
self.devops_platform_gateway,
|
|
162
90
|
)
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
91
|
+
self._use_vulnerability_management(
|
|
92
|
+
config_tool,
|
|
93
|
+
input_core,
|
|
94
|
+
dict_args,
|
|
95
|
+
secret_tool,
|
|
96
|
+
env,
|
|
97
|
+
sbom_components,
|
|
98
|
+
)
|
|
170
99
|
return findings_list, input_core
|
|
171
100
|
elif "engine_dast" in dict_args["tool"]:
|
|
172
101
|
print(MESSAGE_ENABLED)
|
|
@@ -176,39 +105,123 @@ class HandleScan:
|
|
|
176
105
|
config_tool["ENGINE_CODE"]["TOOL"],
|
|
177
106
|
self.devops_platform_gateway,
|
|
178
107
|
)
|
|
179
|
-
|
|
180
|
-
dict_args
|
|
181
|
-
|
|
182
|
-
):
|
|
183
|
-
self._use_vulnerability_management(
|
|
184
|
-
config_tool, input_core, dict_args, secret_tool, env
|
|
185
|
-
)
|
|
108
|
+
self._use_vulnerability_management(
|
|
109
|
+
config_tool, input_core, dict_args, secret_tool, env
|
|
110
|
+
)
|
|
186
111
|
return findings_list, input_core
|
|
187
112
|
elif "engine_secret" in dict_args["tool"]:
|
|
188
113
|
findings_list, input_core = runner_secret_scan(
|
|
189
114
|
dict_args,
|
|
190
115
|
config_tool["ENGINE_SECRET"]["TOOL"],
|
|
191
116
|
self.devops_platform_gateway,
|
|
192
|
-
secret_tool
|
|
117
|
+
secret_tool,
|
|
118
|
+
)
|
|
119
|
+
self._use_vulnerability_management(
|
|
120
|
+
config_tool, input_core, dict_args, secret_tool, env
|
|
193
121
|
)
|
|
194
|
-
if (
|
|
195
|
-
dict_args["use_vulnerability_management"] == "true"
|
|
196
|
-
and input_core.path_file_results
|
|
197
|
-
):
|
|
198
|
-
self._use_vulnerability_management(
|
|
199
|
-
config_tool, input_core, dict_args, secret_tool, env
|
|
200
|
-
)
|
|
201
122
|
return findings_list, input_core
|
|
202
123
|
elif "engine_dependencies" in dict_args["tool"]:
|
|
203
|
-
findings_list, input_core = runner_engine_dependencies(
|
|
204
|
-
dict_args, config_tool, secret_tool, self.devops_platform_gateway
|
|
124
|
+
findings_list, input_core, sbom_components = runner_engine_dependencies(
|
|
125
|
+
dict_args, config_tool, secret_tool, self.devops_platform_gateway, self.sbom_tool_gateway
|
|
205
126
|
)
|
|
127
|
+
self._use_vulnerability_management(
|
|
128
|
+
config_tool,
|
|
129
|
+
input_core,
|
|
130
|
+
dict_args,
|
|
131
|
+
secret_tool,
|
|
132
|
+
env,
|
|
133
|
+
sbom_components
|
|
134
|
+
)
|
|
135
|
+
return findings_list, input_core
|
|
136
|
+
|
|
137
|
+
def _define_threshold_quality_vuln(
|
|
138
|
+
self, input_core: InputCore, dict_args, secret_tool, config_tool
|
|
139
|
+
):
|
|
140
|
+
quality_vulnerability_management = (
|
|
141
|
+
input_core.threshold_defined.quality_vulnerability_management
|
|
142
|
+
)
|
|
143
|
+
if quality_vulnerability_management:
|
|
144
|
+
product_type = self.vulnerability_management.get_product_type_service(
|
|
145
|
+
input_core.scope_pipeline, dict_args, secret_tool, config_tool
|
|
146
|
+
)
|
|
147
|
+
if product_type:
|
|
148
|
+
pt_name = product_type.name
|
|
149
|
+
apply_qualitypt = next(
|
|
150
|
+
filter(
|
|
151
|
+
lambda qapt: pt_name in qapt,
|
|
152
|
+
quality_vulnerability_management["PTS"],
|
|
153
|
+
),
|
|
154
|
+
None,
|
|
155
|
+
)
|
|
156
|
+
if apply_qualitypt:
|
|
157
|
+
pt_info = apply_qualitypt[pt_name]
|
|
158
|
+
pt_profile = pt_info["PROFILE"]
|
|
159
|
+
pt_apps = pt_info["APPS"]
|
|
206
160
|
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
161
|
+
input_core.threshold_defined.vulnerability = (
|
|
162
|
+
LevelVulnerability(quality_vulnerability_management[pt_profile])
|
|
163
|
+
if pt_apps == "ALL"
|
|
164
|
+
or any(map(lambda pd: pd in input_core.scope_pipeline, pt_apps))
|
|
165
|
+
else input_core.threshold_defined.vulnerability
|
|
166
|
+
)
|
|
167
|
+
|
|
168
|
+
def _use_vulnerability_management(
|
|
169
|
+
self,
|
|
170
|
+
config_tool,
|
|
171
|
+
input_core: InputCore,
|
|
172
|
+
dict_args,
|
|
173
|
+
secret_tool,
|
|
174
|
+
env,
|
|
175
|
+
sbom_components=None,
|
|
176
|
+
):
|
|
177
|
+
if dict_args["use_vulnerability_management"] == "true":
|
|
178
|
+
try:
|
|
179
|
+
if input_core.path_file_results:
|
|
180
|
+
self.vulnerability_management.send_vulnerability_management(
|
|
181
|
+
VulnerabilityManagement(
|
|
182
|
+
config_tool[dict_args["tool"].upper()]["TOOL"],
|
|
183
|
+
input_core,
|
|
184
|
+
dict_args,
|
|
185
|
+
secret_tool,
|
|
186
|
+
config_tool,
|
|
187
|
+
self.devops_platform_gateway.get_source_code_management_uri(),
|
|
188
|
+
self.devops_platform_gateway.get_base_compact_remote_config_url(
|
|
189
|
+
dict_args["remote_config_repo"]
|
|
190
|
+
),
|
|
191
|
+
self.devops_platform_gateway.get_variable("access_token"),
|
|
192
|
+
self.devops_platform_gateway.get_variable(
|
|
193
|
+
"build_execution_id"
|
|
194
|
+
),
|
|
195
|
+
self.devops_platform_gateway.get_variable("build_id"),
|
|
196
|
+
self.devops_platform_gateway.get_variable("branch_tag"),
|
|
197
|
+
self.devops_platform_gateway.get_variable("commit_hash"),
|
|
198
|
+
env,
|
|
199
|
+
)
|
|
200
|
+
)
|
|
201
|
+
|
|
202
|
+
if sbom_components:
|
|
203
|
+
self.vulnerability_management.send_sbom_components(
|
|
204
|
+
sbom_components,
|
|
205
|
+
input_core.scope_pipeline,
|
|
206
|
+
dict_args,
|
|
207
|
+
secret_tool,
|
|
208
|
+
config_tool,
|
|
209
|
+
)
|
|
210
|
+
|
|
211
|
+
self._define_threshold_quality_vuln(
|
|
212
|
+
input_core, dict_args, secret_tool, config_tool
|
|
213
213
|
)
|
|
214
|
-
|
|
214
|
+
|
|
215
|
+
except ExceptionVulnerabilityManagement as ex1:
|
|
216
|
+
logger.error(str(ex1))
|
|
217
|
+
try:
|
|
218
|
+
input_core.totalized_exclusions.extend(
|
|
219
|
+
self.vulnerability_management.get_findings_excepted(
|
|
220
|
+
input_core.scope_pipeline,
|
|
221
|
+
dict_args,
|
|
222
|
+
secret_tool,
|
|
223
|
+
config_tool,
|
|
224
|
+
)
|
|
225
|
+
)
|
|
226
|
+
except ExceptionFindingsExcepted as ex2:
|
|
227
|
+
logger.error(str(ex2))
|
devsecops_engine_tools/engine_core/src/infrastructure/driven_adapters/defect_dojo/defect_dojo.py
CHANGED
|
@@ -5,9 +5,6 @@ from devsecops_engine_tools.engine_core.src.domain.model.gateway.vulnerability_m
|
|
|
5
5
|
from devsecops_engine_tools.engine_core.src.domain.model.vulnerability_management import (
|
|
6
6
|
VulnerabilityManagement,
|
|
7
7
|
)
|
|
8
|
-
from devsecops_engine_tools.engine_core.src.domain.model.gateway.devops_platform_gateway import (
|
|
9
|
-
DevopsPlatformGateway
|
|
10
|
-
)
|
|
11
8
|
from devsecops_engine_tools.engine_utilities.defect_dojo import (
|
|
12
9
|
DefectDojo,
|
|
13
10
|
ImportScanRequest,
|
|
@@ -15,6 +12,7 @@ from devsecops_engine_tools.engine_utilities.defect_dojo import (
|
|
|
15
12
|
Finding,
|
|
16
13
|
Engagement,
|
|
17
14
|
Product,
|
|
15
|
+
Component,
|
|
18
16
|
)
|
|
19
17
|
from devsecops_engine_tools.engine_core.src.domain.model.exclusions import Exclusions
|
|
20
18
|
from devsecops_engine_tools.engine_core.src.domain.model.report import Report
|
|
@@ -33,6 +31,7 @@ from functools import partial
|
|
|
33
31
|
from devsecops_engine_tools.engine_utilities.utils.logger_info import MyLogger
|
|
34
32
|
from devsecops_engine_tools.engine_utilities import settings
|
|
35
33
|
import time
|
|
34
|
+
import concurrent.futures
|
|
36
35
|
|
|
37
36
|
logger = MyLogger.__call__(**settings.SETTING_LOGGER).get_logger()
|
|
38
37
|
|
|
@@ -76,14 +75,14 @@ class DefectDojoPlatform(VulnerabilityManagementGateway):
|
|
|
76
75
|
"KICS": "KICS Scanner",
|
|
77
76
|
"BEARER": "Bearer CLI",
|
|
78
77
|
"DEPENDENCY_CHECK": "Dependency Check Scan",
|
|
79
|
-
"SONARQUBE": "SonarQube API Import"
|
|
78
|
+
"SONARQUBE": "SonarQube API Import",
|
|
80
79
|
}
|
|
81
80
|
|
|
82
81
|
if any(
|
|
83
82
|
branch in str(vulnerability_management.branch_tag)
|
|
84
83
|
for branch in vulnerability_management.config_tool[
|
|
85
84
|
"VULNERABILITY_MANAGER"
|
|
86
|
-
]["BRANCH_FILTER"]
|
|
85
|
+
]["BRANCH_FILTER"]
|
|
87
86
|
) or (vulnerability_management.dict_args["tool"] == "engine_secret"):
|
|
88
87
|
tags = vulnerability_management.dict_args["tool"]
|
|
89
88
|
if vulnerability_management.dict_args["tool"] == "engine_iac":
|
|
@@ -178,7 +177,11 @@ class DefectDojoPlatform(VulnerabilityManagementGateway):
|
|
|
178
177
|
"prefetch": "prod_type",
|
|
179
178
|
},
|
|
180
179
|
)
|
|
181
|
-
return
|
|
180
|
+
return (
|
|
181
|
+
response.prefetch.prod_type[str(response.results[0].prod_type)]
|
|
182
|
+
if response.prefetch
|
|
183
|
+
else None
|
|
184
|
+
)
|
|
182
185
|
|
|
183
186
|
return self._retries_requests(request_func, dd_max_retries, retry_delay=5)
|
|
184
187
|
|
|
@@ -282,12 +285,14 @@ class DefectDojoPlatform(VulnerabilityManagementGateway):
|
|
|
282
285
|
"limit": config_tool["VULNERABILITY_MANAGER"]["DEFECT_DOJO"][
|
|
283
286
|
"LIMITS_QUERY"
|
|
284
287
|
],
|
|
285
|
-
"duplicate": "false"
|
|
288
|
+
"duplicate": "false",
|
|
286
289
|
}
|
|
287
290
|
max_retries = config_tool["VULNERABILITY_MANAGER"]["DEFECT_DOJO"][
|
|
288
291
|
"MAX_RETRIES_QUERY"
|
|
289
292
|
]
|
|
290
|
-
host_dd = config_tool["VULNERABILITY_MANAGER"]["DEFECT_DOJO"][
|
|
293
|
+
host_dd = config_tool["VULNERABILITY_MANAGER"]["DEFECT_DOJO"][
|
|
294
|
+
"HOST_DEFECT_DOJO"
|
|
295
|
+
]
|
|
291
296
|
|
|
292
297
|
findings = self._get_findings(
|
|
293
298
|
self._get_session_manager(dict_args, secret_tool, config_tool),
|
|
@@ -337,7 +342,9 @@ class DefectDojoPlatform(VulnerabilityManagementGateway):
|
|
|
337
342
|
|
|
338
343
|
engagements = Engagement.get_engagements(request_is, request_active).results
|
|
339
344
|
|
|
340
|
-
host_dd = config_tool["VULNERABILITY_MANAGER"]["DEFECT_DOJO"][
|
|
345
|
+
host_dd = config_tool["VULNERABILITY_MANAGER"]["DEFECT_DOJO"][
|
|
346
|
+
"HOST_DEFECT_DOJO"
|
|
347
|
+
]
|
|
341
348
|
|
|
342
349
|
for engagement in engagements:
|
|
343
350
|
engagement.vm_url = f"{host_dd}/engagement/{engagement.id}/finding/open"
|
|
@@ -349,6 +356,53 @@ class DefectDojoPlatform(VulnerabilityManagementGateway):
|
|
|
349
356
|
"Error getting engagements with the following error: {0} ".format(ex)
|
|
350
357
|
)
|
|
351
358
|
|
|
359
|
+
def send_sbom_components(
|
|
360
|
+
self, sbom_components, service, dict_args, secret_tool, config_tool
|
|
361
|
+
):
|
|
362
|
+
try:
|
|
363
|
+
engagements = self.get_active_engagements(
|
|
364
|
+
service, dict_args, secret_tool, config_tool
|
|
365
|
+
)
|
|
366
|
+
engagement = [
|
|
367
|
+
engagement for engagement in engagements if engagement.name == service
|
|
368
|
+
]
|
|
369
|
+
session_manager = self._get_session_manager(
|
|
370
|
+
dict_args, secret_tool, config_tool
|
|
371
|
+
)
|
|
372
|
+
|
|
373
|
+
with concurrent.futures.ThreadPoolExecutor(max_workers=25) as executor:
|
|
374
|
+
_ = [
|
|
375
|
+
executor.submit(
|
|
376
|
+
self._process_component,
|
|
377
|
+
sbom_component,
|
|
378
|
+
session_manager,
|
|
379
|
+
engagement,
|
|
380
|
+
)
|
|
381
|
+
for sbom_component in sbom_components
|
|
382
|
+
]
|
|
383
|
+
|
|
384
|
+
except Exception as ex:
|
|
385
|
+
raise ExceptionVulnerabilityManagement(
|
|
386
|
+
"Error sending components sbom to vulnerability management with the following error: {0} ".format(
|
|
387
|
+
ex
|
|
388
|
+
)
|
|
389
|
+
)
|
|
390
|
+
|
|
391
|
+
def _process_component(self, component_sbom, session_manager, engagement):
|
|
392
|
+
request = {
|
|
393
|
+
"name": component_sbom.name,
|
|
394
|
+
"version": component_sbom.version,
|
|
395
|
+
"engagement_id": engagement[0].id,
|
|
396
|
+
}
|
|
397
|
+
components = Component.get_component(session=session_manager, request=request)
|
|
398
|
+
if components.results == []:
|
|
399
|
+
response = Component.create_component(
|
|
400
|
+
session=session_manager, request=request
|
|
401
|
+
)
|
|
402
|
+
logger.info(
|
|
403
|
+
f"Component created: {response.name} - {response.version} found with id: {response.id}"
|
|
404
|
+
)
|
|
405
|
+
|
|
352
406
|
def _get_session_manager(self, dict_args, secret_tool, config_tool):
|
|
353
407
|
token_dd = dict_args.get("token_vulnerability_management") or secret_tool.get(
|
|
354
408
|
"token_defect_dojo"
|
|
@@ -382,7 +436,11 @@ class DefectDojoPlatform(VulnerabilityManagementGateway):
|
|
|
382
436
|
elif finding.risk_status == "Transfer Accepted":
|
|
383
437
|
exclusions.append(
|
|
384
438
|
self._create_report_exclusion(
|
|
385
|
-
finding,
|
|
439
|
+
finding,
|
|
440
|
+
date_fn,
|
|
441
|
+
"engine_risk",
|
|
442
|
+
self.TRANSFERRED_FINDING,
|
|
443
|
+
host_dd,
|
|
386
444
|
)
|
|
387
445
|
)
|
|
388
446
|
return exclusions
|
|
@@ -433,7 +491,6 @@ class DefectDojoPlatform(VulnerabilityManagementGateway):
|
|
|
433
491
|
|
|
434
492
|
return create_date, expired_date
|
|
435
493
|
|
|
436
|
-
|
|
437
494
|
def _create_exclusion(self, finding, date_fn, tool, reason):
|
|
438
495
|
create_date, expired_date = self._date_reason_based(finding, date_fn, reason)
|
|
439
496
|
|
|
@@ -445,7 +502,7 @@ class DefectDojoPlatform(VulnerabilityManagementGateway):
|
|
|
445
502
|
severity=finding.severity,
|
|
446
503
|
reason=reason,
|
|
447
504
|
)
|
|
448
|
-
|
|
505
|
+
|
|
449
506
|
def _create_report_exclusion(self, finding, date_fn, tool, reason, host_dd):
|
|
450
507
|
create_date, expired_date = self._date_reason_based(finding, date_fn, reason)
|
|
451
508
|
|
|
@@ -493,7 +550,7 @@ class DefectDojoPlatform(VulnerabilityManagementGateway):
|
|
|
493
550
|
false_p=finding.false_p,
|
|
494
551
|
out_of_scope=finding.out_of_scope,
|
|
495
552
|
service=finding.service,
|
|
496
|
-
unique_id_from_tool=finding.unique_id_from_tool
|
|
553
|
+
unique_id_from_tool=finding.unique_id_from_tool,
|
|
497
554
|
)
|
|
498
555
|
|
|
499
556
|
def _format_date_to_dd_format(self, date_string):
|
|
@@ -504,7 +561,9 @@ class DefectDojoPlatform(VulnerabilityManagementGateway):
|
|
|
504
561
|
)
|
|
505
562
|
|
|
506
563
|
def _get_where(self, finding, tool):
|
|
507
|
-
if tool
|
|
564
|
+
if tool == "engine_dependencies":
|
|
565
|
+
return finding.component_name.replace("_", ":") + ":" + finding.component_version
|
|
566
|
+
elif tool == "engine_container":
|
|
508
567
|
return finding.component_name + ":" + finding.component_version
|
|
509
568
|
elif tool == "engine_dast":
|
|
510
569
|
return finding.endpoints
|
|
File without changes
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
import requests
|
|
3
|
+
import subprocess
|
|
4
|
+
import tarfile
|
|
5
|
+
import zipfile
|
|
6
|
+
import platform
|
|
7
|
+
|
|
8
|
+
from devsecops_engine_tools.engine_core.src.domain.model.gateway.sbom_manager import (
|
|
9
|
+
SbomManagerGateway,
|
|
10
|
+
)
|
|
11
|
+
from devsecops_engine_tools.engine_utilities.sbom.deserealizator import (
|
|
12
|
+
get_list_component,
|
|
13
|
+
)
|
|
14
|
+
from devsecops_engine_tools.engine_core.src.domain.model.component import (
|
|
15
|
+
Component,
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
from devsecops_engine_tools.engine_utilities.utils.logger_info import MyLogger
|
|
19
|
+
from devsecops_engine_tools.engine_utilities import settings
|
|
20
|
+
|
|
21
|
+
logger = MyLogger.__call__(**settings.SETTING_LOGGER).get_logger()
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
@dataclass
|
|
25
|
+
class Syft(SbomManagerGateway):
|
|
26
|
+
|
|
27
|
+
def get_components(self, artifact, config, service_name) -> "list[Component]":
|
|
28
|
+
try:
|
|
29
|
+
syft_version = config["SYFT"]["SYFT_VERSION"]
|
|
30
|
+
os_platform = platform.system()
|
|
31
|
+
base_url = (
|
|
32
|
+
f"https://github.com/anchore/syft/releases/download/v{syft_version}/"
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
command_prefix = "syft"
|
|
36
|
+
if os_platform == "Linux":
|
|
37
|
+
file = f"syft_{syft_version}_linux_amd64.tar.gz"
|
|
38
|
+
command_prefix = self._install_tool_unix(
|
|
39
|
+
file, base_url + file, command_prefix
|
|
40
|
+
)
|
|
41
|
+
elif os_platform == "Darwin":
|
|
42
|
+
file = f"syft_{syft_version}_darwin_amd64.tar.gz"
|
|
43
|
+
command_prefix = self._install_tool_unix(
|
|
44
|
+
file, base_url + file, command_prefix
|
|
45
|
+
)
|
|
46
|
+
elif os_platform == "Windows":
|
|
47
|
+
file = f"syft_{syft_version}_windows_amd64.zip"
|
|
48
|
+
command_prefix = self._install_tool_windows(
|
|
49
|
+
file, base_url + file, "syft.exe"
|
|
50
|
+
)
|
|
51
|
+
else:
|
|
52
|
+
logger.warning(f"{os_platform} is not supported.")
|
|
53
|
+
return None
|
|
54
|
+
|
|
55
|
+
result_sbom = self._run_syft(command_prefix, artifact, config, service_name)
|
|
56
|
+
return get_list_component(result_sbom, config["SYFT"]["OUTPUT_FORMAT"])
|
|
57
|
+
except Exception as e:
|
|
58
|
+
logger.error(f"Error generating SBOM: {e}")
|
|
59
|
+
return None
|
|
60
|
+
|
|
61
|
+
def _run_syft(self, command_prefix, artifact, config, service_name):
|
|
62
|
+
result_file = f"{service_name}_SBOM.json"
|
|
63
|
+
command = [
|
|
64
|
+
command_prefix,
|
|
65
|
+
artifact,
|
|
66
|
+
"-o",
|
|
67
|
+
f"{config['SYFT']['OUTPUT_FORMAT']}={result_file}",
|
|
68
|
+
]
|
|
69
|
+
try:
|
|
70
|
+
subprocess.run(
|
|
71
|
+
command,
|
|
72
|
+
check=True,
|
|
73
|
+
stdout=subprocess.PIPE,
|
|
74
|
+
stderr=subprocess.PIPE,
|
|
75
|
+
text=True,
|
|
76
|
+
)
|
|
77
|
+
print(f"SBOM generated and saved to: {result_file}")
|
|
78
|
+
return result_file
|
|
79
|
+
except Exception as e:
|
|
80
|
+
logger.error(f"Error running syft: {e}")
|
|
81
|
+
|
|
82
|
+
def _install_tool_unix(self, file, url, command_prefix):
|
|
83
|
+
installed = subprocess.run(
|
|
84
|
+
["which", command_prefix],
|
|
85
|
+
stdout=subprocess.PIPE,
|
|
86
|
+
stderr=subprocess.PIPE,
|
|
87
|
+
)
|
|
88
|
+
if installed.returncode == 1:
|
|
89
|
+
try:
|
|
90
|
+
self._download_tool(file, url)
|
|
91
|
+
with tarfile.open(file, "r:gz") as tar_file:
|
|
92
|
+
tar_file.extract(member=tar_file.getmember("syft"))
|
|
93
|
+
return "./syft"
|
|
94
|
+
except Exception as e:
|
|
95
|
+
logger.error(f"Error installing syft: {e}")
|
|
96
|
+
else:
|
|
97
|
+
return installed.stdout.decode("utf-8").strip()
|
|
98
|
+
|
|
99
|
+
def _install_tool_windows(self, file, url, command_prefix):
|
|
100
|
+
try:
|
|
101
|
+
installed = subprocess.run(
|
|
102
|
+
[command_prefix, "--version"],
|
|
103
|
+
stdout=subprocess.PIPE,
|
|
104
|
+
stderr=subprocess.PIPE,
|
|
105
|
+
)
|
|
106
|
+
return installed.stdout.decode("utf-8").strip()
|
|
107
|
+
except:
|
|
108
|
+
try:
|
|
109
|
+
self._download_tool(file, url)
|
|
110
|
+
with zipfile.ZipFile(file, "r") as zip_file:
|
|
111
|
+
zip_file.extract(member="syft.exe")
|
|
112
|
+
return "./syft.exe"
|
|
113
|
+
except Exception as e:
|
|
114
|
+
logger.error(f"Error installing syft: {e}")
|
|
115
|
+
|
|
116
|
+
def _download_tool(self, file, url):
|
|
117
|
+
try:
|
|
118
|
+
response = requests.get(url, allow_redirects=True)
|
|
119
|
+
with open(file, "wb") as compress_file:
|
|
120
|
+
compress_file.write(response.content)
|
|
121
|
+
except Exception as e:
|
|
122
|
+
logger.error(f"Error downloading syft: {e}")
|