GuardianUnivalle-Benito-Yucra 0.1.39__tar.gz → 0.1.41__tar.gz

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.

Files changed (25) hide show
  1. {guardianunivalle_benito_yucra-0.1.39 → guardianunivalle_benito_yucra-0.1.41}/GuardianUnivalle_Benito_Yucra/detectores/detector_sql.py +53 -42
  2. {guardianunivalle_benito_yucra-0.1.39 → guardianunivalle_benito_yucra-0.1.41}/GuardianUnivalle_Benito_Yucra.egg-info/PKG-INFO +1 -1
  3. {guardianunivalle_benito_yucra-0.1.39 → guardianunivalle_benito_yucra-0.1.41}/PKG-INFO +1 -1
  4. {guardianunivalle_benito_yucra-0.1.39 → guardianunivalle_benito_yucra-0.1.41}/pyproject.toml +1 -1
  5. {guardianunivalle_benito_yucra-0.1.39 → guardianunivalle_benito_yucra-0.1.41}/GuardianUnivalle_Benito_Yucra/__init__.py +0 -0
  6. {guardianunivalle_benito_yucra-0.1.39 → guardianunivalle_benito_yucra-0.1.41}/GuardianUnivalle_Benito_Yucra/auditoria/registro_auditoria.py +0 -0
  7. {guardianunivalle_benito_yucra-0.1.39 → guardianunivalle_benito_yucra-0.1.41}/GuardianUnivalle_Benito_Yucra/criptografia/cifrado_aead.py +0 -0
  8. {guardianunivalle_benito_yucra-0.1.39 → guardianunivalle_benito_yucra-0.1.41}/GuardianUnivalle_Benito_Yucra/criptografia/intercambio_claves.py +0 -0
  9. {guardianunivalle_benito_yucra-0.1.39 → guardianunivalle_benito_yucra-0.1.41}/GuardianUnivalle_Benito_Yucra/criptografia/kdf.py +0 -0
  10. {guardianunivalle_benito_yucra-0.1.39 → guardianunivalle_benito_yucra-0.1.41}/GuardianUnivalle_Benito_Yucra/detectores/detector_csrf.py +0 -0
  11. {guardianunivalle_benito_yucra-0.1.39 → guardianunivalle_benito_yucra-0.1.41}/GuardianUnivalle_Benito_Yucra/detectores/detector_dos.py +0 -0
  12. {guardianunivalle_benito_yucra-0.1.39 → guardianunivalle_benito_yucra-0.1.41}/GuardianUnivalle_Benito_Yucra/detectores/detector_keylogger.py +0 -0
  13. {guardianunivalle_benito_yucra-0.1.39 → guardianunivalle_benito_yucra-0.1.41}/GuardianUnivalle_Benito_Yucra/detectores/detector_xss.py +0 -0
  14. {guardianunivalle_benito_yucra-0.1.39 → guardianunivalle_benito_yucra-0.1.41}/GuardianUnivalle_Benito_Yucra/middleware_web/middleware_web.py +0 -0
  15. {guardianunivalle_benito_yucra-0.1.39 → guardianunivalle_benito_yucra-0.1.41}/GuardianUnivalle_Benito_Yucra/mitigacion/limitador_peticion.py +0 -0
  16. {guardianunivalle_benito_yucra-0.1.39 → guardianunivalle_benito_yucra-0.1.41}/GuardianUnivalle_Benito_Yucra/mitigacion/lista_bloqueo.py +0 -0
  17. {guardianunivalle_benito_yucra-0.1.39 → guardianunivalle_benito_yucra-0.1.41}/GuardianUnivalle_Benito_Yucra/puntuacion/puntuacion_amenaza.py +0 -0
  18. {guardianunivalle_benito_yucra-0.1.39 → guardianunivalle_benito_yucra-0.1.41}/GuardianUnivalle_Benito_Yucra/utilidades.py +0 -0
  19. {guardianunivalle_benito_yucra-0.1.39 → guardianunivalle_benito_yucra-0.1.41}/GuardianUnivalle_Benito_Yucra.egg-info/SOURCES.txt +0 -0
  20. {guardianunivalle_benito_yucra-0.1.39 → guardianunivalle_benito_yucra-0.1.41}/GuardianUnivalle_Benito_Yucra.egg-info/dependency_links.txt +0 -0
  21. {guardianunivalle_benito_yucra-0.1.39 → guardianunivalle_benito_yucra-0.1.41}/GuardianUnivalle_Benito_Yucra.egg-info/requires.txt +0 -0
  22. {guardianunivalle_benito_yucra-0.1.39 → guardianunivalle_benito_yucra-0.1.41}/GuardianUnivalle_Benito_Yucra.egg-info/top_level.txt +0 -0
  23. {guardianunivalle_benito_yucra-0.1.39 → guardianunivalle_benito_yucra-0.1.41}/LICENSE +0 -0
  24. {guardianunivalle_benito_yucra-0.1.39 → guardianunivalle_benito_yucra-0.1.41}/README.md +0 -0
  25. {guardianunivalle_benito_yucra-0.1.39 → guardianunivalle_benito_yucra-0.1.41}/setup.cfg +0 -0
@@ -1,5 +1,6 @@
1
1
  # sql_defense.py
2
- # sql_defense.py - versión robusta y precisa
2
+ # GuardianUnivalle_Benito_Yucra/detectores/detector_sql.py
3
+
3
4
  import json
4
5
  import logging
5
6
  import re
@@ -13,9 +14,10 @@ if not logger.handlers:
13
14
  handler.setFormatter(logging.Formatter("%(asctime)s - %(levelname)s - %(message)s"))
14
15
  logger.addHandler(handler)
15
16
 
16
- # Patrones organizados por nivel de severidad
17
+ # =====================================================
18
+ # === PATRONES DE ATAQUE SQL DEFINIDOS ===
19
+ # =====================================================
17
20
  SQL_PATTERNS = [
18
- # Ataques fuertes (bloqueo inmediato)
19
21
  (re.compile(r"\bunion\b\s+(all\s+)?\bselect\b", re.I), "Uso de UNION SELECT", 0.7),
20
22
  (re.compile(r"\bor\b\s+'?\d+'?\s*=\s*'?\d+'?", re.I), "Tautología OR 1=1", 0.6),
21
23
  (re.compile(r"\bselect\b.+\bfrom\b", re.I), "Consulta SQL SELECT-FROM", 0.5),
@@ -24,84 +26,93 @@ SQL_PATTERNS = [
24
26
  (re.compile(r"exec\s*\(", re.I), "Ejecución de procedimiento almacenado", 0.6),
25
27
  ]
26
28
 
27
- # Campos que deben ser analizados con cuidado o ignorados
28
29
  IGNORED_FIELDS = ["password", "csrfmiddlewaretoken", "token", "auth"]
29
30
 
31
+
30
32
  def get_client_ip(request):
33
+ """
34
+ Obtiene la IP real del cliente.
35
+ Primero revisa 'X-Forwarded-For', luego 'REMOTE_ADDR'.
36
+ """
31
37
  x_forwarded_for = request.META.get("HTTP_X_FORWARDED_FOR")
32
38
  if x_forwarded_for:
33
- return x_forwarded_for.split(",")[0].strip()
39
+ # Render y otros proxies envían múltiples IPs separados por coma
40
+ ips = [ip.strip() for ip in x_forwarded_for.split(",") if ip.strip()]
41
+ if ips:
42
+ return ips[0] # la primera IP es la IP real del cliente
43
+ # Si no hay X-Forwarded-For, tomar REMOTE_ADDR
34
44
  return request.META.get("REMOTE_ADDR", "")
35
45
 
36
- def extract_body(request):
46
+ def extract_payload(request):
47
+ """Extrae datos útiles de la solicitud para análisis."""
48
+ parts = []
37
49
  try:
38
50
  if "application/json" in request.META.get("CONTENT_TYPE", ""):
39
51
  data = json.loads(request.body.decode("utf-8") or "{}")
52
+ parts.append(json.dumps(data))
40
53
  else:
41
- data = request.POST.dict() or {}
54
+ body = request.body.decode("utf-8", errors="ignore")
55
+ if body:
56
+ parts.append(body)
42
57
  except Exception:
43
- data = {}
44
- return data
58
+ pass
59
+
60
+ qs = request.META.get("QUERY_STRING", "")
61
+ if qs:
62
+ parts.append(qs)
63
+
64
+ return " ".join(parts)
45
65
 
46
- def detect_sql_injection(value: str):
47
- score_total = 0.0
48
- descripciones = []
49
- matches = []
50
66
 
67
+ def detect_sql_injection(value):
68
+ """Detecta patrones sospechosos en una cadena."""
69
+ score = 0.0
70
+ descripciones = []
51
71
  for pattern, desc, weight in SQL_PATTERNS:
52
72
  if pattern.search(value):
53
- score_total += weight
73
+ score += weight
54
74
  descripciones.append(desc)
55
- matches.append(pattern.pattern)
56
-
57
- return score_total, descripciones, matches
75
+ return score, descripciones
58
76
 
59
77
  class SQLIDefenseMiddleware(MiddlewareMixin):
78
+ """Middleware de detección SQL Injection."""
79
+
60
80
  def process_request(self, request):
61
81
  client_ip = get_client_ip(request)
62
82
  trusted_ips = getattr(settings, "SQLI_DEFENSE_TRUSTED_IPS", [])
83
+ trusted_urls = getattr(settings, "SQLI_DEFENSE_TRUSTED_URLS", [])
63
84
 
64
85
  if client_ip in trusted_ips:
65
86
  return None
66
87
 
67
- data = extract_body(request)
68
- score = 0.0
69
- all_desc = []
70
- all_matches = []
71
-
72
- for key, value in data.items():
73
- if not isinstance(value, str):
74
- continue
75
- if key.lower() in IGNORED_FIELDS:
76
- continue # No analizar contraseñas ni tokens
88
+ referer = request.META.get("HTTP_REFERER", "")
89
+ host = request.get_host()
90
+ if any(url in referer for url in trusted_urls) or any(url in host for url in trusted_urls):
91
+ return None
77
92
 
78
- s, desc, matches = detect_sql_injection(value)
79
- score += s
80
- all_desc.extend(desc)
81
- all_matches.extend(matches)
93
+ payload = extract_payload(request)
94
+ score, descripciones = detect_sql_injection(payload)
82
95
 
83
96
  if score == 0:
84
- return None # nada sospechoso
97
+ return None
85
98
 
99
+ # Registrar ataque completo
86
100
  logger.warning(
87
- f"[SQLiDetect] IP={client_ip} Score={score:.2f} Desc={all_desc} Campos={list(data.keys())}"
101
+ f"[SQLiDetect] IP={client_ip} Host={host} Referer={referer} "
102
+ f"Score={score:.2f} Desc={descripciones} Payload={payload[:500]}"
88
103
  )
89
104
 
90
- # Guardamos info en request
105
+ # Guardar información del ataque en el request
91
106
  request.sql_attack_info = {
92
107
  "ip": client_ip,
93
108
  "tipos": ["SQLi"],
94
- "descripcion": all_desc,
109
+ "descripcion": descripciones,
110
+ "payload": payload[:1000], # guardar hasta 1000 caracteres
95
111
  "score": round(score, 2),
112
+ "url": request.build_absolute_uri(), # registrar URL completa
96
113
  }
97
114
 
98
- # Bloqueamos solo si supera umbral de riesgo
99
- if score >= 0.7:
100
- from django.http import JsonResponse
101
- return JsonResponse(
102
- {"error": "Posible ataque de inyección SQL detectado. Solicitud bloqueada."},
103
- status=403
104
- )
115
+ return None
105
116
 
106
117
 
107
118
  # =====================================================
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: GuardianUnivalle-Benito-Yucra
3
- Version: 0.1.39
3
+ Version: 0.1.41
4
4
  Summary: Middleware y detectores de seguridad (SQLi, XSS, CSRF, DoS, Keylogger) para Django/Flask
5
5
  Author-email: Andres Benito Calle Yucra <benitoandrescalle035@gmail.com>
6
6
  License: MIT
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: GuardianUnivalle-Benito-Yucra
3
- Version: 0.1.39
3
+ Version: 0.1.41
4
4
  Summary: Middleware y detectores de seguridad (SQLi, XSS, CSRF, DoS, Keylogger) para Django/Flask
5
5
  Author-email: Andres Benito Calle Yucra <benitoandrescalle035@gmail.com>
6
6
  License: MIT
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "GuardianUnivalle-Benito-Yucra" # usar mayúsculas consistente
7
- version = "0.1.39"
7
+ version = "0.1.41"
8
8
  description = "Middleware y detectores de seguridad (SQLi, XSS, CSRF, DoS, Keylogger) para Django/Flask"
9
9
  authors = [
10
10
  { name = "Andres Benito Calle Yucra", email = "benitoandrescalle035@gmail.com" }