GuardianUnivalle-Benito-Yucra 0.1.0__py3-none-any.whl → 0.1.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 GuardianUnivalle-Benito-Yucra might be problematic. Click here for more details.
- GuardianUnivalle_Benito_Yucra/__init__.py +11 -4
- GuardianUnivalle_Benito_Yucra/auditoria/registro_auditoria.py +9 -0
- GuardianUnivalle_Benito_Yucra/criptografia/cifrado_aead.py +25 -0
- GuardianUnivalle_Benito_Yucra/criptografia/intercambio_claves.py +23 -0
- GuardianUnivalle_Benito_Yucra/criptografia/kdf.py +23 -0
- GuardianUnivalle_Benito_Yucra/detectores/detector_csrf.py +21 -0
- GuardianUnivalle_Benito_Yucra/detectores/detector_dos.py +17 -0
- GuardianUnivalle_Benito_Yucra/detectores/detector_keylogger.py +21 -0
- GuardianUnivalle_Benito_Yucra/detectores/detector_sql.py +192 -0
- GuardianUnivalle_Benito_Yucra/detectores/detector_xss.py +21 -0
- GuardianUnivalle_Benito_Yucra/middleware_web/middleware_web.py +13 -0
- GuardianUnivalle_Benito_Yucra/mitigacion/limitador_peticion.py +7 -0
- GuardianUnivalle_Benito_Yucra/mitigacion/lista_bloqueo.py +10 -0
- GuardianUnivalle_Benito_Yucra/puntuacion/puntuacion_amenaza.py +15 -0
- GuardianUnivalle_Benito_Yucra/utilidades.py +7 -0
- guardianunivalle_benito_yucra-0.1.1.dist-info/METADATA +45 -0
- guardianunivalle_benito_yucra-0.1.1.dist-info/RECORD +20 -0
- GuardianUnivalle_Benito_Yucra/dos_protection.py +0 -6
- GuardianUnivalle_Benito_Yucra/encryption.py +0 -10
- GuardianUnivalle_Benito_Yucra/malware_check.py +0 -6
- GuardianUnivalle_Benito_Yucra/utils.py +0 -1
- GuardianUnivalle_Benito_Yucra/web_protection.py +0 -9
- guardianunivalle_benito_yucra-0.1.0.dist-info/METADATA +0 -12
- guardianunivalle_benito_yucra-0.1.0.dist-info/RECORD +0 -11
- {guardianunivalle_benito_yucra-0.1.0.dist-info → guardianunivalle_benito_yucra-0.1.1.dist-info}/WHEEL +0 -0
- {guardianunivalle_benito_yucra-0.1.0.dist-info → guardianunivalle_benito_yucra-0.1.1.dist-info}/licenses/LICENSE +0 -0
- {guardianunivalle_benito_yucra-0.1.0.dist-info → guardianunivalle_benito_yucra-0.1.1.dist-info}/top_level.txt +0 -0
|
@@ -1,10 +1,17 @@
|
|
|
1
1
|
""" Funciones principales """
|
|
2
2
|
# GuardianUnivalle_Benito_Yucra/__init__.py
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
"""
|
|
5
|
+
Paquete principal de GuardianUnivalle.
|
|
6
|
+
Incluye módulos de criptografía, detección de ataques, mitigación, auditoría y puntuación de amenazas.
|
|
7
|
+
"""
|
|
8
|
+
from . import criptografia
|
|
9
|
+
from . import detectores
|
|
10
|
+
from . import mitigacion
|
|
11
|
+
from . import auditoria
|
|
12
|
+
from . import puntuacion
|
|
13
|
+
from . import middleware_web
|
|
14
|
+
from . import utilidades
|
|
8
15
|
|
|
9
16
|
def protect_app():
|
|
10
17
|
"""
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import datetime
|
|
2
|
+
|
|
3
|
+
def registrar_evento(tipo: str, mensaje: str):
|
|
4
|
+
with open("auditoria_guardian.log", "a", encoding="utf-8") as f:
|
|
5
|
+
f.write(f"[{datetime.datetime.now()}] {tipo}: {mensaje}\n")
|
|
6
|
+
|
|
7
|
+
def generar_reporte() -> str:
|
|
8
|
+
with open("auditoria_guardian.log", "r", encoding="utf-8") as f:
|
|
9
|
+
return f.read()
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Cifrado simétrico autenticado: AES-GCM y ChaCha20-Poly1305
|
|
3
|
+
"""
|
|
4
|
+
from cryptography.hazmat.primitives.ciphers.aead import AESGCM, ChaCha20Poly1305
|
|
5
|
+
import os
|
|
6
|
+
|
|
7
|
+
def cifrar_aes_gcm(mensaje: bytes, clave: bytes) -> dict:
|
|
8
|
+
aes = AESGCM(clave)
|
|
9
|
+
nonce = os.urandom(12)
|
|
10
|
+
ciphertext = aes.encrypt(nonce, mensaje, None)
|
|
11
|
+
return {"nonce": nonce, "ciphertext": ciphertext}
|
|
12
|
+
|
|
13
|
+
def descifrar_aes_gcm(cipher: dict, clave: bytes) -> bytes:
|
|
14
|
+
aes = AESGCM(clave)
|
|
15
|
+
return aes.decrypt(cipher["nonce"], cipher["ciphertext"], None)
|
|
16
|
+
|
|
17
|
+
def cifrar_chacha20(mensaje: bytes, clave: bytes) -> dict:
|
|
18
|
+
cipher = ChaCha20Poly1305(clave)
|
|
19
|
+
nonce = os.urandom(12)
|
|
20
|
+
ciphertext = cipher.encrypt(nonce, mensaje, None)
|
|
21
|
+
return {"nonce": nonce, "ciphertext": ciphertext}
|
|
22
|
+
|
|
23
|
+
def descifrar_chacha20(cipher: dict, clave: bytes) -> bytes:
|
|
24
|
+
cipher_obj = ChaCha20Poly1305(clave)
|
|
25
|
+
return cipher_obj.decrypt(cipher["nonce"], cipher["ciphertext"], None)
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Gestión de intercambio de claves con ECDH y derivación HKDF.
|
|
3
|
+
"""
|
|
4
|
+
from cryptography.hazmat.primitives.asymmetric import ec
|
|
5
|
+
from cryptography.hazmat.primitives.kdf.hkdf import HKDF
|
|
6
|
+
from cryptography.hazmat.primitives import hashes
|
|
7
|
+
|
|
8
|
+
def generar_claves_ecdh():
|
|
9
|
+
"""Genera clave privada y pública ECDH"""
|
|
10
|
+
clave_privada = ec.generate_private_key(ec.SECP384R1())
|
|
11
|
+
clave_publica = clave_privada.public_key()
|
|
12
|
+
return clave_privada, clave_publica
|
|
13
|
+
|
|
14
|
+
def derivar_clave_secreta(clave_privada, clave_publica):
|
|
15
|
+
"""Deriva una clave compartida usando HKDF"""
|
|
16
|
+
shared_key = clave_privada.exchange(ec.ECDH(), clave_publica)
|
|
17
|
+
derived_key = HKDF(
|
|
18
|
+
algorithm=hashes.SHA256(),
|
|
19
|
+
length=32,
|
|
20
|
+
salt=None,
|
|
21
|
+
info=b'guardianclave'
|
|
22
|
+
).derive(shared_key)
|
|
23
|
+
return derived_key
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Wrappers para derivación de claves segura: PBKDF2 y Argon2
|
|
3
|
+
"""
|
|
4
|
+
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
|
|
5
|
+
from argon2 import PasswordHasher
|
|
6
|
+
from cryptography.hazmat.primitives import hashes
|
|
7
|
+
import os
|
|
8
|
+
|
|
9
|
+
def pbkdf2_derivar_clave(password: str, salt: bytes = None) -> bytes:
|
|
10
|
+
"""Deriva clave usando PBKDF2"""
|
|
11
|
+
salt = salt or os.urandom(16)
|
|
12
|
+
kdf = PBKDF2HMAC(
|
|
13
|
+
algorithm=hashes.SHA256(),
|
|
14
|
+
length=32,
|
|
15
|
+
salt=salt,
|
|
16
|
+
iterations=100_000,
|
|
17
|
+
)
|
|
18
|
+
return kdf.derive(password.encode()), salt
|
|
19
|
+
|
|
20
|
+
def argon2_derivar_clave(password: str) -> str:
|
|
21
|
+
"""Deriva clave usando Argon2"""
|
|
22
|
+
ph = PasswordHasher()
|
|
23
|
+
return ph.hash(password)
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import secrets
|
|
2
|
+
from ..auditoria.registro_auditoria import registrar_evento
|
|
3
|
+
|
|
4
|
+
def generar_token_csrf() -> str:
|
|
5
|
+
return secrets.token_hex(32)
|
|
6
|
+
|
|
7
|
+
def validar_token_csrf(token: str, token_sesion: str) -> bool:
|
|
8
|
+
valido = token == token_sesion
|
|
9
|
+
if not valido:
|
|
10
|
+
registrar_evento("CSRF", "Intento de CSRF detectado")
|
|
11
|
+
return valido
|
|
12
|
+
|
|
13
|
+
"""
|
|
14
|
+
Algoritmos relacionados:
|
|
15
|
+
*Uso de secreto aleatorio criptográfico.
|
|
16
|
+
*Opcionalmente derivación con PBKDF2 / Argon2 para reforzar token.
|
|
17
|
+
Contribución a fórmula de amenaza S:
|
|
18
|
+
S_csrf = w_csrf * intentos_csrf
|
|
19
|
+
S_csrf = 0.2 * 1
|
|
20
|
+
donde w_csrf es peso asignado a CSRF y intentos_csrf es la cantidad de intentos detectados.
|
|
21
|
+
"""
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
from ..mitigacion.limitador_peticion import limitar_peticion
|
|
2
|
+
from ..auditoria.registro_auditoria import registrar_evento
|
|
3
|
+
|
|
4
|
+
def detectar_dos(tasa_peticion: int, limite: int = 100) -> bool:
|
|
5
|
+
if tasa_peticion > limite:
|
|
6
|
+
registrar_evento("DoS", f"Tasa de petición elevada: {tasa_peticion}")
|
|
7
|
+
return True
|
|
8
|
+
return False
|
|
9
|
+
"""
|
|
10
|
+
Algoritmos relacionados:
|
|
11
|
+
*Rate Limiting, listas de bloqueo.
|
|
12
|
+
*Opcional: cifrado de logs con ChaCha20-Poly1305.
|
|
13
|
+
Contribución a fórmula de amenaza S:
|
|
14
|
+
S_dos = w_dos * (tasa_peticion / limite)
|
|
15
|
+
S_dos = 0.6 * (150 / 100)
|
|
16
|
+
donde w_dos es peso asignado a DoS y tasa_peticion / limite es la proporción de la tasa actual sobre el límite.
|
|
17
|
+
"""
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import psutil
|
|
2
|
+
from ..auditoria.registro_auditoria import registrar_evento
|
|
3
|
+
|
|
4
|
+
def detectar_keylogger():
|
|
5
|
+
sospechosos = []
|
|
6
|
+
for proc in psutil.process_iter(['pid', 'name']):
|
|
7
|
+
if "keylogger" in proc.info['name'].lower():
|
|
8
|
+
sospechosos.append(proc.info)
|
|
9
|
+
registrar_evento("Keylogger", f"Proceso sospechoso: {proc.info}")
|
|
10
|
+
return sospechosos
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
"""
|
|
14
|
+
Algoritmos relacionados:
|
|
15
|
+
*Guardar registros con AES-256 + hash SHA-512 para integridad.
|
|
16
|
+
Contribución a fórmula de amenaza S:
|
|
17
|
+
S_keylogger = w_keylogger * numero_procesos_sospechosos
|
|
18
|
+
S_keylogger = 0.4 * 2
|
|
19
|
+
donde w_keylogger es peso asignado a keyloggers y numero_procesos_sospechosos es la cantidad de procesos detectados.
|
|
20
|
+
|
|
21
|
+
"""
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
# middleware_sql_defense.py
|
|
2
|
+
import re
|
|
3
|
+
import json
|
|
4
|
+
import time
|
|
5
|
+
from typing import Tuple
|
|
6
|
+
from django.conf import settings
|
|
7
|
+
from django.http import JsonResponse
|
|
8
|
+
from django.utils.deprecation import MiddlewareMixin
|
|
9
|
+
import redis
|
|
10
|
+
|
|
11
|
+
# ---------- CONFIGURABLES (poner en settings.py preferiblemente) ----------
|
|
12
|
+
W_SQL = getattr(settings, "SQL_DEFENSE_W_SQL", 1.0)
|
|
13
|
+
THRESHOLD = getattr(settings, "SQL_DEFENSE_THRESHOLD", 0.8) # score normalizado 0..1
|
|
14
|
+
WINDOW_SEC = getattr(
|
|
15
|
+
settings, "SQL_DEFENSE_WINDOW_SEC", 300
|
|
16
|
+
) # ventana para conteo (ej. 5min)
|
|
17
|
+
MAX_EXPECTED_DETECTIONS = getattr(settings, "SQL_DEFENSE_MAX_EXPECTED_DETECTIONS", 10)
|
|
18
|
+
BLOCK_TTL = getattr(
|
|
19
|
+
settings, "SQL_DEFENSE_BLOCK_TTL", 600
|
|
20
|
+
) # bloqueo por IP en segundos (ej. 10min)
|
|
21
|
+
|
|
22
|
+
REDIS_URL = getattr(settings, "SQL_DEFENSE_REDIS_URL", "redis://localhost:6379/0")
|
|
23
|
+
redis_client = redis.from_url(REDIS_URL, decode_responses=True)
|
|
24
|
+
|
|
25
|
+
# ---------- Patrones y normalización ----------
|
|
26
|
+
_literal_single = re.compile(r"'([^'\\]|\\.)*'")
|
|
27
|
+
_literal_double = re.compile(r'"([^"\\]|\\.)*"')
|
|
28
|
+
_comment_sql = re.compile(r"(--[^\n]*|/\*.*?\*/)", re.S)
|
|
29
|
+
|
|
30
|
+
PATTERNS = [
|
|
31
|
+
(re.compile(r"\bunion\b\s+(all\s+)?\bselect\b", re.I), 0.95),
|
|
32
|
+
(re.compile(r"(?<!\w)or(?=\s+1=1)", re.I), 0.99),
|
|
33
|
+
(re.compile(r"\b(select\b.*\bfrom\b.*\bwhere\b.*\b(or|and)\b.*=)", re.I), 0.7),
|
|
34
|
+
(re.compile(r"\b(drop|truncate|delete|insert|update)\b", re.I), 0.8),
|
|
35
|
+
(re.compile(r"(--|#|;)", re.I), 0.4),
|
|
36
|
+
]
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
# ---------- Helpers ----------
|
|
40
|
+
def get_client_ip(request) -> str:
|
|
41
|
+
"""Obtiene la IP real (si hay proxies, usa X-Forwarded-For)"""
|
|
42
|
+
xff = request.META.get("HTTP_X_FORWARDED_FOR")
|
|
43
|
+
if xff:
|
|
44
|
+
# X-Forwarded-For puede contener lista de IPs
|
|
45
|
+
ip = xff.split(",")[0].strip()
|
|
46
|
+
return ip
|
|
47
|
+
return request.META.get("REMOTE_ADDR", "")
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def normalize_text(s: str) -> str:
|
|
51
|
+
"""Quita literales y comentarios para reducir falsos positivos"""
|
|
52
|
+
if not s:
|
|
53
|
+
return ""
|
|
54
|
+
s = _comment_sql.sub(" ", s)
|
|
55
|
+
s = _literal_single.sub("''", s)
|
|
56
|
+
s = _literal_double.sub('""', s)
|
|
57
|
+
s = re.sub(r"\s+", " ", s).strip()
|
|
58
|
+
return s
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def extract_payload_text(request) -> str:
|
|
62
|
+
"""
|
|
63
|
+
Extrae texto potencialmente peligroso del request:
|
|
64
|
+
- query string
|
|
65
|
+
- body (JSON o form)
|
|
66
|
+
- headers sospechosos (User-Agent, Referer)
|
|
67
|
+
"""
|
|
68
|
+
parts = []
|
|
69
|
+
try:
|
|
70
|
+
# query params
|
|
71
|
+
if request.META.get("QUERY_STRING"):
|
|
72
|
+
parts.append(request.META.get("QUERY_STRING"))
|
|
73
|
+
# body: intenta json, si no, raw text
|
|
74
|
+
content_type = request.META.get("CONTENT_TYPE", "")
|
|
75
|
+
if "application/json" in content_type:
|
|
76
|
+
try:
|
|
77
|
+
body_json = json.loads(request.body.decode("utf-8") or "{}")
|
|
78
|
+
parts.append(json.dumps(body_json))
|
|
79
|
+
except Exception:
|
|
80
|
+
parts.append((request.body or b"").decode("utf-8", errors="ignore"))
|
|
81
|
+
else:
|
|
82
|
+
# form-encoded or other text
|
|
83
|
+
try:
|
|
84
|
+
parts.append(request.body.decode("utf-8", errors="ignore"))
|
|
85
|
+
except Exception:
|
|
86
|
+
pass
|
|
87
|
+
# headers
|
|
88
|
+
parts.append(request.META.get("HTTP_USER_AGENT", ""))
|
|
89
|
+
parts.append(request.META.get("HTTP_REFERER", ""))
|
|
90
|
+
except Exception:
|
|
91
|
+
pass
|
|
92
|
+
return " ".join([p for p in parts if p])
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
def detect_sqli_text(text: str) -> Tuple[bool, list]:
|
|
96
|
+
"""Detecta patrones en un texto normalizado; devuelve matches con severidad."""
|
|
97
|
+
q = normalize_text(text)
|
|
98
|
+
matches = []
|
|
99
|
+
for patt, sev in PATTERNS:
|
|
100
|
+
if patt.search(q):
|
|
101
|
+
matches.append((patt.pattern, float(sev)))
|
|
102
|
+
return (len(matches) > 0, matches)
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
# ---------- Redis keys ----------
|
|
106
|
+
def redis_count_key(ip: str) -> str:
|
|
107
|
+
return f"sqli:count:{ip}"
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
def redis_block_key(ip: str) -> str:
|
|
111
|
+
return f"sqli:block:{ip}"
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
# ---------- Cálculo de score S_sql/ip ----------
|
|
115
|
+
def compute_s_sql_ip(detections_count: int) -> float:
|
|
116
|
+
"""
|
|
117
|
+
Convertir conteo a una puntuación normalizada 0..1.
|
|
118
|
+
Usamos saturación en MAX_EXPECTED_DETECTIONS.
|
|
119
|
+
"""
|
|
120
|
+
norm = min(float(detections_count) / float(MAX_EXPECTED_DETECTIONS), 1.0)
|
|
121
|
+
score = float(W_SQL) * norm
|
|
122
|
+
# Normalizamos a 0..1 si W_SQL puede ser mayor que 1
|
|
123
|
+
return min(score, 1.0)
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
# ---------- Middleware ----------
|
|
127
|
+
class SQLIDefenseMiddleware(MiddlewareMixin):
|
|
128
|
+
def process_request(self, request):
|
|
129
|
+
# 1) obtener IP y comprobar si está bloqueada
|
|
130
|
+
ip = get_client_ip(request)
|
|
131
|
+
if not ip:
|
|
132
|
+
return None # no podemos hacer mucho sin IP
|
|
133
|
+
|
|
134
|
+
# comprobar bloqueo en Redis
|
|
135
|
+
block_key = redis_block_key(ip)
|
|
136
|
+
if redis_client.exists(block_key):
|
|
137
|
+
ttl = redis_client.ttl(block_key)
|
|
138
|
+
return JsonResponse(
|
|
139
|
+
{
|
|
140
|
+
"detail": "Acceso denegado (bloqueado por actividad sospechosa)",
|
|
141
|
+
"block_ttl_s": ttl,
|
|
142
|
+
},
|
|
143
|
+
status=403,
|
|
144
|
+
)
|
|
145
|
+
|
|
146
|
+
# 2) extraer texto y detectar patrones
|
|
147
|
+
text = extract_payload_text(request)
|
|
148
|
+
if not text:
|
|
149
|
+
return None
|
|
150
|
+
|
|
151
|
+
flagged, matches = detect_sqli_text(text)
|
|
152
|
+
if flagged:
|
|
153
|
+
# incrementar contador con TTL (ventana)
|
|
154
|
+
count_key = redis_count_key(ip)
|
|
155
|
+
# INCR y asegurar expiration
|
|
156
|
+
new_count = redis_client.incr(count_key)
|
|
157
|
+
# establecer TTL si fue creado de nuevo
|
|
158
|
+
if redis_client.ttl(count_key) == -1:
|
|
159
|
+
redis_client.expire(count_key, WINDOW_SEC)
|
|
160
|
+
|
|
161
|
+
# calcular score
|
|
162
|
+
current_count = int(new_count)
|
|
163
|
+
s_sql_ip = compute_s_sql_ip(current_count)
|
|
164
|
+
|
|
165
|
+
# registrar evento (puedes ampliar con logging o envío a SIEM)
|
|
166
|
+
# guardamos metadata mínima
|
|
167
|
+
event = {
|
|
168
|
+
"time": int(time.time()),
|
|
169
|
+
"ip": ip,
|
|
170
|
+
"count": current_count,
|
|
171
|
+
"score": s_sql_ip,
|
|
172
|
+
"matches": matches,
|
|
173
|
+
}
|
|
174
|
+
# Puedes push a lista en Redis o a un logger
|
|
175
|
+
redis_client.lpush("sqli:events", json.dumps(event))
|
|
176
|
+
redis_client.ltrim("sqli:events", 0, 999) # mantener últimos 1000 eventos
|
|
177
|
+
|
|
178
|
+
# Si supera THRESHOLD -> bloquear ip
|
|
179
|
+
if s_sql_ip >= float(THRESHOLD):
|
|
180
|
+
redis_client.set(redis_block_key(ip), "1", ex=BLOCK_TTL)
|
|
181
|
+
# opcional: publicar alerta en canal pubsub o webhook
|
|
182
|
+
return JsonResponse(
|
|
183
|
+
{"detail": "IP bloqueada por actividad sospechosa", "ip": ip},
|
|
184
|
+
status=403,
|
|
185
|
+
)
|
|
186
|
+
else:
|
|
187
|
+
# no bloqueo todavía: permitir continuar pero devolver alerta en header (opcional)
|
|
188
|
+
# Puedes añadir header para que la vista/log lo capture
|
|
189
|
+
request.META["X-SQLI-ALERT"] = json.dumps(event)
|
|
190
|
+
return None
|
|
191
|
+
|
|
192
|
+
return None
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import html
|
|
2
|
+
from ..auditoria.registro_auditoria import registrar_evento
|
|
3
|
+
|
|
4
|
+
def sanitizar_xss(entrada: str) -> str:
|
|
5
|
+
return html.escape(entrada)
|
|
6
|
+
|
|
7
|
+
def detectar_xss(entrada: str) -> bool:
|
|
8
|
+
patrones = ["<script", "javascript:", "onerror", "onload"]
|
|
9
|
+
if any(p in entrada.lower() for p in patrones):
|
|
10
|
+
registrar_evento("XSS", f"Ataque detectado: {entrada}")
|
|
11
|
+
return True
|
|
12
|
+
return False
|
|
13
|
+
"""
|
|
14
|
+
Algoritmos relacionados:
|
|
15
|
+
*Guardar entradas sospechosas con AES-GCM para confidencialidad y autenticidad.
|
|
16
|
+
Contribución a fórmula de amenaza S:
|
|
17
|
+
S_xss = w_xss * detecciones_xss
|
|
18
|
+
S_xss = 0.3 * 2
|
|
19
|
+
donde w_xss es peso asignado a XSS y detecciones_xss es la cantidad de patrones detectados.
|
|
20
|
+
|
|
21
|
+
"""
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Middleware base para frameworks web (Django/Flask/FastAPI)
|
|
3
|
+
"""
|
|
4
|
+
from ..detectores.detector_sql import detectar_inyeccion_sql
|
|
5
|
+
from ..detectores.detector_xss import detectar_xss
|
|
6
|
+
|
|
7
|
+
def middleware_proteccion(request):
|
|
8
|
+
# Simulación de protección de entrada
|
|
9
|
+
if detectar_inyeccion_sql(request.get("query", "")):
|
|
10
|
+
return {"error": "SQL Injection detectado"}
|
|
11
|
+
if detectar_xss(request.get("input", "")):
|
|
12
|
+
return {"error": "XSS detectado"}
|
|
13
|
+
return {"ok": True}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Fórmula compuesta S para puntuar la amenaza global
|
|
3
|
+
"""
|
|
4
|
+
def calcular_puntuacion(detecciones_sql=0, detecciones_xss=0, intentos_csrf=0,
|
|
5
|
+
procesos_keylogger=0, tasa_dos=0,
|
|
6
|
+
w_sql=1.5, w_xss=1.2, w_csrf=1.0, w_keylogger=2.0, w_dos=2.5,
|
|
7
|
+
limite_dos=100) -> float:
|
|
8
|
+
S = (
|
|
9
|
+
w_sql * detecciones_sql +
|
|
10
|
+
w_xss * detecciones_xss +
|
|
11
|
+
w_csrf * intentos_csrf +
|
|
12
|
+
w_keylogger * procesos_keylogger +
|
|
13
|
+
w_dos * (tasa_dos / limite_dos)
|
|
14
|
+
)
|
|
15
|
+
return S
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: GuardianUnivalle-Benito-Yucra
|
|
3
|
+
Version: 0.1.1
|
|
4
|
+
Summary: Librería de seguridad automática para aplicaciones frontend y backend
|
|
5
|
+
Author-email: Andres Benito Calle Yucra <benitoandrescalle035@gmail.com>
|
|
6
|
+
License: MIT
|
|
7
|
+
Requires-Python: >=3.8
|
|
8
|
+
Description-Content-Type: text/markdown
|
|
9
|
+
License-File: LICENSE
|
|
10
|
+
Dynamic: license-file
|
|
11
|
+
|
|
12
|
+
<!-- Información de la librería -->
|
|
13
|
+
|
|
14
|
+
🔐 Algoritmos de cifrado simétrico
|
|
15
|
+
AES (Rijndael) → AES-128, AES-192, AES-256
|
|
16
|
+
RC6
|
|
17
|
+
ChaCha20
|
|
18
|
+
|
|
19
|
+
🔀 Modos de operación de cifrado simétrico
|
|
20
|
+
CTR (Counter Mode)
|
|
21
|
+
CFB (Cipher Feedback Mode)
|
|
22
|
+
OFB (Output Feedback Mode)
|
|
23
|
+
CCM (Counter with CBC-MAC)
|
|
24
|
+
EAX
|
|
25
|
+
GCM (Galois/Counter Mode)
|
|
26
|
+
XTS
|
|
27
|
+
|
|
28
|
+
🔑 Algoritmos de cifrado asimétrico
|
|
29
|
+
RSA (Rivest–Shamir–Adleman)
|
|
30
|
+
ECC (Elliptic Curve Cryptography)
|
|
31
|
+
🧮 Algoritmos relacionados con factorización y logaritmos
|
|
32
|
+
CGCN (Criba General del Cuerpo de Números / General Number Field Sieve, GNFS)
|
|
33
|
+
Algoritmo de Shor (para computación cuántica)
|
|
34
|
+
Multiplicación por tentativa (método básico de exponenciación para logaritmos discretos)
|
|
35
|
+
|
|
36
|
+
🔑 Funciones de derivación de claves (KDF)
|
|
37
|
+
PBKDF2
|
|
38
|
+
scrypt
|
|
39
|
+
Argon2
|
|
40
|
+
|
|
41
|
+
📝 Funciones hash
|
|
42
|
+
Serie MD: MD2, MD4, MD5, MD6
|
|
43
|
+
SHA (Secure Hash Algorithm): SHA-0, SHA-1, SHA-2 (SHA-224, SHA-256, SHA-384, SHA-512)
|
|
44
|
+
|
|
45
|
+
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
GuardianUnivalle_Benito_Yucra/__init__.py,sha256=lbIRb8fCFYfAdyJV6NsYVZJ5pKYSJZKhhK-En9g_1M8,762
|
|
2
|
+
GuardianUnivalle_Benito_Yucra/utilidades.py,sha256=lFNVnlyTSYmQ1CqtmHx6aefK5uNw0wsMdHRQyxAIZy0,120
|
|
3
|
+
GuardianUnivalle_Benito_Yucra/auditoria/registro_auditoria.py,sha256=YxEtF6ZJj8MXhZ_kWPn9ijmXyJzpbu3UQDD3_BdOSqs,334
|
|
4
|
+
GuardianUnivalle_Benito_Yucra/criptografia/cifrado_aead.py,sha256=wfoRpaKvOqPbollNQsDNUNWClYJlXYTKTYvv0qcR6aI,962
|
|
5
|
+
GuardianUnivalle_Benito_Yucra/criptografia/intercambio_claves.py,sha256=9djnlzb022hUhrDbQyWz7lWLbkn_vQZ4K7qar1FXYmo,829
|
|
6
|
+
GuardianUnivalle_Benito_Yucra/criptografia/kdf.py,sha256=_sbepEY1qHEKga0ExrX2WRg1HeCPY5MC5CfXZWYyl-A,709
|
|
7
|
+
GuardianUnivalle_Benito_Yucra/detectores/detector_csrf.py,sha256=EAYfLkHuxGC5rXSu4mZJ4yZDCbwBpTX8xZWGKz7i5wA,692
|
|
8
|
+
GuardianUnivalle_Benito_Yucra/detectores/detector_dos.py,sha256=lMWmCw6nccCEnek53nVjpoBCeiBqLdrSXxqRuI7VP2I,696
|
|
9
|
+
GuardianUnivalle_Benito_Yucra/detectores/detector_keylogger.py,sha256=rEDG-Q_R56OsG2ypfHVBK7erolYjdvATnAxB3yvPXts,729
|
|
10
|
+
GuardianUnivalle_Benito_Yucra/detectores/detector_sql.py,sha256=F1GItlntAQT0MqxiAnrQItS-Jc_t--LYfdSz9wo3ZMc,7039
|
|
11
|
+
GuardianUnivalle_Benito_Yucra/detectores/detector_xss.py,sha256=66V_xuxNOZEwluvWOT4-6pk5MJ3zWE1IwcVkBl7MZSg,719
|
|
12
|
+
GuardianUnivalle_Benito_Yucra/middleware_web/middleware_web.py,sha256=23pLLYqliUoMrIC6ZEwz3hKXeDjWfHSm9vYPWGmDDik,495
|
|
13
|
+
GuardianUnivalle_Benito_Yucra/mitigacion/limitador_peticion.py,sha256=ipMOebYhql-6mSyHs0ddYXOcXq9w8P_IXLlpiIqGncw,246
|
|
14
|
+
GuardianUnivalle_Benito_Yucra/mitigacion/lista_bloqueo.py,sha256=6AYWII4mrmwCLHCvGTyoBxR4Oasr4raSHpFbVjqn7d8,193
|
|
15
|
+
GuardianUnivalle_Benito_Yucra/puntuacion/puntuacion_amenaza.py,sha256=Wx5XfcII4oweLvZsTBEJ7kUc9pMpP5-36RfI5C5KJXo,561
|
|
16
|
+
guardianunivalle_benito_yucra-0.1.1.dist-info/licenses/LICENSE,sha256=5e4IdL542v1E8Ft0A24GZjrxZeTsVK7XrS3mZEUhPtM,37
|
|
17
|
+
guardianunivalle_benito_yucra-0.1.1.dist-info/METADATA,sha256=qctbyoDFKu13d6hwyGuavjeQg_6Z83vvrEKfXr0lfOk,1303
|
|
18
|
+
guardianunivalle_benito_yucra-0.1.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
19
|
+
guardianunivalle_benito_yucra-0.1.1.dist-info/top_level.txt,sha256=HTWfZM64WAV_QYr5cnXnLuabQt92dvlxqlR3pCwpbDQ,30
|
|
20
|
+
guardianunivalle_benito_yucra-0.1.1.dist-info/RECORD,,
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
""" Funciones de cifrado """
|
|
2
|
-
# GuardianUnivalle_Benito_Yucra/encryption.py
|
|
3
|
-
|
|
4
|
-
def encrypt_data(data: str) -> str:
|
|
5
|
-
"""Simulación de cifrado sencillo"""
|
|
6
|
-
return "".join(chr(ord(c)+3) for c in data)
|
|
7
|
-
|
|
8
|
-
def decrypt_data(data: str) -> str:
|
|
9
|
-
"""Simulación de descifrado sencillo"""
|
|
10
|
-
return "".join(chr(ord(c)-3) for c in data)
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
""" Funciones auxiliares """
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
# GuardianUnivalle_Benito_Yucra/web_protection.py
|
|
2
|
-
|
|
3
|
-
def sanitize_input(user_input: str) -> str:
|
|
4
|
-
"""Elimina caracteres peligrosos (simulación)"""
|
|
5
|
-
return user_input.replace("<", "<").replace(">", ">")
|
|
6
|
-
|
|
7
|
-
def check_csrf():
|
|
8
|
-
"""Simulación de protección CSRF"""
|
|
9
|
-
print("✅ CSRF check passed")
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: GuardianUnivalle-Benito-Yucra
|
|
3
|
-
Version: 0.1.0
|
|
4
|
-
Summary: Librería de seguridad automática para aplicaciones frontend y backend
|
|
5
|
-
Author-email: Benito Yucra <tu_email@dominio.com>
|
|
6
|
-
License: MIT
|
|
7
|
-
Requires-Python: >=3.8
|
|
8
|
-
Description-Content-Type: text/markdown
|
|
9
|
-
License-File: LICENSE
|
|
10
|
-
Dynamic: license-file
|
|
11
|
-
|
|
12
|
-
<!-- Información de la librería -->
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
GuardianUnivalle_Benito_Yucra/__init__.py,sha256=oy-mVZKVEud0LQL5QMoKh7ts9XrWYbiZtlCcpiOXBTk,606
|
|
2
|
-
GuardianUnivalle_Benito_Yucra/dos_protection.py,sha256=JAY2D8LGOBKshyYWwKabB7p5HfaQi-zolwWpDURu93g,187
|
|
3
|
-
GuardianUnivalle_Benito_Yucra/encryption.py,sha256=1pSEDwp5bTe9lol7MJmObRMr_fLZ83PFv9kQ7-Pk6lM,342
|
|
4
|
-
GuardianUnivalle_Benito_Yucra/malware_check.py,sha256=lnUdx3hkLmQ4ZUgkqrqcP2dAELi0xGgQCIn-SZvQ8KE,202
|
|
5
|
-
GuardianUnivalle_Benito_Yucra/utils.py,sha256=7mriluJY8ygJR-j0xyhqrp8BUzu96c1mY75XGtKMzho,28
|
|
6
|
-
GuardianUnivalle_Benito_Yucra/web_protection.py,sha256=M-GyIkTNowhJwhXzZX7embU4BoJxOsHViSLGSJTT-ko,318
|
|
7
|
-
guardianunivalle_benito_yucra-0.1.0.dist-info/licenses/LICENSE,sha256=5e4IdL542v1E8Ft0A24GZjrxZeTsVK7XrS3mZEUhPtM,37
|
|
8
|
-
guardianunivalle_benito_yucra-0.1.0.dist-info/METADATA,sha256=vYtJs612u-DUDWDIHAWrHwr-MWVoFTI3iqlTvXL_fFA,375
|
|
9
|
-
guardianunivalle_benito_yucra-0.1.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
10
|
-
guardianunivalle_benito_yucra-0.1.0.dist-info/top_level.txt,sha256=HTWfZM64WAV_QYr5cnXnLuabQt92dvlxqlR3pCwpbDQ,30
|
|
11
|
-
guardianunivalle_benito_yucra-0.1.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|