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

@@ -82,6 +82,7 @@ class DefectDojoPlatform(VulnerabilityManagementGateway):
82
82
  "BEARER": "Bearer CLI",
83
83
  "DEPENDENCY_CHECK": "Dependency Check Scan",
84
84
  "SONARQUBE": "SonarQube API Import",
85
+ "GITLEAKS": "Gitleaks Scan"
85
86
  }
86
87
 
87
88
  if any(
@@ -7,6 +7,12 @@ from devsecops_engine_tools.engine_sast.engine_secret.src.infrastructure.driven_
7
7
  from devsecops_engine_tools.engine_sast.engine_secret.src.infrastructure.driven_adapters.trufflehog.trufflehog_deserealizator import (
8
8
  SecretScanDeserealizator
9
9
  )
10
+ from devsecops_engine_tools.engine_sast.engine_secret.src.infrastructure.driven_adapters.gitleaks.gitleaks_tool import (
11
+ GitleaksTool
12
+ )
13
+ from devsecops_engine_tools.engine_sast.engine_secret.src.infrastructure.driven_adapters.gitleaks.gitleaks_deserealizator import (
14
+ GitleaksDeserealizator
15
+ )
10
16
  from devsecops_engine_tools.engine_utilities.git_cli.infrastructure.git_run import (
11
17
  GitRun
12
18
  )
@@ -19,6 +25,10 @@ def runner_secret_scan(dict_args, tool, devops_platform_gateway, secret_tool):
19
25
  if (tool == "TRUFFLEHOG"):
20
26
  tool_gateway = TrufflehogRun()
21
27
  tool_deserealizator = SecretScanDeserealizator()
28
+ elif (tool == "GITLEAKS"):
29
+ tool_gateway = GitleaksTool()
30
+ tool_deserealizator = GitleaksDeserealizator()
31
+
22
32
  return engine_secret_scan(
23
33
  devops_platform_gateway = devops_platform_gateway,
24
34
  tool_gateway = tool_gateway,
@@ -0,0 +1,36 @@
1
+ from datetime import datetime
2
+ from dataclasses import dataclass
3
+ from typing import List
4
+ from devsecops_engine_tools.engine_core.src.domain.model.finding import Finding, Category
5
+ from devsecops_engine_tools.engine_sast.engine_secret.src.domain.model.gateway.gateway_deserealizator import (
6
+ DeseralizatorGateway
7
+ )
8
+
9
+ @dataclass
10
+ class GitleaksDeserealizator(DeseralizatorGateway):
11
+
12
+ def get_list_vulnerability(self, results_scan_list: List[dict], path_directory: str, os: str) -> List[Finding]:
13
+ list_open_vulnerabilities = []
14
+ current_date=datetime.now().strftime("%d%m%Y")
15
+
16
+ for result in results_scan_list:
17
+ vulnerability_open = Finding(
18
+ id=result.get("RuleID", "SECRET_SCANNING"),
19
+ cvss=None,
20
+ where=self.get_where_correctly(result, path_directory),
21
+ description=result.get("Description", "No description available"),
22
+ severity="critical",
23
+ identification_date=current_date,
24
+ published_date_cve=None,
25
+ module="engine_secret",
26
+ category=Category.VULNERABILITY,
27
+ requirements="",
28
+ tool="Gitleaks",
29
+ )
30
+ list_open_vulnerabilities.append(vulnerability_open)
31
+ return list_open_vulnerabilities
32
+
33
+ def get_where_correctly(self, result: dict, path_directory=""):
34
+ path = result.get("File", "").replace(path_directory, "")
35
+ hidden_secret = str(result.get("Secret"))[:3] + '*' * 9 + str(result.get("Secret"))[-3:]
36
+ return f"{path}, Secret: {hidden_secret}"
@@ -0,0 +1,150 @@
1
+ import json
2
+ import os
3
+ import re
4
+ import subprocess
5
+ import requests
6
+ from concurrent.futures import ThreadPoolExecutor, as_completed
7
+ from devsecops_engine_tools.engine_utilities.utils.utils import Utils
8
+ from devsecops_engine_tools.engine_sast.engine_secret.src.domain.model.gateway.tool_gateway import (
9
+ ToolGateway,
10
+ )
11
+ from devsecops_engine_tools.engine_utilities.utils.logger_info import MyLogger
12
+ from devsecops_engine_tools.engine_utilities import settings
13
+ from devsecops_engine_tools.engine_utilities.utils.utils import Utils
14
+
15
+ logger = MyLogger.__call__(**settings.SETTING_LOGGER).get_logger()
16
+
17
+ class GitleaksTool(ToolGateway):
18
+ _COMMAND = None
19
+
20
+ def install_tool(self, agent_os, agent_temp_dir, tool_version) -> any:
21
+ is_windows_os = re.search(r"Windows", agent_os)
22
+ is_linux_os = re.search(r"Linux", agent_os)
23
+
24
+ if is_windows_os:
25
+ file_extension = "windows_x64.zip"
26
+ elif is_linux_os:
27
+ file_extension = "linux_x64.tar.gz"
28
+ else:
29
+ file_extension = "darwin_x64.tar.gz"
30
+
31
+ command = f"{agent_temp_dir}{os.sep}gitleaks"
32
+ command = f"{command}.exe" if is_windows_os else command
33
+
34
+ self._COMMAND = command
35
+ result = subprocess.run(f"{command} --version", capture_output=True, shell=True, text=True)
36
+ is_tool_installed = re.search(fr"{tool_version}", result.stdout.strip())
37
+
38
+ if is_tool_installed: return
39
+
40
+ try:
41
+ url = f"https://github.com/gitleaks/gitleaks/releases/download/v{tool_version}/gitleaks_{tool_version}_{file_extension}"
42
+ response = requests.get(url, allow_redirects=True)
43
+ compressed_name = os.path.join(
44
+ agent_temp_dir, f"gitleaks_{tool_version}_{file_extension}"
45
+ )
46
+ with open(compressed_name, "wb") as f:
47
+ f.write(response.content)
48
+
49
+ if is_windows_os:
50
+ Utils().unzip_file(compressed_name, agent_temp_dir)
51
+ else:
52
+ Utils().extract_targz_file(compressed_name, agent_temp_dir)
53
+
54
+ except Exception as ex:
55
+ logger.error(f"An error ocurred downloading Gitleaks: {ex}")
56
+
57
+ def _extract_json_data(self, file_path):
58
+ if os.path.exists(file_path):
59
+ with open(file_path, 'r', encoding='utf-8') as f:
60
+ return json.load(f)
61
+ else:
62
+ print(f"File {file_path} does not exist")
63
+ return []
64
+
65
+ def _create_report(self, output_file, combined_data):
66
+ with open(output_file, 'w', encoding='utf-8') as f:
67
+ json.dump(combined_data, f, ensure_ascii=False, indent=4)
68
+
69
+ def _check_path(self, path, excluded_paths):
70
+ parts = path.split(os.sep)
71
+ for part in parts:
72
+ if part in excluded_paths: return True
73
+ return False
74
+
75
+ def _add_flags(self, config_tool, tool, agent_work_folder):
76
+ flags = []
77
+ if not config_tool[tool]["ALLOW_IGNORE_LEAKS"]:
78
+ flags.append("--ignore-gitleaks-allow")
79
+
80
+ if config_tool[tool]["ENABLE_CUSTOM_RULES"]:
81
+ flags.extend(["--config", f"{agent_work_folder}{os.sep}rules{os.sep}gitleaks{os.sep}gitleaks.toml"])
82
+
83
+ return flags
84
+
85
+ def run_tool_secret_scan(
86
+ self,
87
+ files,
88
+ agent_os,
89
+ agent_work_folder,
90
+ repository_name,
91
+ config_tool,
92
+ secret_tool, # For external checks
93
+ secret_external_checks, # For external checks
94
+ agent_temp_dir,
95
+ tool
96
+ ):
97
+ command = [self._COMMAND, "dir"]
98
+ finding_path = os.path.join(agent_work_folder, "gitleaks_report.json")
99
+ excluded_paths = config_tool[tool]["EXCLUDE_PATH"]
100
+
101
+ if config_tool[tool]["ENABLE_CUSTOM_RULES"]:
102
+ Utils().configurate_external_checks(tool, config_tool, secret_tool, secret_external_checks, agent_work_folder)
103
+
104
+ try:
105
+ findings = []
106
+ flags = self._add_flags(config_tool, tool, agent_work_folder)
107
+ if len(files) > 1:
108
+ with ThreadPoolExecutor(max_workers=config_tool[tool]["NUMBER_THREADS"]) as executor:
109
+ futures = []
110
+
111
+ for pull_file in files:
112
+ if self._check_path(pull_file, excluded_paths): continue
113
+
114
+ aux_finding_path = os.path.join(
115
+ agent_work_folder, f"gitleaks_aux_report_{pull_file.replace(os.sep, '_')}.json"
116
+ )
117
+
118
+ command_aux = command.copy()
119
+ command_aux.extend([
120
+ os.path.join(agent_work_folder, repository_name, pull_file),
121
+ "--report-path", aux_finding_path
122
+ ])
123
+ command_aux.extend(flags)
124
+
125
+ futures.append(executor.submit(self._run_subprocess_command, command_aux, aux_finding_path))
126
+
127
+ for future in as_completed(futures):
128
+ result = future.result()
129
+ findings.extend(result)
130
+
131
+ self._create_report(finding_path, findings)
132
+ else:
133
+ command.extend([files[0], "--report-path", finding_path])
134
+ command.extend(flags)
135
+
136
+ subprocess.run(command, capture_output=True, text=True)
137
+ findings = self._extract_json_data(finding_path)
138
+
139
+ return findings, finding_path
140
+
141
+ except Exception as e:
142
+ logger.error(f"Error executing gitleaks scan: {e}")
143
+
144
+ def _run_subprocess_command(self, command_aux, aux_finding_path):
145
+ try:
146
+ subprocess.run(command_aux, capture_output=True, text=True)
147
+ return self._extract_json_data(aux_finding_path)
148
+ except Exception as e:
149
+ logger.error(f"Error executing gitleaks on {command_aux}: {e}")
150
+ return []
@@ -1,4 +1,5 @@
1
1
  import zipfile
2
+ import tarfile
2
3
  import platform
3
4
  from devsecops_engine_tools.engine_utilities.github.infrastructure.github_api import (
4
5
  GithubApi,
@@ -29,6 +30,10 @@ class Utils:
29
30
  def unzip_file(self, zip_file_path, extract_path):
30
31
  with zipfile.ZipFile(zip_file_path, "r") as zip_ref:
31
32
  zip_ref.extractall(extract_path)
33
+
34
+ def extract_targz_file(self, tar_file_path, extract_path):
35
+ with tarfile.open(tar_file_path, "r:gz") as tar_ref:
36
+ tar_ref.extractall(path=extract_path)
32
37
 
33
38
  def configurate_external_checks(self, tool, config_tool, secret_tool, secret_external_checks, agent_work_folder="/tmp"):
34
39
  try:
@@ -103,7 +108,7 @@ class Utils:
103
108
  config_tool[tool]["EXTERNAL_DIR_OWNER"],
104
109
  config_tool[tool]["EXTERNAL_DIR_REPOSITORY"],
105
110
  github_token,
106
- agent_work_folder if platform.system() in "Windows" else "/tmp"
111
+ agent_work_folder
107
112
  )
108
113
 
109
114
  except Exception as ex:
@@ -1 +1 @@
1
- version = '1.31.0'
1
+ version = '1.32.0'
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: devsecops-engine-tools
3
- Version: 1.31.0
3
+ Version: 1.32.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
@@ -134,10 +134,14 @@ For more information visit [here](https://github.com/bancolombia/devsecops-engin
134
134
  <td>Free</td>
135
135
  </tr>
136
136
  <tr>
137
- <td>ENGINE_SECRET</td>
137
+ <td rowspan="2">ENGINE_SECRET</td>
138
138
  <td><a href="https://trufflesecurity.com/trufflehog">TRUFFLEHOG</a></td>
139
139
  <td>Free</td>
140
140
  </tr>
141
+ <tr>
142
+ <td><a href="https://gitleaks.io/">GITLEAKS</a></td>
143
+ <td>Free</td>
144
+ </tr>
141
145
  <tr>
142
146
  <td rowspan="2">ENGINE_CONTAINER</td>
143
147
  <td><a href="https://www.paloaltonetworks.com/prisma/cloud">PRISMA</a></td>
@@ -1,5 +1,5 @@
1
1
  devsecops_engine_tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- devsecops_engine_tools/version.py,sha256=dORcM9p3Gq4eeQIYB7RelGt7lAEzbOinMO8jaEM2CLo,19
2
+ devsecops_engine_tools/version.py,sha256=qh7fu1xeNri8o7YY1UAeXzATcZjiVeXYKv8u5NDpHlM,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
@@ -38,7 +38,7 @@ devsecops_engine_tools/engine_core/src/infrastructure/driven_adapters/aws/secret
38
38
  devsecops_engine_tools/engine_core/src/infrastructure/driven_adapters/azure/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
39
39
  devsecops_engine_tools/engine_core/src/infrastructure/driven_adapters/azure/azure_devops.py,sha256=buCBJ6kAg-5b_7P-gWzem6NEMbk5lK9Hx0Zuf-BQfXQ,5090
40
40
  devsecops_engine_tools/engine_core/src/infrastructure/driven_adapters/defect_dojo/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
41
- devsecops_engine_tools/engine_core/src/infrastructure/driven_adapters/defect_dojo/defect_dojo.py,sha256=kUGFYhCm4-gZajqZCdhsyDecILWQtFj3dmcIT07pNXU,27745
41
+ devsecops_engine_tools/engine_core/src/infrastructure/driven_adapters/defect_dojo/defect_dojo.py,sha256=zBfd4zI_5fAHsIX3ZKt-WJmESkHkfUeIzAZO3O6adHo,27789
42
42
  devsecops_engine_tools/engine_core/src/infrastructure/driven_adapters/github/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
43
43
  devsecops_engine_tools/engine_core/src/infrastructure/driven_adapters/github/github_actions.py,sha256=KCg6tTDncasrRZbB20QiLZNE6TKYkfgQ9zP0wPd3xe0,3925
44
44
  devsecops_engine_tools/engine_core/src/infrastructure/driven_adapters/printer_pretty_table/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -143,7 +143,7 @@ devsecops_engine_tools/engine_sast/engine_iac/src/infrastructure/helpers/file_ge
143
143
  devsecops_engine_tools/engine_sast/engine_secret/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
144
144
  devsecops_engine_tools/engine_sast/engine_secret/src/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
145
145
  devsecops_engine_tools/engine_sast/engine_secret/src/applications/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
146
- devsecops_engine_tools/engine_sast/engine_secret/src/applications/runner_secret_scan.py,sha256=Th6koLvl0fn5SUAXTZ4cy9PEPKMjYpbB9A2S5rSYWxU,1394
146
+ devsecops_engine_tools/engine_sast/engine_secret/src/applications/runner_secret_scan.py,sha256=Su73AZxnbKX1JhJf7u6ZhQJWdhR9t3pNpi6aBmr6Ipo,1849
147
147
  devsecops_engine_tools/engine_sast/engine_secret/src/deployment/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
148
148
  devsecops_engine_tools/engine_sast/engine_secret/src/deployment/infrastructure/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
149
149
  devsecops_engine_tools/engine_sast/engine_secret/src/domain/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -156,6 +156,9 @@ devsecops_engine_tools/engine_sast/engine_secret/src/domain/usecases/secret_scan
156
156
  devsecops_engine_tools/engine_sast/engine_secret/src/domain/usecases/set_input_core.py,sha256=VbpiXDHIGeFAGHWb6FBR1axRvh5R2vCOzeYsDkQoHAE,3189
157
157
  devsecops_engine_tools/engine_sast/engine_secret/src/infrastructure/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
158
158
  devsecops_engine_tools/engine_sast/engine_secret/src/infrastructure/driven_adapters/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
159
+ devsecops_engine_tools/engine_sast/engine_secret/src/infrastructure/driven_adapters/gitleaks/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
160
+ devsecops_engine_tools/engine_sast/engine_secret/src/infrastructure/driven_adapters/gitleaks/gitleaks_deserealizator.py,sha256=IERIxeHhtQj0npBoL4_qb2mRlNgEUjg603DqGA49RQ4,1617
161
+ devsecops_engine_tools/engine_sast/engine_secret/src/infrastructure/driven_adapters/gitleaks/gitleaks_tool.py,sha256=FTkxlZu9PSX53wri7I0zN6iNdbXEioEvjmLm_ZqxUiM,5978
159
162
  devsecops_engine_tools/engine_sast/engine_secret/src/infrastructure/driven_adapters/trufflehog/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
160
163
  devsecops_engine_tools/engine_sast/engine_secret/src/infrastructure/driven_adapters/trufflehog/trufflehog_deserealizator.py,sha256=mrSqPrkMiikxQ_uY-rF2I8QvicsOMdMBzTC8CTV3Wk8,2392
161
164
  devsecops_engine_tools/engine_sast/engine_secret/src/infrastructure/driven_adapters/trufflehog/trufflehog_run.py,sha256=EEwKXvn8H4fTLZCuJC8CCJPvclqqrT0s3XDCU5xFd5o,7901
@@ -320,9 +323,9 @@ devsecops_engine_tools/engine_utilities/utils/logger_info.py,sha256=4Mz8Bwlm9Mku
320
323
  devsecops_engine_tools/engine_utilities/utils/name_conversion.py,sha256=ADJrRGaxYSDe0ZRh6VHRf53H4sXPcb-vNP_i81PUn3I,307
321
324
  devsecops_engine_tools/engine_utilities/utils/printers.py,sha256=amYAr9YQfYgR6jK9a2l26z3oovFPQ3FAKmhq6BKhEBA,623
322
325
  devsecops_engine_tools/engine_utilities/utils/session_manager.py,sha256=Z0fdhB3r-dxU0nGSD9zW_B4r2Qol1rUnUCkhFR0U-HQ,487
323
- devsecops_engine_tools/engine_utilities/utils/utils.py,sha256=_yaXWHN1pi2xFFKg0yKbb4fsK_ZRv7Dk_9N1FtPS72k,5964
324
- devsecops_engine_tools-1.31.0.dist-info/METADATA,sha256=pvTlUKMErHnqovHTD6U9B8lHN9TSbSXj_H8B9D00HeI,11276
325
- devsecops_engine_tools-1.31.0.dist-info/WHEEL,sha256=R0nc6qTxuoLk7ShA2_Y-UWkN8ZdfDBG2B6Eqpz2WXbs,91
326
- devsecops_engine_tools-1.31.0.dist-info/entry_points.txt,sha256=MHCTFFs9bdNKo6YcWCcBW2_8X6yTisgLOlmVx-V8Rxc,276
327
- devsecops_engine_tools-1.31.0.dist-info/top_level.txt,sha256=ge6y0X_xBAU1aG3EMWFtl9djbVyg5BxuSp2r2Lg6EQU,23
328
- devsecops_engine_tools-1.31.0.dist-info/RECORD,,
326
+ devsecops_engine_tools/engine_utilities/utils/utils.py,sha256=dAklY11OGNDODjZyt9dO68Xiwu9pLJmqLOslqQ7rXa8,6112
327
+ devsecops_engine_tools-1.32.0.dist-info/METADATA,sha256=y8wf8DXMNfi4wI6IVKw2AuXAq5A0C1aeMWwkz6ISD-c,11378
328
+ devsecops_engine_tools-1.32.0.dist-info/WHEEL,sha256=R0nc6qTxuoLk7ShA2_Y-UWkN8ZdfDBG2B6Eqpz2WXbs,91
329
+ devsecops_engine_tools-1.32.0.dist-info/entry_points.txt,sha256=MHCTFFs9bdNKo6YcWCcBW2_8X6yTisgLOlmVx-V8Rxc,276
330
+ devsecops_engine_tools-1.32.0.dist-info/top_level.txt,sha256=ge6y0X_xBAU1aG3EMWFtl9djbVyg5BxuSp2r2Lg6EQU,23
331
+ devsecops_engine_tools-1.32.0.dist-info/RECORD,,