GuardianUnivalle-Benito-Yucra 0.1.39__tar.gz → 0.1.40__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.40}/GuardianUnivalle_Benito_Yucra/detectores/detector_sql.py +44 -41
  2. {guardianunivalle_benito_yucra-0.1.39 → guardianunivalle_benito_yucra-0.1.40}/GuardianUnivalle_Benito_Yucra.egg-info/PKG-INFO +1 -1
  3. {guardianunivalle_benito_yucra-0.1.39 → guardianunivalle_benito_yucra-0.1.40}/PKG-INFO +1 -1
  4. {guardianunivalle_benito_yucra-0.1.39 → guardianunivalle_benito_yucra-0.1.40}/pyproject.toml +1 -1
  5. {guardianunivalle_benito_yucra-0.1.39 → guardianunivalle_benito_yucra-0.1.40}/GuardianUnivalle_Benito_Yucra/__init__.py +0 -0
  6. {guardianunivalle_benito_yucra-0.1.39 → guardianunivalle_benito_yucra-0.1.40}/GuardianUnivalle_Benito_Yucra/auditoria/registro_auditoria.py +0 -0
  7. {guardianunivalle_benito_yucra-0.1.39 → guardianunivalle_benito_yucra-0.1.40}/GuardianUnivalle_Benito_Yucra/criptografia/cifrado_aead.py +0 -0
  8. {guardianunivalle_benito_yucra-0.1.39 → guardianunivalle_benito_yucra-0.1.40}/GuardianUnivalle_Benito_Yucra/criptografia/intercambio_claves.py +0 -0
  9. {guardianunivalle_benito_yucra-0.1.39 → guardianunivalle_benito_yucra-0.1.40}/GuardianUnivalle_Benito_Yucra/criptografia/kdf.py +0 -0
  10. {guardianunivalle_benito_yucra-0.1.39 → guardianunivalle_benito_yucra-0.1.40}/GuardianUnivalle_Benito_Yucra/detectores/detector_csrf.py +0 -0
  11. {guardianunivalle_benito_yucra-0.1.39 → guardianunivalle_benito_yucra-0.1.40}/GuardianUnivalle_Benito_Yucra/detectores/detector_dos.py +0 -0
  12. {guardianunivalle_benito_yucra-0.1.39 → guardianunivalle_benito_yucra-0.1.40}/GuardianUnivalle_Benito_Yucra/detectores/detector_keylogger.py +0 -0
  13. {guardianunivalle_benito_yucra-0.1.39 → guardianunivalle_benito_yucra-0.1.40}/GuardianUnivalle_Benito_Yucra/detectores/detector_xss.py +0 -0
  14. {guardianunivalle_benito_yucra-0.1.39 → guardianunivalle_benito_yucra-0.1.40}/GuardianUnivalle_Benito_Yucra/middleware_web/middleware_web.py +0 -0
  15. {guardianunivalle_benito_yucra-0.1.39 → guardianunivalle_benito_yucra-0.1.40}/GuardianUnivalle_Benito_Yucra/mitigacion/limitador_peticion.py +0 -0
  16. {guardianunivalle_benito_yucra-0.1.39 → guardianunivalle_benito_yucra-0.1.40}/GuardianUnivalle_Benito_Yucra/mitigacion/lista_bloqueo.py +0 -0
  17. {guardianunivalle_benito_yucra-0.1.39 → guardianunivalle_benito_yucra-0.1.40}/GuardianUnivalle_Benito_Yucra/puntuacion/puntuacion_amenaza.py +0 -0
  18. {guardianunivalle_benito_yucra-0.1.39 → guardianunivalle_benito_yucra-0.1.40}/GuardianUnivalle_Benito_Yucra/utilidades.py +0 -0
  19. {guardianunivalle_benito_yucra-0.1.39 → guardianunivalle_benito_yucra-0.1.40}/GuardianUnivalle_Benito_Yucra.egg-info/SOURCES.txt +0 -0
  20. {guardianunivalle_benito_yucra-0.1.39 → guardianunivalle_benito_yucra-0.1.40}/GuardianUnivalle_Benito_Yucra.egg-info/dependency_links.txt +0 -0
  21. {guardianunivalle_benito_yucra-0.1.39 → guardianunivalle_benito_yucra-0.1.40}/GuardianUnivalle_Benito_Yucra.egg-info/requires.txt +0 -0
  22. {guardianunivalle_benito_yucra-0.1.39 → guardianunivalle_benito_yucra-0.1.40}/GuardianUnivalle_Benito_Yucra.egg-info/top_level.txt +0 -0
  23. {guardianunivalle_benito_yucra-0.1.39 → guardianunivalle_benito_yucra-0.1.40}/LICENSE +0 -0
  24. {guardianunivalle_benito_yucra-0.1.39 → guardianunivalle_benito_yucra-0.1.40}/README.md +0 -0
  25. {guardianunivalle_benito_yucra-0.1.39 → guardianunivalle_benito_yucra-0.1.40}/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,85 @@ 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
+ """Obtiene la IP real del cliente."""
31
34
  x_forwarded_for = request.META.get("HTTP_X_FORWARDED_FOR")
32
35
  if x_forwarded_for:
33
36
  return x_forwarded_for.split(",")[0].strip()
34
37
  return request.META.get("REMOTE_ADDR", "")
35
38
 
36
- def extract_body(request):
39
+
40
+ def extract_payload(request):
41
+ """Extrae datos útiles de la solicitud para análisis."""
42
+ parts = []
37
43
  try:
38
44
  if "application/json" in request.META.get("CONTENT_TYPE", ""):
39
45
  data = json.loads(request.body.decode("utf-8") or "{}")
46
+ parts.append(json.dumps(data))
40
47
  else:
41
- data = request.POST.dict() or {}
48
+ body = request.body.decode("utf-8", errors="ignore")
49
+ if body:
50
+ parts.append(body)
42
51
  except Exception:
43
- data = {}
44
- return data
52
+ pass
45
53
 
46
- def detect_sql_injection(value: str):
47
- score_total = 0.0
48
- descripciones = []
49
- matches = []
54
+ qs = request.META.get("QUERY_STRING", "")
55
+ if qs:
56
+ parts.append(qs)
57
+
58
+ return " ".join(parts)
50
59
 
60
+
61
+ def detect_sql_injection(value):
62
+ """Detecta patrones sospechosos en una cadena."""
63
+ score = 0.0
64
+ descripciones = []
51
65
  for pattern, desc, weight in SQL_PATTERNS:
52
66
  if pattern.search(value):
53
- score_total += weight
67
+ score += weight
54
68
  descripciones.append(desc)
55
- matches.append(pattern.pattern)
56
-
57
- return score_total, descripciones, matches
69
+ return score, descripciones
58
70
 
59
71
  class SQLIDefenseMiddleware(MiddlewareMixin):
72
+ """Middleware de detección SQL Injection."""
73
+
60
74
  def process_request(self, request):
61
75
  client_ip = get_client_ip(request)
62
76
  trusted_ips = getattr(settings, "SQLI_DEFENSE_TRUSTED_IPS", [])
77
+ trusted_urls = getattr(settings, "SQLI_DEFENSE_TRUSTED_URLS", [])
63
78
 
79
+ # Ignorar si la IP es confiable
64
80
  if client_ip in trusted_ips:
65
81
  return None
66
82
 
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
83
+ # Ignorar si la URL de referencia (Referer) o Host está en la lista de URLs confiables
84
+ referer = request.META.get("HTTP_REFERER", "")
85
+ host = request.get_host()
86
+ if any(url in referer for url in trusted_urls) or any(url in host for url in trusted_urls):
87
+ return None
77
88
 
78
- s, desc, matches = detect_sql_injection(value)
79
- score += s
80
- all_desc.extend(desc)
81
- all_matches.extend(matches)
89
+ payload = extract_payload(request)
90
+ score, descripciones = detect_sql_injection(payload)
82
91
 
83
92
  if score == 0:
84
- return None # nada sospechoso
93
+ return None
85
94
 
86
95
  logger.warning(
87
- f"[SQLiDetect] IP={client_ip} Score={score:.2f} Desc={all_desc} Campos={list(data.keys())}"
96
+ f"[SQLiDetect] IP={client_ip} Score={score:.2f} Desc={descripciones} Payload={payload[:200]}"
88
97
  )
89
98
 
90
- # Guardamos info en request
91
99
  request.sql_attack_info = {
92
100
  "ip": client_ip,
93
101
  "tipos": ["SQLi"],
94
- "descripcion": all_desc,
102
+ "descripcion": descripciones,
103
+ "payload": payload[:500],
95
104
  "score": round(score, 2),
96
105
  }
97
106
 
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
- )
107
+ return None
105
108
 
106
109
 
107
110
  # =====================================================
@@ -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.40
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.40
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.40"
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" }