devsecops-engine-tools 1.33.0__py3-none-any.whl → 1.33.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.
- devsecops_engine_tools/engine_dast/src/infrastructure/driven_adapters/http/__init__.py +0 -0
- devsecops_engine_tools/engine_dast/src/infrastructure/driven_adapters/http/client/__init__.py +0 -0
- devsecops_engine_tools/engine_dast/src/infrastructure/driven_adapters/http/client/auth_client.py +12 -0
- devsecops_engine_tools/engine_dast/src/infrastructure/driven_adapters/jwt/__init__.py +0 -0
- devsecops_engine_tools/engine_dast/src/infrastructure/driven_adapters/jwt/jwt_object.py +64 -0
- devsecops_engine_tools/engine_dast/src/infrastructure/driven_adapters/jwt/jwt_tool.py +153 -0
- devsecops_engine_tools/version.py +1 -1
- {devsecops_engine_tools-1.33.0.dist-info → devsecops_engine_tools-1.33.1.dist-info}/METADATA +1 -1
- {devsecops_engine_tools-1.33.0.dist-info → devsecops_engine_tools-1.33.1.dist-info}/RECORD +12 -6
- {devsecops_engine_tools-1.33.0.dist-info → devsecops_engine_tools-1.33.1.dist-info}/WHEEL +0 -0
- {devsecops_engine_tools-1.33.0.dist-info → devsecops_engine_tools-1.33.1.dist-info}/entry_points.txt +0 -0
- {devsecops_engine_tools-1.33.0.dist-info → devsecops_engine_tools-1.33.1.dist-info}/top_level.txt +0 -0
|
File without changes
|
|
File without changes
|
devsecops_engine_tools/engine_dast/src/infrastructure/driven_adapters/http/client/auth_client.py
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
from devsecops_engine_tools.engine_dast.src.domain.model.gateways.authentication_gateway import (
|
|
2
|
+
AuthenticationGateway,
|
|
3
|
+
)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class AuthClientCredential(AuthenticationGateway):
|
|
7
|
+
def __init__(self, security_auth: dict):
|
|
8
|
+
self.client_id: str = security_auth.get("client_id")
|
|
9
|
+
self.client_secrets: str = security_auth.get("client_secret")
|
|
10
|
+
|
|
11
|
+
def get_credentials(self):
|
|
12
|
+
return None
|
|
File without changes
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
from time import (
|
|
2
|
+
time
|
|
3
|
+
)
|
|
4
|
+
from secrets import (
|
|
5
|
+
token_hex
|
|
6
|
+
)
|
|
7
|
+
from authlib.jose import (
|
|
8
|
+
jwt
|
|
9
|
+
)
|
|
10
|
+
from devsecops_engine_tools.engine_dast.src.domain.model.gateways.authentication_gateway import (
|
|
11
|
+
AuthenticationGateway,
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class JwtObject(AuthenticationGateway):
|
|
16
|
+
def __init__(self, security_auth: dict):
|
|
17
|
+
self.type = "jwt"
|
|
18
|
+
self.private_key: str = security_auth.get("jwt_private_key")
|
|
19
|
+
self.algorithm: str = security_auth.get("jwt_algorithm")
|
|
20
|
+
self.iss: str = security_auth.get("jwt_iss")
|
|
21
|
+
self.sum: str = security_auth.get("jwt_sum")
|
|
22
|
+
self.aud: str = security_auth.get("jwt_aud")
|
|
23
|
+
self.iat: float = time()
|
|
24
|
+
self.exp: float = self.iat + 60 * 60
|
|
25
|
+
self.nonce = token_hex(10)
|
|
26
|
+
self.payload: dict = {}
|
|
27
|
+
self.header: dict = {}
|
|
28
|
+
self.jwt_token: str = ""
|
|
29
|
+
self.header_name: str = security_auth.get("jwt_header_name")
|
|
30
|
+
self.init_header()
|
|
31
|
+
self.init_payload()
|
|
32
|
+
|
|
33
|
+
def init_header(self) -> None:
|
|
34
|
+
self.header: dict = {"alg": self.algorithm}
|
|
35
|
+
|
|
36
|
+
def init_payload(self) -> dict:
|
|
37
|
+
self.payload: dict = {
|
|
38
|
+
"iss": self.iss,
|
|
39
|
+
"sum": self.sum,
|
|
40
|
+
"aud": self.aud,
|
|
41
|
+
"exp": self.exp,
|
|
42
|
+
"iat": self.iat,
|
|
43
|
+
"nonce": self.nonce,
|
|
44
|
+
}
|
|
45
|
+
return self.payload
|
|
46
|
+
|
|
47
|
+
def get_credentials(self) -> tuple:
|
|
48
|
+
"""
|
|
49
|
+
Generates JWT using a file with the configuration
|
|
50
|
+
|
|
51
|
+
Returns:
|
|
52
|
+
|
|
53
|
+
tuple: header and jwt
|
|
54
|
+
|
|
55
|
+
"""
|
|
56
|
+
self.private_key = (
|
|
57
|
+
self.private_key.replace(" ", "\n")
|
|
58
|
+
.replace("-----BEGIN\nPRIVATE\nKEY-----", "-----BEGIN PRIVATE KEY-----")
|
|
59
|
+
.replace("-----END\nPRIVATE\nKEY-----", "-----END PRIVATE KEY-----")
|
|
60
|
+
)
|
|
61
|
+
self.jwt_token = jwt.encode(self.header, self.payload, self.private_key).decode(
|
|
62
|
+
"utf-8"
|
|
63
|
+
)
|
|
64
|
+
return self.header_name, self.jwt_token
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
from typing import (
|
|
2
|
+
List
|
|
3
|
+
)
|
|
4
|
+
from datetime import (
|
|
5
|
+
datetime,
|
|
6
|
+
)
|
|
7
|
+
import jwt
|
|
8
|
+
from devsecops_engine_tools.engine_core.src.domain.model.finding import (
|
|
9
|
+
Category,
|
|
10
|
+
Finding,
|
|
11
|
+
)
|
|
12
|
+
from devsecops_engine_tools.engine_dast.src.domain.model.gateways.tool_gateway import (
|
|
13
|
+
ToolGateway,
|
|
14
|
+
)
|
|
15
|
+
from devsecops_engine_tools.engine_dast.src.domain.model.api_operation import (
|
|
16
|
+
ApiOperation
|
|
17
|
+
)
|
|
18
|
+
from devsecops_engine_tools.engine_dast.src.infrastructure.helpers.file_generator_tool import (
|
|
19
|
+
generate_file_from_tool,
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
class JwtTool(ToolGateway):
|
|
23
|
+
|
|
24
|
+
def __init__(self, target_config):
|
|
25
|
+
self.TOOL = "JWT"
|
|
26
|
+
self.BAD_JWT_ALG = ["none", "ES256", "ES384", "ES512"]
|
|
27
|
+
self.BAD_JWS_ALG = ["none", "ES256", "ES384", "ES512"]
|
|
28
|
+
self.GOOD_JWE_ALG = ["dir", "RSA-OAEP", "RSA-OAEP-256"]
|
|
29
|
+
self.GOOD_JWE_ENC = ["A256GCM"]
|
|
30
|
+
self.target_config = target_config
|
|
31
|
+
|
|
32
|
+
def verify_jwt_alg(self, token):
|
|
33
|
+
"Evaluate JSON Web token's algorithm"
|
|
34
|
+
|
|
35
|
+
map_id = "JWT_ALGORITHM"
|
|
36
|
+
alg = jwt.get_unverified_header(token)["alg"]
|
|
37
|
+
|
|
38
|
+
if alg in self.BAD_JWT_ALG: #Is vulnerable
|
|
39
|
+
return {
|
|
40
|
+
"map_id": map_id,
|
|
41
|
+
"description": "msg"
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
def verify_jws_alg(self, token):
|
|
45
|
+
"""Evaluate JSON Web signature's algorithm"""
|
|
46
|
+
|
|
47
|
+
map_id = "JWS_ALGORITHM"
|
|
48
|
+
alg = jwt.get_unverified_header(token)["alg"]
|
|
49
|
+
|
|
50
|
+
if alg in self.BAD_JWS_ALG:#Is vulnerable
|
|
51
|
+
return {
|
|
52
|
+
"map_id": map_id,
|
|
53
|
+
"description": "msg"
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
def verify_jwe(self, token):
|
|
57
|
+
"""Evaluate JSON Web encryption's algorithm"""
|
|
58
|
+
|
|
59
|
+
map_id = "JWE_ALGORITHM"
|
|
60
|
+
msg = ""
|
|
61
|
+
enc = jwt.get_unverified_header(token)["enc"]
|
|
62
|
+
alg = jwt.get_unverified_header(token)["alg"]
|
|
63
|
+
|
|
64
|
+
if enc in self.GOOD_JWE_ENC:
|
|
65
|
+
if alg in self.GOOD_JWE_ALG:# Is not vulnerable
|
|
66
|
+
return
|
|
67
|
+
else:
|
|
68
|
+
msg = "Algorithm: " + alg
|
|
69
|
+
else:
|
|
70
|
+
msg = "Encryption: " + enc
|
|
71
|
+
|
|
72
|
+
return {
|
|
73
|
+
"map_id": map_id,
|
|
74
|
+
"description": msg
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
def check_token(self, token, jwt_details, config_tool):
|
|
78
|
+
"Validates JWT, JWS or JWE"
|
|
79
|
+
|
|
80
|
+
hed = jwt.get_unverified_header(token)
|
|
81
|
+
|
|
82
|
+
if "enc" in hed.keys():
|
|
83
|
+
result = self.verify_jwe(token)
|
|
84
|
+
elif "typ" in hed.keys():
|
|
85
|
+
result = self.verify_jwt_alg(token)
|
|
86
|
+
else:
|
|
87
|
+
result = self.verify_jws_alg(token)
|
|
88
|
+
|
|
89
|
+
if result:
|
|
90
|
+
mapped_result = {
|
|
91
|
+
"check_id": config_tool["RULES"][result["map_id"]]["checkID"],
|
|
92
|
+
"cvss": config_tool["RULES"][result["map_id"]]["cvss"],
|
|
93
|
+
"matched-at": jwt_details["path"],
|
|
94
|
+
"description": result["msg"],
|
|
95
|
+
"severity": config_tool["RULES"][result["map_id"]]["severity"],
|
|
96
|
+
"remediation": result["remediation"]
|
|
97
|
+
}
|
|
98
|
+
return mapped_result
|
|
99
|
+
return None
|
|
100
|
+
|
|
101
|
+
def configure_tool(self, target_data):
|
|
102
|
+
"""Method for group all operations that uses JWT"""
|
|
103
|
+
jwt_list: List[ApiOperation] = []
|
|
104
|
+
for operation in target_data.operations:
|
|
105
|
+
if operation.authentication_gateway.type.lower() == "jwt":
|
|
106
|
+
jwt_list.append(operation)
|
|
107
|
+
return jwt_list
|
|
108
|
+
|
|
109
|
+
def execute(self, jwt_config: List[ApiOperation], config_tool):
|
|
110
|
+
result_scans = []
|
|
111
|
+
if len(jwt_config) > 0:
|
|
112
|
+
for jwt_operation in jwt_config:
|
|
113
|
+
jwt_operation.authenticate()
|
|
114
|
+
result = self.check_token(token=jwt_operation.credentials[1],
|
|
115
|
+
jwt_details=jwt_operation.data["operation"],
|
|
116
|
+
config_tool=config_tool)
|
|
117
|
+
if result:
|
|
118
|
+
result_scans.append(result)
|
|
119
|
+
return result_scans
|
|
120
|
+
|
|
121
|
+
def get_list_finding(
|
|
122
|
+
self,
|
|
123
|
+
result_scan_list: "List[dict]"
|
|
124
|
+
) -> "List[Finding]":
|
|
125
|
+
list_open_findings = []
|
|
126
|
+
if len(result_scan_list) > 0:
|
|
127
|
+
for scan in result_scan_list:
|
|
128
|
+
finding_open = Finding(
|
|
129
|
+
id=scan.get("check-id"),
|
|
130
|
+
cvss=scan.get("cvss"),
|
|
131
|
+
where=scan.get("matched-at"),
|
|
132
|
+
description=scan.get("description"),
|
|
133
|
+
severity=scan.get("severity").lower(),
|
|
134
|
+
identification_date=datetime.now().strftime("%d%m%Y"),
|
|
135
|
+
module="engine_dast",
|
|
136
|
+
category=Category("vulnerability"),
|
|
137
|
+
requirements=scan.get("remediation"),
|
|
138
|
+
tool="jwt",
|
|
139
|
+
published_date_cve=scan.get("published-cve")
|
|
140
|
+
)
|
|
141
|
+
list_open_findings.append(finding_open)
|
|
142
|
+
return list_open_findings
|
|
143
|
+
|
|
144
|
+
def run_tool(self, target_data, config_tool):
|
|
145
|
+
jwt_config = self.configure_tool(target_data)
|
|
146
|
+
result_scans = self.execute(jwt_config, config_tool)
|
|
147
|
+
if result_scans:
|
|
148
|
+
finding_list = self.get_list_finding(result_scans)
|
|
149
|
+
path_file_results = generate_file_from_tool(
|
|
150
|
+
self.TOOL, result_scans, config_tool
|
|
151
|
+
)
|
|
152
|
+
return finding_list, path_file_results
|
|
153
|
+
return []
|
|
@@ -1 +1 @@
|
|
|
1
|
-
version = '1.33.
|
|
1
|
+
version = '1.33.1'
|
|
@@ -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=C3tgQeyYdXECCw9lJcXqOY08lfb8673_qriiLlgXXUE,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
|
|
@@ -72,6 +72,12 @@ devsecops_engine_tools/engine_dast/src/domain/usecases/__init__.py,sha256=47DEQp
|
|
|
72
72
|
devsecops_engine_tools/engine_dast/src/domain/usecases/dast_scan.py,sha256=9zQhA8d9McGWNT2ZdvjmjWCIPN3UpST7RWve2QvyHu4,4693
|
|
73
73
|
devsecops_engine_tools/engine_dast/src/infrastructure/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
74
74
|
devsecops_engine_tools/engine_dast/src/infrastructure/driven_adapters/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
75
|
+
devsecops_engine_tools/engine_dast/src/infrastructure/driven_adapters/http/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
76
|
+
devsecops_engine_tools/engine_dast/src/infrastructure/driven_adapters/http/client/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
77
|
+
devsecops_engine_tools/engine_dast/src/infrastructure/driven_adapters/http/client/auth_client.py,sha256=aeEB5-TKH1jow8KwxSpucpgoGrxotJ7jeY2Jliwr20o,407
|
|
78
|
+
devsecops_engine_tools/engine_dast/src/infrastructure/driven_adapters/jwt/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
79
|
+
devsecops_engine_tools/engine_dast/src/infrastructure/driven_adapters/jwt/jwt_object.py,sha256=p0_rDDjdsyAa_ar-HgZE_SQE-beua0oK3KBnwj8EmPo,1998
|
|
80
|
+
devsecops_engine_tools/engine_dast/src/infrastructure/driven_adapters/jwt/jwt_tool.py,sha256=9Yh7lOd6lsHcvl8exgWW7N8qTP55w-Znl0kid7IlKrM,5431
|
|
75
81
|
devsecops_engine_tools/engine_dast/src/infrastructure/driven_adapters/nuclei/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
76
82
|
devsecops_engine_tools/engine_dast/src/infrastructure/driven_adapters/nuclei/nuclei_config.py,sha256=TxjdA5_KDmn-RqZQsPkrrqyjd9zPMweKH37pwnxSV8Q,3090
|
|
77
83
|
devsecops_engine_tools/engine_dast/src/infrastructure/driven_adapters/nuclei/nuclei_deserealizer.py,sha256=qqoBMXr350ItzabSU6a_fD2-9kB6pAmtWioFP5AvCIE,1346
|
|
@@ -341,8 +347,8 @@ devsecops_engine_tools/engine_utilities/utils/name_conversion.py,sha256=ADJrRGax
|
|
|
341
347
|
devsecops_engine_tools/engine_utilities/utils/printers.py,sha256=amYAr9YQfYgR6jK9a2l26z3oovFPQ3FAKmhq6BKhEBA,623
|
|
342
348
|
devsecops_engine_tools/engine_utilities/utils/session_manager.py,sha256=Z0fdhB3r-dxU0nGSD9zW_B4r2Qol1rUnUCkhFR0U-HQ,487
|
|
343
349
|
devsecops_engine_tools/engine_utilities/utils/utils.py,sha256=dAklY11OGNDODjZyt9dO68Xiwu9pLJmqLOslqQ7rXa8,6112
|
|
344
|
-
devsecops_engine_tools-1.33.
|
|
345
|
-
devsecops_engine_tools-1.33.
|
|
346
|
-
devsecops_engine_tools-1.33.
|
|
347
|
-
devsecops_engine_tools-1.33.
|
|
348
|
-
devsecops_engine_tools-1.33.
|
|
350
|
+
devsecops_engine_tools-1.33.1.dist-info/METADATA,sha256=2w3FO-t3Z9lQmBt-8CrAO7CRvGyvi8BojDLAC4uTFBA,11592
|
|
351
|
+
devsecops_engine_tools-1.33.1.dist-info/WHEEL,sha256=R0nc6qTxuoLk7ShA2_Y-UWkN8ZdfDBG2B6Eqpz2WXbs,91
|
|
352
|
+
devsecops_engine_tools-1.33.1.dist-info/entry_points.txt,sha256=MHCTFFs9bdNKo6YcWCcBW2_8X6yTisgLOlmVx-V8Rxc,276
|
|
353
|
+
devsecops_engine_tools-1.33.1.dist-info/top_level.txt,sha256=ge6y0X_xBAU1aG3EMWFtl9djbVyg5BxuSp2r2Lg6EQU,23
|
|
354
|
+
devsecops_engine_tools-1.33.1.dist-info/RECORD,,
|
|
File without changes
|
{devsecops_engine_tools-1.33.0.dist-info → devsecops_engine_tools-1.33.1.dist-info}/entry_points.txt
RENAMED
|
File without changes
|
{devsecops_engine_tools-1.33.0.dist-info → devsecops_engine_tools-1.33.1.dist-info}/top_level.txt
RENAMED
|
File without changes
|