devsecops-engine-tools 1.40.1__py3-none-any.whl → 1.41.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.

@@ -26,6 +26,7 @@ class BreakBuild:
26
26
  report_list: "list[Report]",
27
27
  all_report: "list[Report]",
28
28
  threshold: any,
29
+ policy_excluded: int,
29
30
  ):
30
31
  self.devops_platform_gateway = devops_platform_gateway
31
32
  self.printer_table_gateway = printer_table_gateway
@@ -35,6 +36,7 @@ class BreakBuild:
35
36
  self.report_list = report_list
36
37
  self.all_report = all_report
37
38
  self.threshold = threshold
39
+ self.policy_excluded = policy_excluded
38
40
  self.break_build = False
39
41
  self.warning_build = False
40
42
  self.report_breaker = []
@@ -50,11 +52,9 @@ class BreakBuild:
50
52
  }
51
53
 
52
54
  def process(self):
53
- self._remediation_rate_control(self.all_report)
54
55
  new_report_list, applied_exclusions = self._apply_exclusions(self.report_list)
55
- if self.break_build:
56
- self.report_breaker.extend(copy.deepcopy(new_report_list))
57
56
  self._tag_blacklist_control(new_report_list)
57
+ self._remediation_rate_control(self.all_report, new_report_list)
58
58
  self._risk_score_control(new_report_list)
59
59
  all_exclusions = list(self.vm_exclusions) + list(applied_exclusions)
60
60
  self._print_exclusions(self._map_applied_exclusion(all_exclusions))
@@ -118,10 +118,19 @@ class BreakBuild:
118
118
  else:
119
119
  print(self.devops_platform_gateway.result_pipeline("succeeded"))
120
120
 
121
- def _remediation_rate_control(self, all_report: "list[Report]"):
121
+ def _remediation_rate_control(
122
+ self, all_report: "list[Report]", new_report_list: "list[Report]"
123
+ ):
122
124
  mitigated = sum(1 for report in all_report if report.mitigated)
123
- total = len(all_report)
124
- print(f"Mitigated count: {mitigated} Total count: {total}")
125
+ white_list = sum(
126
+ 1
127
+ for report in all_report
128
+ if "white_list" in report.tags and not report.mitigated
129
+ )
130
+ total = len(all_report) - self.policy_excluded - white_list
131
+ print(
132
+ f"Mitigated count: {mitigated} Total count: {len(all_report)} Policy excluded: {self.policy_excluded + white_list}"
133
+ )
125
134
  remediation_rate_value = self._get_percentage(mitigated / total)
126
135
 
127
136
  risk_threshold = self._get_remediation_rate_threshold(total)
@@ -150,10 +159,18 @@ class BreakBuild:
150
159
  )
151
160
  )
152
161
  self.break_build = True
162
+ [
163
+ setattr(report, "reason", "Remediation Rate")
164
+ for report in new_report_list
165
+ ]
166
+ self.report_breaker.extend(copy.deepcopy(new_report_list))
153
167
 
154
168
  def _get_remediation_rate_threshold(self, total):
155
169
  remediation_rate = self.threshold["REMEDIATION_RATE"]
156
- for key in sorted(remediation_rate.keys(), key=lambda x: int(x) if x.isdigit() else float('inf')):
170
+ for key in sorted(
171
+ remediation_rate.keys(),
172
+ key=lambda x: int(x) if x.isdigit() else float("inf"),
173
+ ):
157
174
  if key.isdigit() and total <= int(key):
158
175
  return remediation_rate[key]
159
176
  return remediation_rate["other"]
@@ -209,7 +226,6 @@ class BreakBuild:
209
226
  applied_exclusions.append(exclusion_copy)
210
227
  break
211
228
  if not exclude:
212
- report.reason = "Remediation Rate"
213
229
  filtered_reports.append(report)
214
230
 
215
231
  return filtered_reports, applied_exclusions
@@ -217,21 +233,22 @@ class BreakBuild:
217
233
  def _tag_blacklist_control(self, report_list: "list[Report]"):
218
234
  remote_config = self.remote_config
219
235
  if report_list:
220
- tag_blacklist = set(remote_config["TAG_BLACKLIST"])
221
- tag_age_threshold = self.threshold["TAG_MAX_AGE"]
236
+ tag_blacklist = set(remote_config["TAG_BLACKLIST_EXCLUSION_DAYS"].keys())
222
237
 
223
238
  filtered_reports_above_threshold = [
224
239
  (report, tag)
225
240
  for report in report_list
226
241
  for tag in report.tags
227
- if tag in tag_blacklist and report.age >= tag_age_threshold
242
+ if tag in tag_blacklist
243
+ and report.age >= remote_config["TAG_BLACKLIST_EXCLUSION_DAYS"][tag]
228
244
  ]
229
245
 
230
246
  filtered_reports_below_threshold = [
231
247
  (report, tag)
232
248
  for report in report_list
233
249
  for tag in report.tags
234
- if tag in tag_blacklist and report.age < tag_age_threshold
250
+ if tag in tag_blacklist
251
+ and report.age < remote_config["TAG_BLACKLIST_EXCLUSION_DAYS"][tag]
235
252
  ]
236
253
 
237
254
  for report, tag in filtered_reports_above_threshold:
@@ -239,7 +256,7 @@ class BreakBuild:
239
256
  print(
240
257
  self.devops_platform_gateway.message(
241
258
  "error",
242
- f"Report {report.vm_id} with tag {tag} is blacklisted and age {report.age} is above threshold {tag_age_threshold}",
259
+ f"Report {report.vm_id} with tag '{tag}' is blacklisted and age {report.age} is above threshold {remote_config['TAG_BLACKLIST_EXCLUSION_DAYS'][tag]}",
243
260
  )
244
261
  )
245
262
 
@@ -247,9 +264,10 @@ class BreakBuild:
247
264
  print(
248
265
  self.devops_platform_gateway.message(
249
266
  "warning",
250
- f"Report {report.vm_id} with tag {tag} is blacklisted but age {report.age} is below threshold {tag_age_threshold}",
267
+ f"Report {report.vm_id} with tag '{tag}' is blacklisted but age {report.age} is below threshold {remote_config['TAG_BLACKLIST_EXCLUSION_DAYS'][tag]}",
251
268
  )
252
269
  )
270
+ self.policy_excluded += 1
253
271
 
254
272
  if filtered_reports_above_threshold:
255
273
  self.break_build = True
@@ -1,6 +1,7 @@
1
1
  from devsecops_engine_tools.engine_core.src.domain.model.exclusions import (
2
2
  Exclusions,
3
3
  )
4
+ from datetime import datetime, timedelta
4
5
 
5
6
 
6
7
  class GetExclusions:
@@ -12,6 +13,7 @@ class GetExclusions:
12
13
  risk_config,
13
14
  risk_exclusions,
14
15
  services,
16
+ active_findings,
15
17
  ):
16
18
  self.devops_platform_gateway = devops_platform_gateway
17
19
  self.dict_args = dict_args
@@ -19,10 +21,13 @@ class GetExclusions:
19
21
  self.risk_config = risk_config
20
22
  self.risk_exclusions = risk_exclusions
21
23
  self.services = services
24
+ self.active_findings = active_findings
22
25
 
23
26
  def process(self):
24
27
  core_config = self.devops_platform_gateway.get_remote_config(
25
- self.dict_args["remote_config_repo"], "engine_core/ConfigTool.json", self.dict_args["remote_config_branch"]
28
+ self.dict_args["remote_config_repo"],
29
+ "engine_core/ConfigTool.json",
30
+ self.dict_args["remote_config_branch"],
26
31
  )
27
32
  unique_tags = self._get_unique_tags()
28
33
  exclusions = []
@@ -35,14 +40,19 @@ class GetExclusions:
35
40
  )
36
41
  )
37
42
 
38
- return exclusions
43
+ new_vuln_exclusions, len_new_vuln_exclusions = self._get_exclusions_new_vuln()
44
+ exclusions.extend(new_vuln_exclusions)
45
+
46
+ return exclusions, len_new_vuln_exclusions
39
47
 
40
48
  def _get_risk_exclusions(self):
41
49
  return self._get_exclusions(self.risk_exclusions, "RISK")
42
50
 
43
51
  def _get_exclusions_by_practice(self, core_config, practice, path):
44
52
  exclusions_config = self.devops_platform_gateway.get_remote_config(
45
- self.dict_args["remote_config_repo"], path, self.dict_args["remote_config_branch"]
53
+ self.dict_args["remote_config_repo"],
54
+ path,
55
+ self.dict_args["remote_config_branch"],
46
56
  )
47
57
  tool = core_config[practice.upper()]["TOOL"]
48
58
  return self._get_exclusions(exclusions_config, tool)
@@ -69,3 +79,26 @@ class GetExclusions:
69
79
  tags = finding.tags
70
80
  unique_tags.update(tags)
71
81
  return list(unique_tags)
82
+
83
+ def _get_exclusions_new_vuln(self):
84
+ cutoff_date = datetime.now() - timedelta(days=5)
85
+ exclusions = []
86
+ for finding in self.active_findings:
87
+ if finding.publish_date:
88
+ try:
89
+ finding_publish_date = datetime.strptime(
90
+ finding.publish_date, "%Y-%m-%d"
91
+ )
92
+ except ValueError:
93
+ continue
94
+ if finding_publish_date >= cutoff_date and hasattr(finding, "id"):
95
+ exclusion_data = finding.__dict__.copy()
96
+ exclusion_data["create_date"] = finding_publish_date.strftime(
97
+ "%d%m%Y"
98
+ )
99
+ exclusion_data["expired_date"] = (
100
+ finding_publish_date + timedelta(days=5)
101
+ ).strftime("%d%m%Y")
102
+ exclusion_data["reason"] = "New vulnerability in the industry"
103
+ exclusions.append(Exclusions(**exclusion_data))
104
+ return exclusions, len(exclusions)
@@ -49,11 +49,13 @@ class HandleFilters:
49
49
  def filter_tags_days(self, devops_platform_gateway, remote_config, findings):
50
50
  tag_exclusion_days = remote_config["TAG_EXCLUSION_DAYS"]
51
51
  filtered_findings = []
52
+ filtered = 0
52
53
 
53
54
  for finding in findings:
54
55
  exclude = False
55
56
  for tag in finding.tags:
56
57
  if tag in tag_exclusion_days and finding.age < tag_exclusion_days[tag]:
58
+ filtered += 1
57
59
  exclude = True
58
60
  print(
59
61
  devops_platform_gateway.message(
@@ -65,7 +67,7 @@ class HandleFilters:
65
67
  if not exclude:
66
68
  filtered_findings.append(finding)
67
69
 
68
- return filtered_findings
70
+ return filtered_findings, filtered
69
71
 
70
72
  def _get_active_findings(self, findings):
71
73
  return list(
@@ -31,10 +31,14 @@ def init_engine_risk(
31
31
  vm_exclusions,
32
32
  ):
33
33
  remote_config = devops_platform_gateway.get_remote_config(
34
- dict_args["remote_config_repo"], "engine_risk/ConfigTool.json", dict_args["remote_config_branch"]
34
+ dict_args["remote_config_repo"],
35
+ "engine_risk/ConfigTool.json",
36
+ dict_args["remote_config_branch"],
35
37
  )
36
38
  risk_exclusions = devops_platform_gateway.get_remote_config(
37
- dict_args["remote_config_repo"], "engine_risk/Exclusions.json", dict_args["remote_config_branch"]
39
+ dict_args["remote_config_repo"],
40
+ "engine_risk/Exclusions.json",
41
+ dict_args["remote_config_branch"],
38
42
  )
39
43
  pipeline_name = devops_platform_gateway.get_variable("pipeline_name")
40
44
 
@@ -49,7 +53,7 @@ def init_engine_risk(
49
53
 
50
54
  unique_findings = handle_filters.filter_duplicated(active_findings)
51
55
 
52
- filtered_findings = handle_filters.filter_tags_days(
56
+ filtered_findings, len_tag_filtered = handle_filters.filter_tags_days(
53
57
  devops_platform_gateway, remote_config, unique_findings
54
58
  )
55
59
 
@@ -62,8 +66,11 @@ def init_engine_risk(
62
66
  remote_config,
63
67
  risk_exclusions,
64
68
  services,
69
+ active_findings,
65
70
  )
66
- exclusions = get_exclusions.process()
71
+ exclusions, len_new_vuln = get_exclusions.process()
72
+
73
+ policy_excluded = len_tag_filtered + len_new_vuln
67
74
 
68
75
  threshold = CheckThreshold(
69
76
  pipeline_name, remote_config["THRESHOLD"], risk_exclusions
@@ -78,6 +85,7 @@ def init_engine_risk(
78
85
  data_added,
79
86
  findings,
80
87
  threshold,
88
+ policy_excluded,
81
89
  )
82
90
 
83
91
  return break_build.process()
@@ -77,7 +77,7 @@ class Finding(FromDictMixin):
77
77
  sast_source_line = None
78
78
  sast_source_file_path = None
79
79
  nb_occurences = None
80
- publish_date = None
80
+ publish_date: str = ""
81
81
  planned_remediation_date = None
82
82
  planned_remediation_version = None
83
83
  effort_for_fixing = None
@@ -1 +1 @@
1
- version = '1.40.1'
1
+ version = '1.41.0'
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: devsecops-engine-tools
3
- Version: 1.40.1
3
+ Version: 1.41.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
@@ -1,5 +1,5 @@
1
1
  devsecops_engine_tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- devsecops_engine_tools/version.py,sha256=CzOchPN3BP6JxBIpFBs1_bjOHUmWZIroALSUWXop0r4,19
2
+ devsecops_engine_tools/version.py,sha256=-B41LzxW9MaDd_gk-GaUDRhpW1fsMeynOvaN5fZXPV4,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,16 +101,16 @@ 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=qE9giBOR19rI7W084uE0OoPHpYGwKq0yRm4Tz6R10vw,12536
104
+ devsecops_engine_tools/engine_risk/src/domain/usecases/break_build.py,sha256=k24X9gipSiFQNp4V8guW4hCWUtCzxyKq-eo2FwGW2b8,13216
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=1ekBmLK36R3ddkQ40s8teAYvaldG8hnVsacXnWdkKrg,2460
107
- devsecops_engine_tools/engine_risk/src/domain/usecases/handle_filters.py,sha256=JmeBtO6CMufjYSRpGQU1kPZoW3PnXwVXnl33LSIU3n8,3543
106
+ devsecops_engine_tools/engine_risk/src/domain/usecases/get_exclusions.py,sha256=O6LoALXzQq0kB4TUuDdF1g5JUO0vtCeXF8txEkHYb6I,3850
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
110
110
  devsecops_engine_tools/engine_risk/src/infrastructure/driven_adapters/first_csv/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
111
111
  devsecops_engine_tools/engine_risk/src/infrastructure/driven_adapters/first_csv/first_epss_csv.py,sha256=pWaRmIwVyiB5mlmWySHIx-DUgN9vtKQc-MqyRNVlTJo,2150
112
112
  devsecops_engine_tools/engine_risk/src/infrastructure/entry_points/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
113
- devsecops_engine_tools/engine_risk/src/infrastructure/entry_points/entry_point_risk.py,sha256=tiXRqWcehAoFn-HrvteOKTYemwlfTJHCqIGYDGAk28Q,2459
113
+ devsecops_engine_tools/engine_risk/src/infrastructure/entry_points/entry_point_risk.py,sha256=3SIhdvy0_fEuN-w2_KNvwklo5mL3rCr5Zb2SV6HY77k,2630
114
114
  devsecops_engine_tools/engine_risk/src/infrastructure/helpers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
115
115
  devsecops_engine_tools/engine_sast/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
116
116
  devsecops_engine_tools/engine_sast/engine_code/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -267,7 +267,7 @@ devsecops_engine_tools/engine_utilities/defect_dojo/domain/models/__init__.py,sh
267
267
  devsecops_engine_tools/engine_utilities/defect_dojo/domain/models/cmdb.py,sha256=7EAzKzBJaDqP4Q57cyu_nCpl9WqcTZFjXydkYCh8h-k,320
268
268
  devsecops_engine_tools/engine_utilities/defect_dojo/domain/models/component.py,sha256=KYyWMUQcPsraqRaw0KY9eBaZPfajfBiskgOuwTI8mnA,483
269
269
  devsecops_engine_tools/engine_utilities/defect_dojo/domain/models/engagement.py,sha256=MXb7c526tz0zSDS8xGPC5IjTMF9g9qtzcEKLyfcY89c,1393
270
- devsecops_engine_tools/engine_utilities/defect_dojo/domain/models/finding.py,sha256=0Xj7BOlC30LCdBjIkviB2QmmdSj0GlDvT1-TbnaT8nE,3201
270
+ devsecops_engine_tools/engine_utilities/defect_dojo/domain/models/finding.py,sha256=fOlKeGPf9gMjz6RyRVWRyEZWxwm7XFE6eEQ5bIBmTBs,3204
271
271
  devsecops_engine_tools/engine_utilities/defect_dojo/domain/models/finding_exclusion.py,sha256=mz6RDW3Xk3VHNQcUHm9cCMAyX6Ultcb-IZy9N59qPI4,530
272
272
  devsecops_engine_tools/engine_utilities/defect_dojo/domain/models/product.py,sha256=KL5ue6icA8HH1xKkmAJzElAat3OOYU3_lt3xuNfo7Mc,1272
273
273
  devsecops_engine_tools/engine_utilities/defect_dojo/domain/models/product_list.py,sha256=yFo8eYOGJiJMkU5pGpW0r1o5uVaNP5iA80-5w_MyWxU,664
@@ -348,8 +348,8 @@ devsecops_engine_tools/engine_utilities/utils/name_conversion.py,sha256=ADJrRGax
348
348
  devsecops_engine_tools/engine_utilities/utils/printers.py,sha256=amYAr9YQfYgR6jK9a2l26z3oovFPQ3FAKmhq6BKhEBA,623
349
349
  devsecops_engine_tools/engine_utilities/utils/session_manager.py,sha256=Z0fdhB3r-dxU0nGSD9zW_B4r2Qol1rUnUCkhFR0U-HQ,487
350
350
  devsecops_engine_tools/engine_utilities/utils/utils.py,sha256=XFap4yOK7ItLWsqbwDhvLd7NpDhs7i-UGJAMD6jjd7w,6687
351
- devsecops_engine_tools-1.40.1.dist-info/METADATA,sha256=tW-9wImZKsHAxUSScW2dAyqQAzhc7bUS65oohhY1-6Y,11750
352
- devsecops_engine_tools-1.40.1.dist-info/WHEEL,sha256=R0nc6qTxuoLk7ShA2_Y-UWkN8ZdfDBG2B6Eqpz2WXbs,91
353
- devsecops_engine_tools-1.40.1.dist-info/entry_points.txt,sha256=MHCTFFs9bdNKo6YcWCcBW2_8X6yTisgLOlmVx-V8Rxc,276
354
- devsecops_engine_tools-1.40.1.dist-info/top_level.txt,sha256=ge6y0X_xBAU1aG3EMWFtl9djbVyg5BxuSp2r2Lg6EQU,23
355
- devsecops_engine_tools-1.40.1.dist-info/RECORD,,
351
+ devsecops_engine_tools-1.41.0.dist-info/METADATA,sha256=aYG37gdm8hbtdPKsGJpfQqcjO2rOldAfqfWhANIh5ps,11750
352
+ devsecops_engine_tools-1.41.0.dist-info/WHEEL,sha256=R0nc6qTxuoLk7ShA2_Y-UWkN8ZdfDBG2B6Eqpz2WXbs,91
353
+ devsecops_engine_tools-1.41.0.dist-info/entry_points.txt,sha256=MHCTFFs9bdNKo6YcWCcBW2_8X6yTisgLOlmVx-V8Rxc,276
354
+ devsecops_engine_tools-1.41.0.dist-info/top_level.txt,sha256=ge6y0X_xBAU1aG3EMWFtl9djbVyg5BxuSp2r2Lg6EQU,23
355
+ devsecops_engine_tools-1.41.0.dist-info/RECORD,,