devsecops-engine-tools 1.16.0__py3-none-any.whl → 1.17.1__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.

Files changed (20) hide show
  1. devsecops_engine_tools/engine_core/src/applications/runner_engine_core.py +1 -1
  2. devsecops_engine_tools/engine_core/src/domain/model/exclusions.py +4 -0
  3. devsecops_engine_tools/engine_core/src/domain/model/report.py +2 -0
  4. devsecops_engine_tools/engine_core/src/domain/usecases/handle_risk.py +54 -28
  5. devsecops_engine_tools/engine_core/src/infrastructure/driven_adapters/defect_dojo/defect_dojo.py +45 -12
  6. devsecops_engine_tools/engine_core/src/infrastructure/driven_adapters/printer_pretty_table/printer_pretty_table.py +66 -13
  7. devsecops_engine_tools/engine_core/src/infrastructure/driven_adapters/printer_rich_table/__init__.py +0 -0
  8. devsecops_engine_tools/engine_core/src/infrastructure/driven_adapters/printer_rich_table/printer_rich_table.py +86 -0
  9. devsecops_engine_tools/engine_risk/src/domain/usecases/break_build.py +20 -11
  10. devsecops_engine_tools/engine_risk/src/domain/usecases/handle_filters.py +63 -0
  11. devsecops_engine_tools/engine_risk/src/infrastructure/entry_points/entry_point_risk.py +9 -51
  12. devsecops_engine_tools/engine_sast/engine_secret/src/domain/model/DeserializeConfigTool.py +1 -0
  13. devsecops_engine_tools/engine_sast/engine_secret/src/infrastructure/driven_adapters/trufflehog/trufflehog_run.py +7 -5
  14. devsecops_engine_tools/engine_utilities/defect_dojo/domain/models/engagement.py +1 -0
  15. devsecops_engine_tools/version.py +1 -1
  16. {devsecops_engine_tools-1.16.0.dist-info → devsecops_engine_tools-1.17.1.dist-info}/METADATA +2 -1
  17. {devsecops_engine_tools-1.16.0.dist-info → devsecops_engine_tools-1.17.1.dist-info}/RECORD +20 -18
  18. {devsecops_engine_tools-1.16.0.dist-info → devsecops_engine_tools-1.17.1.dist-info}/WHEEL +0 -0
  19. {devsecops_engine_tools-1.16.0.dist-info → devsecops_engine_tools-1.17.1.dist-info}/entry_points.txt +0 -0
  20. {devsecops_engine_tools-1.16.0.dist-info → devsecops_engine_tools-1.17.1.dist-info}/top_level.txt +0 -0
@@ -191,8 +191,8 @@ def application_core():
191
191
  "github": GithubActions(),
192
192
  "local": RuntimeLocal(),
193
193
  }.get(args["platform_devops"])
194
- printer_table_gateway = PrinterPrettyTable()
195
194
  metrics_manager_gateway = S3Manager()
195
+ printer_table_gateway = PrinterPrettyTable()
196
196
 
197
197
  init_engine_core(
198
198
  vulnerability_management_gateway,
@@ -12,3 +12,7 @@ class Exclusions:
12
12
  self.severity = kwargs.get("severity", "")
13
13
  self.hu = kwargs.get("hu", "")
14
14
  self.reason = kwargs.get("reason", "Risk Accepted")
15
+ self.vm_id = kwargs.get("vm_id", "")
16
+ self.vm_id_url = kwargs.get("vm_id_url", "")
17
+ self.service = kwargs.get("service", "")
18
+ self.tags = kwargs.get("tags", [])
@@ -4,6 +4,8 @@ from dataclasses import dataclass
4
4
  @dataclass
5
5
  class Report:
6
6
  def __init__(self, **kwargs):
7
+ self.vm_id = kwargs.get("vm_id", "")
8
+ self.vm_id_url = kwargs.get("vm_id_url", "")
7
9
  self.id = kwargs.get("id", [])
8
10
  self.vuln_id_from_tool = kwargs.get("vuln_id_from_tool", "")
9
11
  self.where = kwargs.get("where", "")
@@ -51,7 +51,7 @@ class HandleRisk:
51
51
  "Error getting finding list in handle risk: {0}".format(str(e))
52
52
  )
53
53
 
54
- def _filter_engagements(self, engagements, service, risk_config):
54
+ def _filter_engagements(self, engagements, service, initial_services, risk_config):
55
55
  filtered_engagements = []
56
56
  min_word_length = risk_config["HANDLE_SERVICE_NAME"]["MIN_WORD_LENGTH"]
57
57
  words = [
@@ -65,20 +65,22 @@ class HandleRisk:
65
65
  min_word_amount = risk_config["HANDLE_SERVICE_NAME"]["MIN_WORD_AMOUNT"]
66
66
  endings = risk_config["HANDLE_SERVICE_NAME"]["CHECK_ENDING"]
67
67
 
68
+ initial_services_lower = [service.lower() for service in initial_services]
69
+
68
70
  for engagement in engagements:
69
- if service.lower() == engagement.name.lower():
70
- filtered_engagements += [engagement.name]
71
+ if engagement.name.lower() in initial_services_lower:
72
+ filtered_engagements += [engagement]
71
73
  elif re.search(check_words_regex, engagement.name.lower()) and (
72
74
  sum(1 for word in words if word.lower() in engagement.name.lower())
73
75
  >= min_word_amount
74
76
  ):
75
- filtered_engagements += [engagement.name]
77
+ filtered_engagements += [engagement]
76
78
  elif endings:
77
79
  if any(
78
80
  (service.lower() + ending.lower() == engagement.name.lower())
79
81
  for ending in endings
80
82
  ):
81
- filtered_engagements += [engagement.name]
83
+ filtered_engagements += [engagement]
82
84
 
83
85
  return filtered_engagements
84
86
 
@@ -94,15 +96,28 @@ class HandleRisk:
94
96
  services_to_exclude = set(
95
97
  risk_exclusions[pipeline_name]["SKIP_SERVICE"].get("services", [])
96
98
  )
97
- service_set = set(service_list)
98
-
99
- remaining_services = list(service_set - services_to_exclude)
100
- service_excluded = list(service_set & services_to_exclude)
101
99
 
102
- print(f"Services to exclude: {service_excluded}")
103
- logger.info(f"Services to exclude: {service_excluded}")
100
+ remaining_engagements = [
101
+ engagement
102
+ for engagement in service_list
103
+ if engagement.name.lower()
104
+ not in [service.lower() for service in services_to_exclude]
105
+ ]
106
+ excluded_engagements = [
107
+ engagement
108
+ for engagement in service_list
109
+ if engagement.name.lower()
110
+ in [service.lower() for service in services_to_exclude]
111
+ ]
112
+
113
+ print(
114
+ f"Services to exclude: {[engagement.name for engagement in excluded_engagements]}"
115
+ )
116
+ logger.info(
117
+ f"Services to exclude: {[engagement.name for engagement in excluded_engagements]}"
118
+ )
104
119
 
105
- return remaining_services
120
+ return remaining_engagements
106
121
  return service_list
107
122
 
108
123
  def _should_skip_analysis(self, remote_config, pipeline_name, exclusions):
@@ -141,6 +156,15 @@ class HandleRisk:
141
156
 
142
157
  service = pipeline_name
143
158
  service_list = []
159
+ initial_services = []
160
+ initial_services += [service]
161
+
162
+ match_parent = re.match(
163
+ risk_config["PARENT_ANALYSIS"]["REGEX_GET_PARENT"], service
164
+ )
165
+ if risk_config["PARENT_ANALYSIS"]["ENABLED"].lower() == "true" and match_parent:
166
+ parent_service = match_parent.group(0)
167
+ initial_services += [parent_service]
144
168
 
145
169
  if risk_config["HANDLE_SERVICE_NAME"]["ENABLED"].lower() == "true":
146
170
  service = next(
@@ -156,7 +180,7 @@ class HandleRisk:
156
180
  )
157
181
  if match_service_code:
158
182
  service_code = match_service_code.group(0)
159
- service_list += [
183
+ initial_services += [
160
184
  service.format(service_code=service_code)
161
185
  for service in risk_config["HANDLE_SERVICE_NAME"]["ADD_SERVICES"]
162
186
  ]
@@ -164,31 +188,33 @@ class HandleRisk:
164
188
  service_code, dict_args, secret_tool, remote_config
165
189
  )
166
190
  service_list += self._filter_engagements(
167
- engagements, service, risk_config
191
+ engagements, service, initial_services, risk_config
168
192
  )
193
+ else:
194
+ for service in initial_services:
195
+ engagements = self.vulnerability_management.get_active_engagements(
196
+ service, dict_args, secret_tool, remote_config
197
+ )
198
+ for engagement in engagements:
199
+ if engagement.name.lower() == service.lower():
200
+ service_list += [engagement]
201
+ break
169
202
 
170
- service_list += [service]
171
-
172
- match_parent = re.match(
173
- risk_config["PARENT_ANALYSIS"]["REGEX_GET_PARENT"], service
174
- )
175
- if risk_config["PARENT_ANALYSIS"]["ENABLED"].lower() == "true" and match_parent:
176
- parent_service = match_parent.group(0)
177
- service_list += [parent_service]
178
-
179
- service_list = list(set(service_list))
180
203
  new_service_list = self._exclude_services(
181
204
  dict_args, pipeline_name, service_list
182
205
  )
183
206
 
184
- print(f"Services to analyze: {new_service_list}")
185
- logger.info(f"Services to analyze: {new_service_list}")
207
+ for engagement in new_service_list:
208
+ print(f"Service to analyze: {engagement.name}, URL: {engagement.vm_url}")
209
+ logger.info(
210
+ f"Service to analyze: {engagement.name}, URL: {engagement.vm_url}"
211
+ )
186
212
 
187
213
  findings = []
188
214
  exclusions = []
189
215
  for service in new_service_list:
190
216
  findings_list, exclusions_list = self._get_all_from_vm(
191
- dict_args, secret_tool, remote_config, service
217
+ dict_args, secret_tool, remote_config, service.name
192
218
  )
193
219
  findings += findings_list
194
220
  exclusions += exclusions_list
@@ -197,7 +223,7 @@ class HandleRisk:
197
223
  dict_args,
198
224
  findings,
199
225
  exclusions,
200
- new_service_list,
226
+ [service.name for service in new_service_list],
201
227
  self.devops_platform_gateway,
202
228
  self.print_table_gateway,
203
229
  )
@@ -263,6 +263,7 @@ class DefectDojoPlatform(VulnerabilityManagementGateway):
263
263
  max_retries = config_tool["VULNERABILITY_MANAGER"]["DEFECT_DOJO"][
264
264
  "MAX_RETRIES_QUERY"
265
265
  ]
266
+ host_dd = config_tool["VULNERABILITY_MANAGER"]["DEFECT_DOJO"]["HOST_DEFECT_DOJO"]
266
267
 
267
268
  findings = self._get_findings(
268
269
  self._get_session_manager(dict_args, secret_tool, config_tool),
@@ -273,13 +274,13 @@ class DefectDojoPlatform(VulnerabilityManagementGateway):
273
274
 
274
275
  all_findings = list(
275
276
  map(
276
- partial(self._create_report),
277
+ partial(self._create_report, host_dd=host_dd),
277
278
  findings,
278
279
  )
279
280
  )
280
281
 
281
282
  all_exclusions = self._get_report_exclusions(
282
- all_findings, self._format_date_to_dd_format
283
+ all_findings, self._format_date_to_dd_format, host_dd=host_dd
283
284
  )
284
285
 
285
286
  return all_findings, all_exclusions
@@ -310,7 +311,14 @@ class DefectDojoPlatform(VulnerabilityManagementGateway):
310
311
  "active": "true",
311
312
  }
312
313
 
313
- return Engagement.get_engagements(request_is, request_active).results
314
+ engagements = Engagement.get_engagements(request_is, request_active).results
315
+
316
+ host_dd = config_tool["VULNERABILITY_MANAGER"]["DEFECT_DOJO"]["HOST_DEFECT_DOJO"]
317
+
318
+ for engagement in engagements:
319
+ engagement.vm_url = f"{host_dd}/engagement/{engagement.id}/finding/open"
320
+
321
+ return engagements
314
322
 
315
323
  except Exception as ex:
316
324
  raise ExceptionGettingEngagements(
@@ -326,25 +334,25 @@ class DefectDojoPlatform(VulnerabilityManagementGateway):
326
334
  config_tool["VULNERABILITY_MANAGER"]["DEFECT_DOJO"]["HOST_DEFECT_DOJO"],
327
335
  )
328
336
 
329
- def _get_report_exclusions(self, total_findings, date_fn):
337
+ def _get_report_exclusions(self, total_findings, date_fn, host_dd):
330
338
  exclusions = []
331
339
  for finding in total_findings:
332
340
  if finding.risk_accepted:
333
341
  exclusions.append(
334
- self._create_exclusion(
335
- finding, date_fn, "engine_risk", "Risk Accepted"
342
+ self._create_report_exclusion(
343
+ finding, date_fn, "engine_risk", "Risk Accepted", host_dd
336
344
  )
337
345
  )
338
346
  elif finding.false_p:
339
347
  exclusions.append(
340
- self._create_exclusion(
341
- finding, date_fn, "engine_risk", "False Positive"
348
+ self._create_report_exclusion(
349
+ finding, date_fn, "engine_risk", "False Positive", host_dd
342
350
  )
343
351
  )
344
352
  elif finding.risk_status == "Transfer Accepted":
345
353
  exclusions.append(
346
- self._create_exclusion(
347
- finding, date_fn, "engine_risk", "Transferred Finding"
354
+ self._create_report_exclusion(
355
+ finding, date_fn, "engine_risk", "Transferred Finding", host_dd
348
356
  )
349
357
  )
350
358
  return exclusions
@@ -381,7 +389,7 @@ class DefectDojoPlatform(VulnerabilityManagementGateway):
381
389
  logger.error("Maximum number of retries reached, aborting.")
382
390
  raise e
383
391
 
384
- def _create_exclusion(self, finding, date_fn, tool, reason):
392
+ def _date_reason_based(self, finding, date_fn, reason):
385
393
  if reason == "False Positive":
386
394
  create_date = date_fn(finding.last_status_update)
387
395
  expired_date = date_fn(None)
@@ -393,6 +401,24 @@ class DefectDojoPlatform(VulnerabilityManagementGateway):
393
401
  create_date = date_fn(last_accepted_risk["created"])
394
402
  expired_date = date_fn(last_accepted_risk["expiration_date"])
395
403
 
404
+ return create_date, expired_date
405
+
406
+
407
+ def _create_exclusion(self, finding, date_fn, tool, reason):
408
+ create_date, expired_date = self._date_reason_based(finding, date_fn, reason)
409
+
410
+ return Exclusions(
411
+ id=finding.vuln_id_from_tool,
412
+ where=self._get_where(finding, tool),
413
+ create_date=create_date,
414
+ expired_date=expired_date,
415
+ severity=finding.severity,
416
+ reason=reason,
417
+ )
418
+
419
+ def _create_report_exclusion(self, finding, date_fn, tool, reason, host_dd):
420
+ create_date, expired_date = self._date_reason_based(finding, date_fn, reason)
421
+
396
422
  return Exclusions(
397
423
  id=finding.vuln_id_from_tool,
398
424
  where=self._get_where(finding, tool),
@@ -400,10 +426,16 @@ class DefectDojoPlatform(VulnerabilityManagementGateway):
400
426
  expired_date=expired_date,
401
427
  severity=finding.severity,
402
428
  reason=reason,
429
+ vm_id=str(finding.vm_id),
430
+ vm_id_url=f"{host_dd}/finding/{finding.vm_id}",
431
+ service=finding.service,
432
+ tags=finding.tags,
403
433
  )
404
434
 
405
- def _create_report(self, finding):
435
+ def _create_report(self, finding, host_dd):
406
436
  return Report(
437
+ vm_id=str(finding.id),
438
+ vm_id_url=f"{host_dd}/finding/{finding.id}",
407
439
  id=finding.vulnerability_ids,
408
440
  vuln_id_from_tool=finding.vuln_id_from_tool,
409
441
  status=finding.display_status,
@@ -449,5 +481,6 @@ class DefectDojoPlatform(VulnerabilityManagementGateway):
449
481
  elif tool == "engine_risk":
450
482
  for tag in finding.tags:
451
483
  return self._get_where(finding, tag)
484
+ return finding.file_path
452
485
  else:
453
486
  return finding.file_path
@@ -10,7 +10,7 @@ from devsecops_engine_tools.engine_core.src.domain.model.report import (
10
10
  Report,
11
11
  )
12
12
  from devsecops_engine_tools.engine_core.src.infrastructure.helpers.util import (
13
- format_date
13
+ format_date,
14
14
  )
15
15
  from prettytable import PrettyTable, DOUBLE_BORDER
16
16
 
@@ -63,24 +63,20 @@ class PrinterPrettyTable(PrinterTableGateway):
63
63
  print(sorted_table)
64
64
 
65
65
  def print_table_report(self, report_list: "list[Report]"):
66
- headers = ["Risk Score", "Severity", "ID", "Tags", "Where", "Service"]
66
+ headers = ["Risk Score", "VM ID", "Services", "Tags"]
67
67
  table = PrettyTable(headers)
68
68
  for report in report_list:
69
69
  row_data = [
70
70
  report.risk_score,
71
- report.severity.lower(),
72
- report.vuln_id_from_tool if report.vuln_id_from_tool else report.id,
73
- report.tags,
74
- report.where,
75
- report.service
71
+ self._check_spaces(report.vm_id),
72
+ self._check_spaces(report.service),
73
+ ", ".join(report.tags),
76
74
  ]
77
75
  table.add_row(row_data)
78
76
 
79
77
  sorted_table = PrettyTable()
80
78
  sorted_table.field_names = table.field_names
81
- sorted_table.add_rows(
82
- sorted(table._rows, key=lambda row: row[0], reverse=True)
83
- )
79
+ sorted_table.add_rows(sorted(table._rows, key=lambda row: row[0], reverse=True))
84
80
 
85
81
  for column in table.field_names:
86
82
  sorted_table.align[column] = "l"
@@ -90,9 +86,52 @@ class PrinterPrettyTable(PrinterTableGateway):
90
86
  if len(sorted_table.rows) > 0:
91
87
  print(sorted_table)
92
88
 
89
+ def print_table_report_exlusions(self, exclusions):
90
+ if exclusions:
91
+ headers = [
92
+ "VM ID",
93
+ "Tags",
94
+ "Services",
95
+ "Created Date",
96
+ "Expired Date",
97
+ "Reason",
98
+ ]
99
+
100
+ table = PrettyTable(headers)
101
+
102
+ for exclusion in exclusions:
103
+ row_data = [
104
+ self._check_spaces(exclusion["vm_id"]),
105
+ ", ".join(exclusion["tags"]),
106
+ self._check_spaces(exclusion["service"]),
107
+ format_date(exclusion["create_date"], "%d%m%Y", "%d/%m/%Y"),
108
+ (
109
+ format_date(exclusion["expired_date"], "%d%m%Y", "%d/%m/%Y")
110
+ if exclusion["expired_date"]
111
+ and exclusion["expired_date"] != "undefined"
112
+ else "NA"
113
+ ),
114
+ exclusion["reason"],
115
+ ]
116
+ table.add_row(row_data)
117
+
118
+ for column in table.field_names:
119
+ table.align[column] = "l"
120
+
121
+ table.set_style(DOUBLE_BORDER)
122
+ if len(table.rows) > 0:
123
+ print(table)
124
+
93
125
  def print_table_exclusions(self, exclusions):
94
- if (exclusions):
95
- headers = ["Severity", "ID", "Where", "Create Date", "Expired Date", "Reason"]
126
+ if exclusions:
127
+ headers = [
128
+ "Severity",
129
+ "ID",
130
+ "Where",
131
+ "Create Date",
132
+ "Expired Date",
133
+ "Reason",
134
+ ]
96
135
 
97
136
  table = PrettyTable(headers)
98
137
 
@@ -102,7 +141,12 @@ class PrinterPrettyTable(PrinterTableGateway):
102
141
  exclusion["id"],
103
142
  exclusion["where"],
104
143
  format_date(exclusion["create_date"], "%d%m%Y", "%d/%m/%Y"),
105
- format_date(exclusion["expired_date"], "%d%m%Y", "%d/%m/%Y") if exclusion["expired_date"] and exclusion["expired_date"] != "undefined" else "NA",
144
+ (
145
+ format_date(exclusion["expired_date"], "%d%m%Y", "%d/%m/%Y")
146
+ if exclusion["expired_date"]
147
+ and exclusion["expired_date"] != "undefined"
148
+ else "NA"
149
+ ),
106
150
  exclusion["reason"],
107
151
  ]
108
152
  table.add_row(row_data)
@@ -113,3 +157,12 @@ class PrinterPrettyTable(PrinterTableGateway):
113
157
  table.set_style(DOUBLE_BORDER)
114
158
  if len(table.rows) > 0:
115
159
  print(table)
160
+
161
+ def _check_spaces(self, value):
162
+ values = value.split()
163
+ new_value = ""
164
+ if len(values) > 1:
165
+ new_value = "\n".join(values)
166
+ else:
167
+ new_value = f"{values[0]}"
168
+ return new_value
@@ -0,0 +1,86 @@
1
+ from dataclasses import dataclass
2
+
3
+ from devsecops_engine_tools.engine_core.src.domain.model.gateway.printer_table_gateway import (
4
+ PrinterTableGateway,
5
+ )
6
+ from devsecops_engine_tools.engine_core.src.domain.model.finding import (
7
+ Finding,
8
+ )
9
+ from devsecops_engine_tools.engine_core.src.domain.model.report import (
10
+ Report,
11
+ )
12
+ from devsecops_engine_tools.engine_core.src.infrastructure.helpers.util import (
13
+ format_date,
14
+ )
15
+ from rich.console import Console
16
+ from rich.table import Table
17
+ from rich import box
18
+
19
+
20
+ @dataclass
21
+ class PrinterRichTable(PrinterTableGateway):
22
+ def print_table_findings(self, finding_list: "list[Finding]"):
23
+ # To implement
24
+ return
25
+
26
+ def print_table_report(self, report_list: "list[Report]"):
27
+ sorted_report_list = sorted(
28
+ report_list, key=lambda report: report.risk_score, reverse=True
29
+ )
30
+ headers = ["Risk Score", "ID", "Tags", "Services"]
31
+ table = Table(
32
+ show_header=True, header_style="bold magenta", box=box.DOUBLE_EDGE
33
+ )
34
+ for header in headers:
35
+ table.add_column(header)
36
+ for report in sorted_report_list:
37
+ row_data = [
38
+ str(report.risk_score),
39
+ self._check_spaces(report.vm_id, report.vm_id_url),
40
+ ", ".join(report.tags),
41
+ report.service,
42
+ ]
43
+ table.add_row(*row_data)
44
+ console = Console()
45
+ console.print(table)
46
+
47
+ def print_table_exclusions(self, exclusions_list):
48
+ headers = []
49
+ if exclusions_list:
50
+ headers = ["ID", "Tags", "Service", "Create Date", "Expired Date", "Reason"]
51
+ table = Table(
52
+ show_header=True, header_style="bold magenta", box=box.DOUBLE_EDGE
53
+ )
54
+ for header in headers:
55
+ table.add_column(header)
56
+ for exclusion in exclusions_list:
57
+ row_data = [
58
+ self._check_spaces(exclusion["vm_id"], exclusion["vm_id_url"]),
59
+ ", ".join(exclusion["tags"]),
60
+ exclusion["service"],
61
+ format_date(exclusion["create_date"], "%d%m%Y", "%d/%m/%Y"),
62
+ (
63
+ format_date(exclusion["expired_date"], "%d%m%Y", "%d/%m/%Y")
64
+ if exclusion["expired_date"]
65
+ and exclusion["expired_date"] != "undefined"
66
+ else "NA"
67
+ ),
68
+ exclusion["reason"],
69
+ ]
70
+ table.add_row(*row_data)
71
+ console = Console()
72
+ console.print(table)
73
+
74
+ def _check_spaces(self, value, url):
75
+ values = value.split()
76
+ urls = url.split()
77
+ new_value = ""
78
+ if len(values) > 1 or len(urls) > 1:
79
+ for value, url in zip(values, urls):
80
+ new_value += self._make_hyperlink(value, url) + " "
81
+ else:
82
+ new_value = self._make_hyperlink(values[0], urls[0])
83
+ return new_value
84
+
85
+ def _make_hyperlink(self, value, url):
86
+ return f"[link={url}]{value}[/link]"
@@ -130,14 +130,14 @@ class BreakBuild:
130
130
  print(
131
131
  self.devops_platform_gateway.message(
132
132
  "succeeded",
133
- f"Remediation Rate {remediation_rate_value}% is greater than {risk_threshold}%",
133
+ f"Remediation rate {remediation_rate_value}% is greater than {risk_threshold}%",
134
134
  )
135
135
  )
136
136
  elif remediation_rate_value >= risk_threshold:
137
137
  print(
138
138
  self.devops_platform_gateway.message(
139
139
  "warning",
140
- f"Remediation Rate {remediation_rate_value}% is close to {risk_threshold}%",
140
+ f"Remediation rate {remediation_rate_value}% is close to {risk_threshold}%",
141
141
  )
142
142
  )
143
143
  self.warning_build = True
@@ -145,7 +145,7 @@ class BreakBuild:
145
145
  print(
146
146
  self.devops_platform_gateway.message(
147
147
  "error",
148
- f"Remediation Rate {remediation_rate_value}% is less than {risk_threshold}%",
148
+ f"Remediation rate {remediation_rate_value}% is less than {risk_threshold}%",
149
149
  )
150
150
  )
151
151
  self.break_build = True
@@ -162,6 +162,10 @@ class BreakBuild:
162
162
  "create_date": exclusion.create_date,
163
163
  "expired_date": exclusion.expired_date,
164
164
  "reason": exclusion.reason,
165
+ "vm_id": exclusion.vm_id,
166
+ "vm_id_url": exclusion.vm_id_url,
167
+ "service": exclusion.service,
168
+ "tags": exclusion.tags,
165
169
  }
166
170
  for exclusion in exclusions
167
171
  ]
@@ -179,9 +183,15 @@ class BreakBuild:
179
183
  and report.vuln_id_from_tool == exclusion.id
180
184
  )
181
185
  or (report.id and report.id == exclusion.id)
186
+ or (report.vm_id and exclusion.id in report.vm_id)
182
187
  ) and ((exclusion.where in report.where) or (exclusion.where == "all")):
183
188
  exclude = True
184
- applied_exclusions.append(exclusion)
189
+ exclusion_copy = copy.deepcopy(exclusion)
190
+ exclusion_copy.vm_id = report.vm_id
191
+ exclusion_copy.vm_id_url = report.vm_id_url
192
+ exclusion_copy.service = report.service
193
+ exclusion_copy.tags = report.tags
194
+ applied_exclusions.append(exclusion_copy)
185
195
  break
186
196
  if not exclude:
187
197
  report.reason = "Remediation Rate"
@@ -214,7 +224,7 @@ class BreakBuild:
214
224
  print(
215
225
  self.devops_platform_gateway.message(
216
226
  "error",
217
- f"Report {report.vuln_id_from_tool if report.vuln_id_from_tool else report.id} with tag {tag} is blacklisted and age {report.age} is above threshold {tag_age_threshold}",
227
+ f"Report {report.vm_id} with tag {tag} is blacklisted and age {report.age} is above threshold {tag_age_threshold}",
218
228
  )
219
229
  )
220
230
 
@@ -222,7 +232,7 @@ class BreakBuild:
222
232
  print(
223
233
  self.devops_platform_gateway.message(
224
234
  "warning",
225
- f"Report {report.vuln_id_from_tool if report.vuln_id_from_tool else report.id} with tag {tag} is blacklisted but age {report.age} is below threshold {tag_age_threshold}",
235
+ f"Report {report.vm_id} with tag {tag} is blacklisted but age {report.age} is below threshold {tag_age_threshold}",
226
236
  )
227
237
  )
228
238
 
@@ -258,9 +268,7 @@ class BreakBuild:
258
268
  break_build = True
259
269
  report.reason = "Risk Score"
260
270
  self.report_breaker.append(copy.deepcopy(report))
261
- print(
262
- "Below are open vulnerabilities from Vulnerability Management Platform"
263
- )
271
+ print("Below are open findings from Vulnerability Management Platform")
264
272
  self.printer_table_gateway.print_table_report(
265
273
  report_list,
266
274
  )
@@ -284,7 +292,8 @@ class BreakBuild:
284
292
  else:
285
293
  print(
286
294
  self.devops_platform_gateway.message(
287
- "succeeded", "There are no vulnerabilities"
295
+ "succeeded",
296
+ "There are no open findings from Vulnerability Management Platform",
288
297
  )
289
298
  )
290
299
 
@@ -295,7 +304,7 @@ class BreakBuild:
295
304
  "warning", "Bellow are all findings that were excepted"
296
305
  )
297
306
  )
298
- self.printer_table_gateway.print_table_exclusions(applied_exclusions)
307
+ self.printer_table_gateway.print_table_report_exlusions(applied_exclusions)
299
308
  for reason, total in Counter(
300
309
  map(lambda x: x["reason"], applied_exclusions)
301
310
  ).items():
@@ -1,9 +1,72 @@
1
+ import copy
2
+
3
+
1
4
  class HandleFilters:
2
5
  def filter(self, findings):
3
6
  active_findings = self._get_active_findings(findings)
4
7
  self._get_priority_vulnerability(active_findings)
5
8
  return active_findings
6
9
 
10
+ def filter_duplicated(self, findings):
11
+ unique_findings = []
12
+ findings_map = {}
13
+
14
+ for finding in findings:
15
+ key = (finding.where, tuple(finding.id), finding.vuln_id_from_tool)
16
+ if key in findings_map:
17
+ existing_finding = findings_map[key]
18
+ combined_services = existing_finding.service.split() + [
19
+ s
20
+ for s in finding.service.split()
21
+ if s not in existing_finding.service.split()
22
+ ]
23
+ combined_vm_ids = existing_finding.vm_id.split() + [
24
+ vm
25
+ for vm in finding.vm_id.split()
26
+ if vm not in existing_finding.vm_id.split()
27
+ ]
28
+ combined_vm_id_urls = existing_finding.vm_id_url.split() + [
29
+ vm_url
30
+ for vm_url in finding.vm_id_url.split()
31
+ if vm_url not in existing_finding.vm_id_url.split()
32
+ ]
33
+ if finding.age >= existing_finding.age:
34
+ new_finding = copy.deepcopy(finding)
35
+ new_finding.service = " ".join(combined_services)
36
+ new_finding.vm_id = " ".join(combined_vm_ids)
37
+ new_finding.vm_id_url = " ".join(combined_vm_id_urls)
38
+ findings_map[key] = new_finding
39
+ else:
40
+ existing_finding.service = " ".join(combined_services)
41
+ new_finding.vm_id = " ".join(combined_vm_ids)
42
+ new_finding.vm_id_url = " ".join(combined_vm_id_urls)
43
+ else:
44
+ findings_map[key] = copy.deepcopy(finding)
45
+
46
+ unique_findings = list(findings_map.values())
47
+ return unique_findings
48
+
49
+ def filter_tags_days(self, devops_platform_gateway, remote_config, findings):
50
+ tag_exclusion_days = remote_config["TAG_EXCLUSION_DAYS"]
51
+ filtered_findings = []
52
+
53
+ for finding in findings:
54
+ exclude = False
55
+ for tag in finding.tags:
56
+ if tag in tag_exclusion_days and finding.age < tag_exclusion_days[tag]:
57
+ exclude = True
58
+ print(
59
+ devops_platform_gateway.message(
60
+ "warning",
61
+ f"Report {finding.vm_id} with tag '{tag}' and age {finding.age} days is being excluded. It will be considered in {tag_exclusion_days[tag] - finding.age} days.",
62
+ )
63
+ )
64
+ break
65
+ if not exclude:
66
+ filtered_findings.append(finding)
67
+
68
+ return filtered_findings
69
+
7
70
  def _get_active_findings(self, findings):
8
71
  return list(
9
72
  filter(
@@ -12,8 +12,6 @@ from devsecops_engine_tools.engine_risk.src.domain.usecases.get_exclusions impor
12
12
  )
13
13
 
14
14
 
15
- import re
16
-
17
15
  from devsecops_engine_tools.engine_utilities.utils.logger_info import MyLogger
18
16
  from devsecops_engine_tools.engine_utilities import settings
19
17
 
@@ -36,30 +34,6 @@ def init_engine_risk(
36
34
  dict_args["remote_config_repo"], "engine_risk/Exclusions.json"
37
35
  )
38
36
 
39
- return process_findings(
40
- findings,
41
- vm_exclusions,
42
- dict_args,
43
- services,
44
- risk_exclusions,
45
- remote_config,
46
- add_epss_gateway,
47
- devops_platform_gateway,
48
- print_table_gateway,
49
- )
50
-
51
-
52
- def process_findings(
53
- findings,
54
- vm_exclusions,
55
- dict_args,
56
- services,
57
- risk_exclusions,
58
- remote_config,
59
- add_epss_gateway,
60
- devops_platform_gateway,
61
- print_table_gateway,
62
- ):
63
37
  if not findings:
64
38
  print("No findings found in Vulnerability Management Platform")
65
39
  logger.info("No findings found in Vulnerability Management Platform")
@@ -67,33 +41,16 @@ def process_findings(
67
41
 
68
42
  handle_filters = HandleFilters()
69
43
 
70
- return process_active_findings(
71
- handle_filters.filter(findings),
72
- findings,
73
- vm_exclusions,
74
- devops_platform_gateway,
75
- dict_args,
76
- remote_config,
77
- risk_exclusions,
78
- services,
79
- add_epss_gateway,
80
- print_table_gateway,
44
+ active_findings = handle_filters.filter(findings)
45
+
46
+ unique_findings = handle_filters.filter_duplicated(active_findings)
47
+
48
+ filtered_findings = handle_filters.filter_tags_days(
49
+ devops_platform_gateway, remote_config, unique_findings
81
50
  )
82
51
 
52
+ data_added = AddData(add_epss_gateway, filtered_findings).process()
83
53
 
84
- def process_active_findings(
85
- active_findings,
86
- total_findings,
87
- vm_exclusions,
88
- devops_platform_gateway,
89
- dict_args,
90
- remote_config,
91
- risk_exclusions,
92
- services,
93
- add_epss_gateway,
94
- print_table_gateway,
95
- ):
96
- data_added = AddData(add_epss_gateway, active_findings).process()
97
54
  get_exclusions = GetExclusions(
98
55
  devops_platform_gateway,
99
56
  dict_args,
@@ -103,6 +60,7 @@ def process_active_findings(
103
60
  services,
104
61
  )
105
62
  exclusions = get_exclusions.process()
63
+
106
64
  break_build = BreakBuild(
107
65
  devops_platform_gateway,
108
66
  print_table_gateway,
@@ -110,7 +68,7 @@ def process_active_findings(
110
68
  exclusions,
111
69
  vm_exclusions,
112
70
  data_added,
113
- total_findings,
71
+ findings,
114
72
  )
115
73
 
116
74
  return break_build.process()
@@ -13,3 +13,4 @@ class DeserializeConfigTool:
13
13
  self.external_dir_owner = json_data[tool]["EXTERNAL_DIR_OWNER"]
14
14
  self.external_dir_repo = json_data[tool]["EXTERNAL_DIR_REPOSITORY"]
15
15
  self.tool_version = json_data[tool]["VERSION"]
16
+ self.extradata_rules = json_data[tool]["RULES"]
@@ -94,7 +94,7 @@ class TrufflehogRun(ToolGateway):
94
94
  [repository_name] * len(include_paths),
95
95
  [enable_custom_rules] * len(include_paths),
96
96
  )
97
- findings, file_findings = self.create_file(self.decode_output(results), agent_work_folder)
97
+ findings, file_findings = self.create_file(self.decode_output(results), agent_work_folder, config_tool)
98
98
  return findings, file_findings
99
99
 
100
100
  def config_include_path(self, files, agent_work_folder, agent_os):
@@ -128,8 +128,8 @@ class TrufflehogRun(ToolGateway):
128
128
  ):
129
129
  command = f"{trufflehog_command} filesystem {agent_work_folder + '/' + repository_name} --include-paths {include_path} --exclude-paths {exclude_path} --no-verification --no-update --json"
130
130
 
131
- if enable_custom_rules == "true":
132
- command = command.replace("--no-verification --json", "--config /tmp/rules/trufflehog/custom-rules.yaml --no-verification --no-update --json")
131
+ if str(enable_custom_rules).lower() == "true":
132
+ command = command.replace("--no-verification --no-update --json", "--config /tmp/rules/trufflehog/custom-rules.yaml --no-verification --no-update --json")
133
133
 
134
134
  result = subprocess.run(command, capture_output=True, shell=True, text=True, encoding='utf-8')
135
135
  return result.stdout.strip()
@@ -144,7 +144,7 @@ class TrufflehogRun(ToolGateway):
144
144
  result.append(json_obj)
145
145
  return result
146
146
 
147
- def create_file(self, findings, agent_work_folder):
147
+ def create_file(self, findings, agent_work_folder, config_tool):
148
148
  file_findings = os.path.join(agent_work_folder, "secret_scan_result.json")
149
149
  with open(file_findings, "w") as file:
150
150
  for find in findings:
@@ -152,7 +152,9 @@ class TrufflehogRun(ToolGateway):
152
152
  original_where = original_where.replace("\\", "/")
153
153
  where_text = original_where.replace(agent_work_folder, "")
154
154
  find["SourceMetadata"]["Data"]["Filesystem"]["file"] = where_text
155
- find["Id"] = "MISSCONFIGURATION_SCANNING" if "exposure" in find["Raw"] else "SECRET_SCANNING"
155
+ find["Id"] = "MISCONFIGURATION_SCANNING" if "exposure" in find["Raw"] else "SECRET_SCANNING"
156
+ find["References"] = config_tool.extradata_rules[find["Id"]]["References"] if "SECRET_SCANNING" not in find["Id"] else "N.A"
157
+ find["Mitigation"] = config_tool.extradata_rules[find["Id"]]["Mitigation"] if "SECRET_SCANNING" not in find["Id"] else "N.A"
156
158
  json_str = json.dumps(find)
157
159
  file.write(json_str + '\n')
158
160
  return findings, file_findings
@@ -41,6 +41,7 @@ class Engagement(FromDictMixin):
41
41
  build_server: str = ""
42
42
  source_code_management_server: str = ""
43
43
  orchestration_engine: str = ""
44
+ vm_url: str = ""
44
45
  notes = []
45
46
  files = []
46
47
  risk_acceptance = []
@@ -1 +1 @@
1
- version = '1.16.0'
1
+ version = '1.17.1'
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: devsecops-engine-tools
3
- Version: 1.16.0
3
+ Version: 1.17.1
4
4
  Summary: Tool for DevSecOps strategy
5
5
  Home-page: https://github.com/bancolombia/devsecops-engine-tools
6
6
  Author: Bancolombia DevSecOps Team
@@ -25,6 +25,7 @@ Requires-Dist: distro==1.9.0
25
25
  Requires-Dist: boto3==1.34.157
26
26
  Requires-Dist: docker==7.1.0
27
27
  Requires-Dist: setuptools==72.1.0
28
+ Requires-Dist: rich==13.9.4
28
29
 
29
30
  # DevSecOps Engine Tools
30
31
 
@@ -1,20 +1,20 @@
1
1
  devsecops_engine_tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- devsecops_engine_tools/version.py,sha256=tT_8ISLXFdCq-Rgso5Q9lk3Q5eDlHoUO7dbUcqFExA0,19
2
+ devsecops_engine_tools/version.py,sha256=0sNIVdGl6teHLyJfh55ulmHcFArD6sztXiZevppt-Do,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
6
- devsecops_engine_tools/engine_core/src/applications/runner_engine_core.py,sha256=9QaRFl_QYXSLxK_Qo5B84Jyeq7iZP9WeLc2ioSdkLOc,7209
6
+ devsecops_engine_tools/engine_core/src/applications/runner_engine_core.py,sha256=3IvzG7IfQFs8gxsv4Xo5722hV3jG6g0g4JWFq74i2iM,7209
7
7
  devsecops_engine_tools/engine_core/src/deployment/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
8
  devsecops_engine_tools/engine_core/src/deployment/infrastructure/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
9
9
  devsecops_engine_tools/engine_core/src/domain/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10
10
  devsecops_engine_tools/engine_core/src/domain/model/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
11
11
  devsecops_engine_tools/engine_core/src/domain/model/customs_exceptions.py,sha256=YLeOj4O7kNsUx8RD6pwBQdFLYbkm7Eh-F-ohZ3jFGbs,599
12
- devsecops_engine_tools/engine_core/src/domain/model/exclusions.py,sha256=rFinY7wQsIu4nNPdT9WlvzB-1S1tS3J3oQgb8tDxbZk,499
12
+ devsecops_engine_tools/engine_core/src/domain/model/exclusions.py,sha256=W9DXUWI7rGJWRHEulnUY5ybdJK2wknG4zY7CbTtSyfc,689
13
13
  devsecops_engine_tools/engine_core/src/domain/model/finding.py,sha256=MntDksQuPt1L-1Ww3nK7NbMLfVwRjxPGCN_oHYXbbWk,383
14
14
  devsecops_engine_tools/engine_core/src/domain/model/input_core.py,sha256=hc1WMzCwsGxnrlvvk84S5iNYJRDQWbaQP9MwR3N7tVM,422
15
15
  devsecops_engine_tools/engine_core/src/domain/model/level_compliance.py,sha256=ntn_UWqHc6sT5g_LozBdjdewTQxFsp7Kt8M0xqw-k_o,98
16
16
  devsecops_engine_tools/engine_core/src/domain/model/level_vulnerability.py,sha256=0sySEnFNkS2Y8uF5GUVAYehXw-i2OglUClkVobnSTPc,257
17
- devsecops_engine_tools/engine_core/src/domain/model/report.py,sha256=Lsp7CuAdhW8kJkbP6VyHJmFb5rPhxY_u_mEOLHzbD8Y,1772
17
+ devsecops_engine_tools/engine_core/src/domain/model/report.py,sha256=6ByyjXmUbowWbZIkn3qfL-QyhkyCDzdTCdRj-I7wTXA,1870
18
18
  devsecops_engine_tools/engine_core/src/domain/model/threshold.py,sha256=TCBECuvoC3-9g8vg3iKWGIixssNecP0iUaZ9Qzv0n7w,596
19
19
  devsecops_engine_tools/engine_core/src/domain/model/vulnerability_management.py,sha256=5RcMHpeqznrTOpkjLuqekA_Bqf2Qr-w6OZ5Eoi3b-bs,465
20
20
  devsecops_engine_tools/engine_core/src/domain/model/gateway/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -25,7 +25,7 @@ devsecops_engine_tools/engine_core/src/domain/model/gateway/secrets_manager_gate
25
25
  devsecops_engine_tools/engine_core/src/domain/model/gateway/vulnerability_management_gateway.py,sha256=dT2YDlWJ4Zvny_5uCTtxBojw4i77UOgGbs8p2jlRo74,1137
26
26
  devsecops_engine_tools/engine_core/src/domain/usecases/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
27
27
  devsecops_engine_tools/engine_core/src/domain/usecases/break_build.py,sha256=0JK4U5LGxzrLVZOw68j1PMxmLTDPru7Kts_-RtAG0jA,15965
28
- devsecops_engine_tools/engine_core/src/domain/usecases/handle_risk.py,sha256=1vctNN5aSPGsSgrldPiYg2Fq86q6Z9DzFdazjWAm2Do,8133
28
+ devsecops_engine_tools/engine_core/src/domain/usecases/handle_risk.py,sha256=9Qhh1n8rUCYugEMJ72Mlk3R9SH_wYEbLdGlA6NetBrQ,9269
29
29
  devsecops_engine_tools/engine_core/src/domain/usecases/handle_scan.py,sha256=Li0NDwHwj_g2iM4tKF3wyKqXWYXspTThzKxkSma3S6E,8912
30
30
  devsecops_engine_tools/engine_core/src/domain/usecases/metrics_manager.py,sha256=Xi0iNnPrFgqd2cBdAA5E_tgouhxs-BTo016aolnGgv8,2413
31
31
  devsecops_engine_tools/engine_core/src/infrastructure/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -36,11 +36,13 @@ devsecops_engine_tools/engine_core/src/infrastructure/driven_adapters/aws/secret
36
36
  devsecops_engine_tools/engine_core/src/infrastructure/driven_adapters/azure/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
37
37
  devsecops_engine_tools/engine_core/src/infrastructure/driven_adapters/azure/azure_devops.py,sha256=blI4ZrquRE4y6DJ7N2YRx1nL0wrAXvdpx0fLSUf5qwA,4831
38
38
  devsecops_engine_tools/engine_core/src/infrastructure/driven_adapters/defect_dojo/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
39
- devsecops_engine_tools/engine_core/src/infrastructure/driven_adapters/defect_dojo/defect_dojo.py,sha256=XKM107OQZ75sb1oeOqJKintyRAR9q8k1fkoe2sm7nBo,18190
39
+ devsecops_engine_tools/engine_core/src/infrastructure/driven_adapters/defect_dojo/defect_dojo.py,sha256=A_xCCj7Gs5-LAJY8bs1p_nViTI_sdtegmO3_cdPjh-Q,19580
40
40
  devsecops_engine_tools/engine_core/src/infrastructure/driven_adapters/github/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
41
41
  devsecops_engine_tools/engine_core/src/infrastructure/driven_adapters/github/github_actions.py,sha256=pxlgjhX4-Dssn-XHKK8AdCOj6Ry6VcQtoDf5q8CxTks,3731
42
42
  devsecops_engine_tools/engine_core/src/infrastructure/driven_adapters/printer_pretty_table/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
43
- devsecops_engine_tools/engine_core/src/infrastructure/driven_adapters/printer_pretty_table/printer_pretty_table.py,sha256=oEhsYOS5dmTtNOzpWNurWgLxth6vBhWVvVlKul9Heys,3884
43
+ devsecops_engine_tools/engine_core/src/infrastructure/driven_adapters/printer_pretty_table/printer_pretty_table.py,sha256=P0oavy_3AMbuRx5kPPiM2_LopVXqHK4Hz4Lb2UNfr-4,5369
44
+ devsecops_engine_tools/engine_core/src/infrastructure/driven_adapters/printer_rich_table/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
45
+ devsecops_engine_tools/engine_core/src/infrastructure/driven_adapters/printer_rich_table/printer_rich_table.py,sha256=LPr3xSv0I7ENEdu1xj8ve5PXzpUohs7hbQvHjDSaUuE,3028
44
46
  devsecops_engine_tools/engine_core/src/infrastructure/driven_adapters/runtime_local/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
45
47
  devsecops_engine_tools/engine_core/src/infrastructure/driven_adapters/runtime_local/runtime_local.py,sha256=qKINENZGbfV8XFF7fzUK6grQ5Jx7Nwv9xOqjjKlXp3o,2475
46
48
  devsecops_engine_tools/engine_core/src/infrastructure/entry_points/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -72,15 +74,15 @@ devsecops_engine_tools/engine_risk/src/domain/model/gateways/__init__.py,sha256=
72
74
  devsecops_engine_tools/engine_risk/src/domain/model/gateways/add_epss_gateway.py,sha256=cTm4QSxiaUt7ETCdXWZxKEus8pmEDA3e9k5b39SLDDE,178
73
75
  devsecops_engine_tools/engine_risk/src/domain/usecases/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
74
76
  devsecops_engine_tools/engine_risk/src/domain/usecases/add_data.py,sha256=4wqDj-q7hJfJscvrbMDcy7tONqxdxl-CSl_TWTRUGKA,402
75
- devsecops_engine_tools/engine_risk/src/domain/usecases/break_build.py,sha256=sYcsReL3FF_9_NTEcK-sFCFHK5Hi9zJrMpD4cDLAX4w,11380
77
+ devsecops_engine_tools/engine_risk/src/domain/usecases/break_build.py,sha256=TSZTXR8raKA1906dFl-Cv3J711iGUcBQmx82Jw6mF_M,11847
76
78
  devsecops_engine_tools/engine_risk/src/domain/usecases/get_exclusions.py,sha256=o4vMpmgt5q1BsaWpGZWdCHPVs1CFyj-P3TrgOSEBcqM,2327
77
- devsecops_engine_tools/engine_risk/src/domain/usecases/handle_filters.py,sha256=w18CVVSs0mkfLYo7f-wZJv1afoPWzEU-IBKUzk7LMYI,832
79
+ devsecops_engine_tools/engine_risk/src/domain/usecases/handle_filters.py,sha256=1yJKPzh64gu67g_pLyr7V8Ahzs3KK8tncigPzKWMX7Q,3533
78
80
  devsecops_engine_tools/engine_risk/src/infrastructure/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
79
81
  devsecops_engine_tools/engine_risk/src/infrastructure/driven_adapters/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
80
82
  devsecops_engine_tools/engine_risk/src/infrastructure/driven_adapters/first_csv/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
81
83
  devsecops_engine_tools/engine_risk/src/infrastructure/driven_adapters/first_csv/first_epss_csv.py,sha256=pWaRmIwVyiB5mlmWySHIx-DUgN9vtKQc-MqyRNVlTJo,2150
82
84
  devsecops_engine_tools/engine_risk/src/infrastructure/entry_points/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
83
- devsecops_engine_tools/engine_risk/src/infrastructure/entry_points/entry_point_risk.py,sha256=URwX6I8Rihhy8x-bUR1XsZ_S3jZT61WdIkGMjPJN0ZA,2820
85
+ devsecops_engine_tools/engine_risk/src/infrastructure/entry_points/entry_point_risk.py,sha256=DQe1yUd5p83zecH53jKrsnS-JV2ZaN7YvdtQLwzEx0A,2073
84
86
  devsecops_engine_tools/engine_risk/src/infrastructure/helpers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
85
87
  devsecops_engine_tools/engine_sast/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
86
88
  devsecops_engine_tools/engine_sast/engine_code/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -140,7 +142,7 @@ devsecops_engine_tools/engine_sast/engine_secret/src/applications/runner_secret_
140
142
  devsecops_engine_tools/engine_sast/engine_secret/src/deployment/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
141
143
  devsecops_engine_tools/engine_sast/engine_secret/src/deployment/infrastructure/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
142
144
  devsecops_engine_tools/engine_sast/engine_secret/src/domain/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
143
- devsecops_engine_tools/engine_sast/engine_secret/src/domain/model/DeserializeConfigTool.py,sha256=2YXBnWA3DGiEKNpRMgVk2CmgOFfJPzDbgexXHjJpaBU,884
145
+ devsecops_engine_tools/engine_sast/engine_secret/src/domain/model/DeserializeConfigTool.py,sha256=vwV7OoH943fQvwSgoKqLnnB8XcuMwQsebrIXvQIgiTs,941
144
146
  devsecops_engine_tools/engine_sast/engine_secret/src/domain/model/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
145
147
  devsecops_engine_tools/engine_sast/engine_secret/src/domain/model/gateway/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
146
148
  devsecops_engine_tools/engine_sast/engine_secret/src/domain/model/gateway/gateway_deserealizator.py,sha256=4fYPengHW3K0uVP6wHgOiNu-gRb08m78E7QZayZ2LC4,441
@@ -152,7 +154,7 @@ devsecops_engine_tools/engine_sast/engine_secret/src/infrastructure/__init__.py,
152
154
  devsecops_engine_tools/engine_sast/engine_secret/src/infrastructure/driven_adapters/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
153
155
  devsecops_engine_tools/engine_sast/engine_secret/src/infrastructure/driven_adapters/trufflehog/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
154
156
  devsecops_engine_tools/engine_sast/engine_secret/src/infrastructure/driven_adapters/trufflehog/trufflehog_deserealizator.py,sha256=mrSqPrkMiikxQ_uY-rF2I8QvicsOMdMBzTC8CTV3Wk8,2392
155
- devsecops_engine_tools/engine_sast/engine_secret/src/infrastructure/driven_adapters/trufflehog/trufflehog_run.py,sha256=Q8KKDu-rFBxmsMnqRRtYMhO3u6e3Uumj61msKQDHVLs,8196
157
+ devsecops_engine_tools/engine_sast/engine_secret/src/infrastructure/driven_adapters/trufflehog/trufflehog_run.py,sha256=GcO8r_LjIjhPlyiUujAM23AK2ks1xl6hy3owyNXk5WI,8530
156
158
  devsecops_engine_tools/engine_sast/engine_secret/src/infrastructure/entry_points/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
157
159
  devsecops_engine_tools/engine_sast/engine_secret/src/infrastructure/entry_points/entry_point_tool.py,sha256=NiA5-pRL6-tMuOa2Al-wIYq3uIMFBQrJd0w7ur16kgs,1049
158
160
  devsecops_engine_tools/engine_sca/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -231,7 +233,7 @@ devsecops_engine_tools/engine_utilities/defect_dojo/applications/product.py,sha2
231
233
  devsecops_engine_tools/engine_utilities/defect_dojo/domain/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
232
234
  devsecops_engine_tools/engine_utilities/defect_dojo/domain/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
233
235
  devsecops_engine_tools/engine_utilities/defect_dojo/domain/models/cmdb.py,sha256=7EAzKzBJaDqP4Q57cyu_nCpl9WqcTZFjXydkYCh8h-k,320
234
- devsecops_engine_tools/engine_utilities/defect_dojo/domain/models/engagement.py,sha256=x0mkWoLv8rRHZTh7hhI1aZb2g9XFJ-Gz_gC-f-rZdWM,1372
236
+ devsecops_engine_tools/engine_utilities/defect_dojo/domain/models/engagement.py,sha256=MXb7c526tz0zSDS8xGPC5IjTMF9g9qtzcEKLyfcY89c,1393
235
237
  devsecops_engine_tools/engine_utilities/defect_dojo/domain/models/finding.py,sha256=0Xj7BOlC30LCdBjIkviB2QmmdSj0GlDvT1-TbnaT8nE,3201
236
238
  devsecops_engine_tools/engine_utilities/defect_dojo/domain/models/product.py,sha256=KL5ue6icA8HH1xKkmAJzElAat3OOYU3_lt3xuNfo7Mc,1272
237
239
  devsecops_engine_tools/engine_utilities/defect_dojo/domain/models/product_list.py,sha256=yFo8eYOGJiJMkU5pGpW0r1o5uVaNP5iA80-5w_MyWxU,664
@@ -305,8 +307,8 @@ devsecops_engine_tools/engine_utilities/utils/name_conversion.py,sha256=ADJrRGax
305
307
  devsecops_engine_tools/engine_utilities/utils/printers.py,sha256=amYAr9YQfYgR6jK9a2l26z3oovFPQ3FAKmhq6BKhEBA,623
306
308
  devsecops_engine_tools/engine_utilities/utils/session_manager.py,sha256=yNtlT-8Legz1sHbGPH8LNYjL-LgDUE0zXG2rYjiab7U,290
307
309
  devsecops_engine_tools/engine_utilities/utils/utils.py,sha256=r_mng-OVWeqQyy6yIFsCeJrvH81VUPI3o1zdJO0JS0I,397
308
- devsecops_engine_tools-1.16.0.dist-info/METADATA,sha256=YXRISLfqURRXsKhLnN19CzANuAERAVKU_tNuUoCBoF4,10867
309
- devsecops_engine_tools-1.16.0.dist-info/WHEEL,sha256=R0nc6qTxuoLk7ShA2_Y-UWkN8ZdfDBG2B6Eqpz2WXbs,91
310
- devsecops_engine_tools-1.16.0.dist-info/entry_points.txt,sha256=MHCTFFs9bdNKo6YcWCcBW2_8X6yTisgLOlmVx-V8Rxc,276
311
- devsecops_engine_tools-1.16.0.dist-info/top_level.txt,sha256=ge6y0X_xBAU1aG3EMWFtl9djbVyg5BxuSp2r2Lg6EQU,23
312
- devsecops_engine_tools-1.16.0.dist-info/RECORD,,
310
+ devsecops_engine_tools-1.17.1.dist-info/METADATA,sha256=AsMazqyFZJ1BF1l_CRjCRmIKMMITk17008LevuRWAy4,10895
311
+ devsecops_engine_tools-1.17.1.dist-info/WHEEL,sha256=R0nc6qTxuoLk7ShA2_Y-UWkN8ZdfDBG2B6Eqpz2WXbs,91
312
+ devsecops_engine_tools-1.17.1.dist-info/entry_points.txt,sha256=MHCTFFs9bdNKo6YcWCcBW2_8X6yTisgLOlmVx-V8Rxc,276
313
+ devsecops_engine_tools-1.17.1.dist-info/top_level.txt,sha256=ge6y0X_xBAU1aG3EMWFtl9djbVyg5BxuSp2r2Lg6EQU,23
314
+ devsecops_engine_tools-1.17.1.dist-info/RECORD,,