devsecops-engine-tools 1.43.0__py3-none-any.whl → 1.44.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_risk/src/domain/usecases/break_build.py +54 -10
- devsecops_engine_tools/engine_risk/src/domain/usecases/get_exclusions.py +3 -0
- devsecops_engine_tools/engine_sca/engine_container/src/infrastructure/driven_adapters/docker/docker_images.py +12 -5
- devsecops_engine_tools/version.py +1 -1
- {devsecops_engine_tools-1.43.0.dist-info → devsecops_engine_tools-1.44.0.dist-info}/METADATA +2 -1
- {devsecops_engine_tools-1.43.0.dist-info → devsecops_engine_tools-1.44.0.dist-info}/RECORD +9 -9
- {devsecops_engine_tools-1.43.0.dist-info → devsecops_engine_tools-1.44.0.dist-info}/WHEEL +0 -0
- {devsecops_engine_tools-1.43.0.dist-info → devsecops_engine_tools-1.44.0.dist-info}/entry_points.txt +0 -0
- {devsecops_engine_tools-1.43.0.dist-info → devsecops_engine_tools-1.44.0.dist-info}/top_level.txt +0 -0
|
@@ -13,6 +13,8 @@ from devsecops_engine_tools.engine_core.src.domain.model.exclusions import (
|
|
|
13
13
|
|
|
14
14
|
from collections import Counter
|
|
15
15
|
import copy
|
|
16
|
+
import sympy as sp
|
|
17
|
+
import math
|
|
16
18
|
|
|
17
19
|
|
|
18
20
|
class BreakBuild:
|
|
@@ -53,7 +55,7 @@ class BreakBuild:
|
|
|
53
55
|
|
|
54
56
|
def process(self):
|
|
55
57
|
new_report_list, applied_exclusions = self._apply_exclusions(self.report_list)
|
|
56
|
-
self.
|
|
58
|
+
self._blacklist_control(new_report_list)
|
|
57
59
|
self._remediation_rate_control(self.all_report, new_report_list)
|
|
58
60
|
self._risk_score_control(new_report_list)
|
|
59
61
|
all_exclusions = list(self.vm_exclusions) + list(applied_exclusions)
|
|
@@ -121,17 +123,45 @@ class BreakBuild:
|
|
|
121
123
|
def _remediation_rate_control(
|
|
122
124
|
self, all_report: "list[Report]", new_report_list: "list[Report]"
|
|
123
125
|
):
|
|
124
|
-
|
|
125
|
-
|
|
126
|
+
sp.init_printing(use_unicode=True)
|
|
127
|
+
(
|
|
128
|
+
remediation_rate_name,
|
|
129
|
+
mitigated_name,
|
|
130
|
+
all_findings_name,
|
|
131
|
+
new_industry_vulnerabilities,
|
|
132
|
+
white_list_name,
|
|
133
|
+
base_image_name,
|
|
134
|
+
) = sp.symbols(
|
|
135
|
+
"RemediationRate Mitigated AllFindings NewIndustryVulnerabilities WhiteList BaseImage"
|
|
136
|
+
)
|
|
137
|
+
formula = sp.Eq(
|
|
138
|
+
remediation_rate_name,
|
|
139
|
+
100
|
|
140
|
+
* (mitigated_name / (all_findings_name - new_industry_vulnerabilities - white_list_name - base_image_name)),
|
|
141
|
+
)
|
|
142
|
+
print("\n")
|
|
143
|
+
sp.pretty_print(formula)
|
|
144
|
+
print("\n")
|
|
145
|
+
|
|
146
|
+
mitigated_count = sum(1 for report in all_report if report.mitigated)
|
|
147
|
+
white_list_count = sum(
|
|
148
|
+
1
|
|
149
|
+
for report in all_report
|
|
150
|
+
if "On Whitelist" in report.risk_status and not report.mitigated
|
|
151
|
+
)
|
|
152
|
+
base_image_count = sum(
|
|
126
153
|
1
|
|
127
154
|
for report in all_report
|
|
128
|
-
if "
|
|
155
|
+
if "Image Base" in report.vul_description
|
|
156
|
+
and "On Whitelist" not in report.risk_status
|
|
157
|
+
and not report.mitigated
|
|
129
158
|
)
|
|
130
|
-
|
|
159
|
+
all_findings_count = len(all_report)
|
|
131
160
|
print(
|
|
132
|
-
f"Mitigated
|
|
161
|
+
f"Mitigated: {mitigated_count} AllFindings: {all_findings_count} BaseImage: {base_image_count} NewIndustryVulnerabilities: {self.policy_excluded} WhiteList: {white_list_count}\n\n"
|
|
133
162
|
)
|
|
134
|
-
|
|
163
|
+
total = all_findings_count - self.policy_excluded - white_list_count - base_image_count
|
|
164
|
+
remediation_rate_value = self._get_percentage(mitigated_count / total)
|
|
135
165
|
|
|
136
166
|
risk_threshold = self._get_remediation_rate_threshold(total)
|
|
137
167
|
self.remediation_rate = remediation_rate_value
|
|
@@ -152,10 +182,11 @@ class BreakBuild:
|
|
|
152
182
|
)
|
|
153
183
|
self.warning_build = True
|
|
154
184
|
else:
|
|
185
|
+
missing_findings = math.ceil((risk_threshold / 100 * total) - mitigated_count)
|
|
155
186
|
print(
|
|
156
187
|
self.devops_platform_gateway.message(
|
|
157
188
|
"error",
|
|
158
|
-
f"Remediation rate {remediation_rate_value}% is less than {risk_threshold}
|
|
189
|
+
f"Remediation rate {remediation_rate_value}% is less than {risk_threshold}%. Minimum findings to mitigate: {missing_findings}.",
|
|
159
190
|
)
|
|
160
191
|
)
|
|
161
192
|
self.break_build = True
|
|
@@ -230,7 +261,7 @@ class BreakBuild:
|
|
|
230
261
|
|
|
231
262
|
return filtered_reports, applied_exclusions
|
|
232
263
|
|
|
233
|
-
def
|
|
264
|
+
def _blacklist_control(self, report_list: "list[Report]"):
|
|
234
265
|
remote_config = self.remote_config
|
|
235
266
|
if report_list:
|
|
236
267
|
tag_blacklist = set(remote_config["TAG_BLACKLIST_EXCLUSION_DAYS"].keys())
|
|
@@ -271,13 +302,26 @@ class BreakBuild:
|
|
|
271
302
|
|
|
272
303
|
if filtered_reports_above_threshold:
|
|
273
304
|
self.break_build = True
|
|
274
|
-
self.blacklisted
|
|
305
|
+
self.blacklisted += len(filtered_reports_above_threshold)
|
|
275
306
|
self.report_breaker.extend(
|
|
276
307
|
copy.deepcopy(
|
|
277
308
|
[report for report, _ in filtered_reports_above_threshold]
|
|
278
309
|
)
|
|
279
310
|
)
|
|
280
311
|
|
|
312
|
+
for report in report_list:
|
|
313
|
+
if "On Blacklist" in report.risk_status:
|
|
314
|
+
self.break_build = True
|
|
315
|
+
report.reason = "Blacklisted"
|
|
316
|
+
self.blacklisted += 1
|
|
317
|
+
self.report_breaker.append(copy.deepcopy(report))
|
|
318
|
+
print(
|
|
319
|
+
self.devops_platform_gateway.message(
|
|
320
|
+
"error",
|
|
321
|
+
f"Report {report.vm_id} is blacklisted.",
|
|
322
|
+
)
|
|
323
|
+
)
|
|
324
|
+
|
|
281
325
|
def _risk_score_control(self, report_list: "list[Report]"):
|
|
282
326
|
remote_config = self.remote_config
|
|
283
327
|
risk_score_threshold = self.threshold["RISK_SCORE"]
|
|
@@ -101,4 +101,7 @@ class GetExclusions:
|
|
|
101
101
|
).strftime("%d%m%Y")
|
|
102
102
|
exclusion_data["reason"] = "New vulnerability in the industry"
|
|
103
103
|
exclusions.append(Exclusions(**exclusion_data))
|
|
104
|
+
finding.vul_description = finding.vul_description.replace(
|
|
105
|
+
"Image Base", ""
|
|
106
|
+
)
|
|
104
107
|
return exclusions, len(exclusions)
|
|
@@ -34,14 +34,21 @@ class DockerImages(ImagesGateway):
|
|
|
34
34
|
)
|
|
35
35
|
|
|
36
36
|
def get_base_image(self, matching_image):
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
37
|
+
try:
|
|
38
|
+
image_details = self.get_image_details(matching_image.id)
|
|
39
|
+
if not image_details:
|
|
40
|
+
return None
|
|
40
41
|
|
|
41
|
-
|
|
42
|
-
|
|
42
|
+
labels = image_details.get("Config", {}).get("Labels", {})
|
|
43
|
+
return self.extract_base_image_from_labels(labels, matching_image)
|
|
44
|
+
except Exception as e:
|
|
45
|
+
logger.warning(f"Error obtaining base image: {e}")
|
|
46
|
+
return None
|
|
43
47
|
|
|
44
48
|
def validate_base_image_date(self, matching_image, referenced_date):
|
|
49
|
+
if matching_image is None or matching_image.id is None:
|
|
50
|
+
logger.error("Error: matching_image ID is None")
|
|
51
|
+
return False
|
|
45
52
|
image_details = self.get_image_details(matching_image.id)
|
|
46
53
|
if not image_details:
|
|
47
54
|
return False
|
|
@@ -1 +1 @@
|
|
|
1
|
-
version = '1.
|
|
1
|
+
version = '1.44.0'
|
{devsecops_engine_tools-1.43.0.dist-info → devsecops_engine_tools-1.44.0.dist-info}/METADATA
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: devsecops-engine-tools
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.44.0
|
|
4
4
|
Summary: Tool for DevSecOps strategy
|
|
5
5
|
Home-page: https://github.com/bancolombia/devsecops-engine-tools
|
|
6
6
|
Author: Bancolombia DevSecOps Team
|
|
@@ -31,6 +31,7 @@ Requires-Dist: packageurl-python==0.15.6
|
|
|
31
31
|
Requires-Dist: ruamel.yaml==0.18.6
|
|
32
32
|
Requires-Dist: Authlib==1.3.2
|
|
33
33
|
Requires-Dist: PyJWT==2.9.0
|
|
34
|
+
Requires-Dist: sympy==1.13.3
|
|
34
35
|
|
|
35
36
|
# DevSecOps Engine Tools
|
|
36
37
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
devsecops_engine_tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
-
devsecops_engine_tools/version.py,sha256=
|
|
2
|
+
devsecops_engine_tools/version.py,sha256=wS3RHs8gSUSbjEyCqrz_WglPyvNGJoNxlUU3ajViqAA,19
|
|
3
3
|
devsecops_engine_tools/engine_core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
4
4
|
devsecops_engine_tools/engine_core/src/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
5
5
|
devsecops_engine_tools/engine_core/src/applications/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -101,9 +101,9 @@ devsecops_engine_tools/engine_risk/src/domain/model/gateways/__init__.py,sha256=
|
|
|
101
101
|
devsecops_engine_tools/engine_risk/src/domain/model/gateways/add_epss_gateway.py,sha256=cTm4QSxiaUt7ETCdXWZxKEus8pmEDA3e9k5b39SLDDE,178
|
|
102
102
|
devsecops_engine_tools/engine_risk/src/domain/usecases/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
103
103
|
devsecops_engine_tools/engine_risk/src/domain/usecases/add_data.py,sha256=4wqDj-q7hJfJscvrbMDcy7tONqxdxl-CSl_TWTRUGKA,402
|
|
104
|
-
devsecops_engine_tools/engine_risk/src/domain/usecases/break_build.py,sha256=
|
|
104
|
+
devsecops_engine_tools/engine_risk/src/domain/usecases/break_build.py,sha256=iSZOvwfyJgjIkOmDMa_kBWMxLbnXkgdlfogM4mtftVM,15000
|
|
105
105
|
devsecops_engine_tools/engine_risk/src/domain/usecases/check_threshold.py,sha256=VYdmcbAuNNvdHCegRfvza7YJ8FHbFNyDosrKJrMW93I,765
|
|
106
|
-
devsecops_engine_tools/engine_risk/src/domain/usecases/get_exclusions.py,sha256=
|
|
106
|
+
devsecops_engine_tools/engine_risk/src/domain/usecases/get_exclusions.py,sha256=1UNNq_Yhg3R78jLRSKcMNQYe8T8gl1C31C0ttBF0OAk,3992
|
|
107
107
|
devsecops_engine_tools/engine_risk/src/domain/usecases/handle_filters.py,sha256=R53fnuIQYfr7YbpMz1BGPJ1d5z9jY_Hnm7EmPt99wlE,3608
|
|
108
108
|
devsecops_engine_tools/engine_risk/src/infrastructure/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
109
109
|
devsecops_engine_tools/engine_risk/src/infrastructure/driven_adapters/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -207,7 +207,7 @@ devsecops_engine_tools/engine_sca/engine_container/src/domain/usecases/set_input
|
|
|
207
207
|
devsecops_engine_tools/engine_sca/engine_container/src/infrastructure/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
208
208
|
devsecops_engine_tools/engine_sca/engine_container/src/infrastructure/driven_adapters/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
209
209
|
devsecops_engine_tools/engine_sca/engine_container/src/infrastructure/driven_adapters/docker/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
210
|
-
devsecops_engine_tools/engine_sca/engine_container/src/infrastructure/driven_adapters/docker/docker_images.py,sha256=
|
|
210
|
+
devsecops_engine_tools/engine_sca/engine_container/src/infrastructure/driven_adapters/docker/docker_images.py,sha256=BjM10dlf27HWp4cI7xrhI7_50uBUsKx-XlUsaBWhXXQ,4617
|
|
211
211
|
devsecops_engine_tools/engine_sca/engine_container/src/infrastructure/driven_adapters/prisma_cloud/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
212
212
|
devsecops_engine_tools/engine_sca/engine_container/src/infrastructure/driven_adapters/prisma_cloud/prisma_cloud_manager_scan.py,sha256=tf33YFYB47th4Zu0WtWpsrAm5I6_xCON4yOwFacTQLA,6758
|
|
213
213
|
devsecops_engine_tools/engine_sca/engine_container/src/infrastructure/driven_adapters/prisma_cloud/prisma_deserialize_output.py,sha256=oK0NKuPODm38qDgQjf6w40lfNG6NFJS43p5k44wDoMA,2562
|
|
@@ -347,8 +347,8 @@ devsecops_engine_tools/engine_utilities/utils/name_conversion.py,sha256=ADJrRGax
|
|
|
347
347
|
devsecops_engine_tools/engine_utilities/utils/printers.py,sha256=amYAr9YQfYgR6jK9a2l26z3oovFPQ3FAKmhq6BKhEBA,623
|
|
348
348
|
devsecops_engine_tools/engine_utilities/utils/session_manager.py,sha256=Z0fdhB3r-dxU0nGSD9zW_B4r2Qol1rUnUCkhFR0U-HQ,487
|
|
349
349
|
devsecops_engine_tools/engine_utilities/utils/utils.py,sha256=XFap4yOK7ItLWsqbwDhvLd7NpDhs7i-UGJAMD6jjd7w,6687
|
|
350
|
-
devsecops_engine_tools-1.
|
|
351
|
-
devsecops_engine_tools-1.
|
|
352
|
-
devsecops_engine_tools-1.
|
|
353
|
-
devsecops_engine_tools-1.
|
|
354
|
-
devsecops_engine_tools-1.
|
|
350
|
+
devsecops_engine_tools-1.44.0.dist-info/METADATA,sha256=Zp1Pg2NcHomo3IzO2kFaC3pD3xXUMN2j8fU5knU7qKA,11779
|
|
351
|
+
devsecops_engine_tools-1.44.0.dist-info/WHEEL,sha256=R0nc6qTxuoLk7ShA2_Y-UWkN8ZdfDBG2B6Eqpz2WXbs,91
|
|
352
|
+
devsecops_engine_tools-1.44.0.dist-info/entry_points.txt,sha256=MHCTFFs9bdNKo6YcWCcBW2_8X6yTisgLOlmVx-V8Rxc,276
|
|
353
|
+
devsecops_engine_tools-1.44.0.dist-info/top_level.txt,sha256=ge6y0X_xBAU1aG3EMWFtl9djbVyg5BxuSp2r2Lg6EQU,23
|
|
354
|
+
devsecops_engine_tools-1.44.0.dist-info/RECORD,,
|
|
File without changes
|
{devsecops_engine_tools-1.43.0.dist-info → devsecops_engine_tools-1.44.0.dist-info}/entry_points.txt
RENAMED
|
File without changes
|
{devsecops_engine_tools-1.43.0.dist-info → devsecops_engine_tools-1.44.0.dist-info}/top_level.txt
RENAMED
|
File without changes
|