GuardianUnivalle-Benito-Yucra 0.1.47__tar.gz → 0.1.49__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 (28) hide show
  1. guardianunivalle_benito_yucra-0.1.49/GuardianUnivalle_Benito_Yucra/auditoria/auditoria_servidor.py +124 -0
  2. guardianunivalle_benito_yucra-0.1.49/GuardianUnivalle_Benito_Yucra/auditoria/registro_auditoria.py +40 -0
  3. {guardianunivalle_benito_yucra-0.1.47 → guardianunivalle_benito_yucra-0.1.49}/GuardianUnivalle_Benito_Yucra.egg-info/PKG-INFO +1 -1
  4. {guardianunivalle_benito_yucra-0.1.47 → guardianunivalle_benito_yucra-0.1.49}/GuardianUnivalle_Benito_Yucra.egg-info/SOURCES.txt +1 -1
  5. {guardianunivalle_benito_yucra-0.1.47 → guardianunivalle_benito_yucra-0.1.49}/PKG-INFO +1 -1
  6. {guardianunivalle_benito_yucra-0.1.47 → guardianunivalle_benito_yucra-0.1.49}/pyproject.toml +1 -1
  7. guardianunivalle_benito_yucra-0.1.47/GuardianUnivalle_Benito_Yucra/auditoria/registro_auditoria.py +0 -118
  8. guardianunivalle_benito_yucra-0.1.47/GuardianUnivalle_Benito_Yucra/auditoria/utils_auditoria.py +0 -57
  9. {guardianunivalle_benito_yucra-0.1.47 → guardianunivalle_benito_yucra-0.1.49}/GuardianUnivalle_Benito_Yucra/__init__.py +0 -0
  10. {guardianunivalle_benito_yucra-0.1.47 → guardianunivalle_benito_yucra-0.1.49}/GuardianUnivalle_Benito_Yucra/criptografia/cifrado_aead.py +0 -0
  11. {guardianunivalle_benito_yucra-0.1.47 → guardianunivalle_benito_yucra-0.1.49}/GuardianUnivalle_Benito_Yucra/criptografia/intercambio_claves.py +0 -0
  12. {guardianunivalle_benito_yucra-0.1.47 → guardianunivalle_benito_yucra-0.1.49}/GuardianUnivalle_Benito_Yucra/criptografia/kdf.py +0 -0
  13. {guardianunivalle_benito_yucra-0.1.47 → guardianunivalle_benito_yucra-0.1.49}/GuardianUnivalle_Benito_Yucra/detectores/detector_csrf.py +0 -0
  14. {guardianunivalle_benito_yucra-0.1.47 → guardianunivalle_benito_yucra-0.1.49}/GuardianUnivalle_Benito_Yucra/detectores/detector_dos.py +0 -0
  15. {guardianunivalle_benito_yucra-0.1.47 → guardianunivalle_benito_yucra-0.1.49}/GuardianUnivalle_Benito_Yucra/detectores/detector_keylogger.py +0 -0
  16. {guardianunivalle_benito_yucra-0.1.47 → guardianunivalle_benito_yucra-0.1.49}/GuardianUnivalle_Benito_Yucra/detectores/detector_sql.py +0 -0
  17. {guardianunivalle_benito_yucra-0.1.47 → guardianunivalle_benito_yucra-0.1.49}/GuardianUnivalle_Benito_Yucra/detectores/detector_xss.py +0 -0
  18. {guardianunivalle_benito_yucra-0.1.47 → guardianunivalle_benito_yucra-0.1.49}/GuardianUnivalle_Benito_Yucra/middleware_web/middleware_web.py +0 -0
  19. {guardianunivalle_benito_yucra-0.1.47 → guardianunivalle_benito_yucra-0.1.49}/GuardianUnivalle_Benito_Yucra/mitigacion/limitador_peticion.py +0 -0
  20. {guardianunivalle_benito_yucra-0.1.47 → guardianunivalle_benito_yucra-0.1.49}/GuardianUnivalle_Benito_Yucra/mitigacion/lista_bloqueo.py +0 -0
  21. {guardianunivalle_benito_yucra-0.1.47 → guardianunivalle_benito_yucra-0.1.49}/GuardianUnivalle_Benito_Yucra/puntuacion/puntuacion_amenaza.py +0 -0
  22. {guardianunivalle_benito_yucra-0.1.47 → guardianunivalle_benito_yucra-0.1.49}/GuardianUnivalle_Benito_Yucra/utilidades.py +0 -0
  23. {guardianunivalle_benito_yucra-0.1.47 → guardianunivalle_benito_yucra-0.1.49}/GuardianUnivalle_Benito_Yucra.egg-info/dependency_links.txt +0 -0
  24. {guardianunivalle_benito_yucra-0.1.47 → guardianunivalle_benito_yucra-0.1.49}/GuardianUnivalle_Benito_Yucra.egg-info/requires.txt +0 -0
  25. {guardianunivalle_benito_yucra-0.1.47 → guardianunivalle_benito_yucra-0.1.49}/GuardianUnivalle_Benito_Yucra.egg-info/top_level.txt +0 -0
  26. {guardianunivalle_benito_yucra-0.1.47 → guardianunivalle_benito_yucra-0.1.49}/LICENSE +0 -0
  27. {guardianunivalle_benito_yucra-0.1.47 → guardianunivalle_benito_yucra-0.1.49}/README.md +0 -0
  28. {guardianunivalle_benito_yucra-0.1.47 → guardianunivalle_benito_yucra-0.1.49}/setup.cfg +0 -0
@@ -0,0 +1,124 @@
1
+ import logging
2
+ import json
3
+ import platform
4
+ import socket
5
+ import uuid
6
+ from datetime import datetime
7
+ from django.utils.deprecation import MiddlewareMixin
8
+
9
+ logger = logging.getLogger("auditoria_servidor")
10
+ logger.setLevel(logging.INFO)
11
+ if not logger.handlers:
12
+ handler = logging.StreamHandler()
13
+ handler.setFormatter(logging.Formatter("%(asctime)s - %(levelname)s - %(message)s"))
14
+ logger.addHandler(handler)
15
+
16
+
17
+ def obtener_datos_maquina(request):
18
+ """
19
+ Retorna un diccionario con información del cliente y del servidor.
20
+ No accede a ningún modelo Django.
21
+ """
22
+ datos = {}
23
+ try:
24
+ # Datos del cliente
25
+ datos["ip"] = request.META.get("HTTP_X_FORWARDED_FOR", "").split(",")[0] or request.META.get("REMOTE_ADDR", "")
26
+ datos["user_agent"] = request.META.get("HTTP_USER_AGENT", "")
27
+ datos["navegador"] = datos["user_agent"].split("/")[0] if "/" in datos["user_agent"] else datos["user_agent"]
28
+ datos["sistema_operativo"] = platform.system()
29
+ datos["url"] = request.build_absolute_uri()
30
+ datos["fecha"] = datetime.now().isoformat()
31
+
32
+ # Datos del servidor
33
+ datos["servidor_nombre"] = socket.gethostname()
34
+ datos["servidor_ip"] = socket.gethostbyname(socket.gethostname())
35
+ datos["servidor_uuid"] = str(uuid.uuid4())
36
+ except Exception as e:
37
+ logger.error(f"Error obteniendo datos de máquina: {e}")
38
+ return datos
39
+
40
+
41
+ def analizar_comportamiento_cliente(datos):
42
+ """
43
+ Analiza los datos del cliente y retorna una evaluación general:
44
+ (nivel_severidad, descripcion)
45
+ """
46
+ if not datos:
47
+ return "BAJA", "Sin datos del cliente"
48
+
49
+ ip = datos.get("ip", "")
50
+ navegador = datos.get("navegador", "")
51
+ descripcion = f"Actividad detectada desde IP {ip} con navegador {navegador}"
52
+
53
+ if "bot" in navegador.lower():
54
+ return "MEDIA", descripcion + " (posible bot)"
55
+ return "BAJA", descripcion
56
+
57
+
58
+ def registrar_evento(tipo, descripcion, severidad="BAJA", extra=None):
59
+ """
60
+ Registra un evento en los logs (la BD será manejada por el backend Django).
61
+ """
62
+ try:
63
+ registro = {
64
+ "tipo": tipo,
65
+ "descripcion": descripcion,
66
+ "severidad": severidad,
67
+ "fecha": datetime.now().isoformat(),
68
+ "extra": extra or {},
69
+ }
70
+ logger.info("[AUDITORIA] %s", json.dumps(registro, ensure_ascii=False))
71
+ return registro
72
+ except Exception as e:
73
+ logger.error(f"Error registrando evento: {e}")
74
+ return None
75
+
76
+
77
+ class AuditoriaServidorMiddleware(MiddlewareMixin):
78
+ """
79
+ Middleware que integra toda la información generada por los detectores (SQLi, XSS, etc.)
80
+ y la deja lista en request.guardian_auditoria para que el backend (Django)
81
+ la guarde en la base de datos.
82
+ """
83
+
84
+ def process_request(self, request):
85
+ try:
86
+ datos_cliente = obtener_datos_maquina(request)
87
+ severidad, descripcion = analizar_comportamiento_cliente(datos_cliente)
88
+
89
+ # Base del registro
90
+ registro_base = {
91
+ "datos_cliente": datos_cliente,
92
+ "descripcion": descripcion,
93
+ "severidad": severidad,
94
+ "eventos_detectados": [],
95
+ }
96
+
97
+ # Integrar información de ataques detectada por otros middlewares
98
+ if hasattr(request, "sql_attack_info"):
99
+ registro_base["eventos_detectados"].append(request.sql_attack_info)
100
+
101
+ if hasattr(request, "xss_attack_info"):
102
+ registro_base["eventos_detectados"].append(request.xss_attack_info)
103
+
104
+ if hasattr(request, "csrf_attack_info"):
105
+ registro_base["eventos_detectados"].append(request.csrf_attack_info)
106
+
107
+ if hasattr(request, "dos_attack_info"):
108
+ registro_base["eventos_detectados"].append(request.dos_attack_info)
109
+
110
+ # Si hubo algún evento sospechoso
111
+ if registro_base["eventos_detectados"]:
112
+ registrar_evento(
113
+ tipo="ATAQUE_DETECTADO",
114
+ descripcion="Se detectó comportamiento sospechoso en la solicitud",
115
+ severidad="ALTA",
116
+ extra=registro_base,
117
+ )
118
+
119
+ # Guardar la info para el backend (sin registrar aún en BD)
120
+ request.guardian_auditoria = registro_base
121
+
122
+ except Exception as e:
123
+ logger.error(f"Error en AuditoriaServidorMiddleware: {e}")
124
+ return None
@@ -0,0 +1,40 @@
1
+ import os
2
+ import datetime
3
+ import json
4
+
5
+ LOG_FILE = "auditoria_guardian.log"
6
+
7
+
8
+ def registrar_evento(
9
+ tipo: str,
10
+ descripcion: str = "",
11
+ severidad: str = "MEDIA",
12
+ extra: dict | None = None,
13
+ ):
14
+ try:
15
+ evento = {
16
+ "fecha": datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
17
+ "tipo": tipo,
18
+ "descripcion": descripcion,
19
+ "severidad": severidad,
20
+ "extra": extra or {},
21
+ }
22
+
23
+ # ✅ Crear carpeta solo si hay directorio en la ruta
24
+ log_dir = os.path.dirname(LOG_FILE)
25
+ if log_dir:
26
+ os.makedirs(log_dir, exist_ok=True)
27
+
28
+ with open(LOG_FILE, "a", encoding="utf-8") as f:
29
+ f.write(json.dumps(evento, ensure_ascii=False) + "\n")
30
+
31
+ except Exception as e:
32
+ print(f"[Auditoría] Error al registrar evento: {e}")
33
+
34
+
35
+ def generar_reporte() -> str:
36
+ """Devuelve todo el contenido del archivo de auditoría."""
37
+ if not os.path.exists(LOG_FILE):
38
+ return "No hay registros aún."
39
+ with open(LOG_FILE, "r", encoding="utf-8") as f:
40
+ return f.read()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: GuardianUnivalle-Benito-Yucra
3
- Version: 0.1.47
3
+ Version: 0.1.49
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
@@ -9,8 +9,8 @@ GuardianUnivalle_Benito_Yucra.egg-info/SOURCES.txt
9
9
  GuardianUnivalle_Benito_Yucra.egg-info/dependency_links.txt
10
10
  GuardianUnivalle_Benito_Yucra.egg-info/requires.txt
11
11
  GuardianUnivalle_Benito_Yucra.egg-info/top_level.txt
12
+ GuardianUnivalle_Benito_Yucra/auditoria/auditoria_servidor.py
12
13
  GuardianUnivalle_Benito_Yucra/auditoria/registro_auditoria.py
13
- GuardianUnivalle_Benito_Yucra/auditoria/utils_auditoria.py
14
14
  GuardianUnivalle_Benito_Yucra/criptografia/cifrado_aead.py
15
15
  GuardianUnivalle_Benito_Yucra/criptografia/intercambio_claves.py
16
16
  GuardianUnivalle_Benito_Yucra/criptografia/kdf.py
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: GuardianUnivalle-Benito-Yucra
3
- Version: 0.1.47
3
+ Version: 0.1.49
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.47"
7
+ version = "0.1.49"
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" }
@@ -1,118 +0,0 @@
1
- import os
2
- import datetime
3
- import json
4
- import platform
5
- from django.utils import timezone
6
-
7
- LOG_FILE = "auditoria_guardian.log"
8
-
9
- # =====================================================
10
- # === FUNCIONES DE CAPTURA Y ANÁLISIS DE CLIENTE ===
11
- # =====================================================
12
- def capturar_datos_cliente(request) -> dict:
13
- """Extrae información útil del cliente que accede al sistema."""
14
- ip = request.META.get("HTTP_X_FORWARDED_FOR")
15
- if ip:
16
- ip = ip.split(",")[0].strip()
17
- else:
18
- ip = request.META.get("REMOTE_ADDR", "Desconocida")
19
-
20
- user_agent = request.META.get("HTTP_USER_AGENT", "Desconocido")
21
- metodo = request.method
22
- ruta = request.path
23
- parametros = request.GET.dict() if metodo == "GET" else request.POST.dict()
24
- so_servidor = platform.system()
25
-
26
- return {
27
- "ip_cliente": ip,
28
- "navegador": user_agent,
29
- "metodo": metodo,
30
- "ruta": ruta,
31
- "parametros": parametros,
32
- "servidor_os": so_servidor,
33
- "hora_servidor": timezone.now().strftime("%Y-%m-%d %H:%M:%S"),
34
- }
35
-
36
-
37
- def analizar_comportamiento_cliente(datos_cliente: dict) -> tuple[str, str]:
38
- """
39
- Aplica reglas básicas de detección:
40
- - IP sospechosa o repetitiva
41
- - Agente extraño o vacío
42
- - Peticiones sospechosas (ej: /admin, /etc/passwd)
43
- Devuelve: (nivel_riesgo, descripcion)
44
- """
45
- descripcion = []
46
- riesgo = "BAJO"
47
-
48
- ip = datos_cliente.get("ip_cliente", "")
49
- user_agent = datos_cliente.get("navegador", "").lower()
50
- ruta = datos_cliente.get("ruta", "")
51
-
52
- # === Reglas simples ===
53
- if not user_agent or "curl" in user_agent or "python" in user_agent:
54
- descripcion.append("Agente de usuario anómalo (posible bot o script).")
55
- riesgo = "MEDIO"
56
-
57
- if "admin" in ruta or "etc/passwd" in ruta or "../" in ruta:
58
- descripcion.append("Ruta sospechosa accedida.")
59
- riesgo = "ALTO"
60
-
61
- if "Desconocida" in ip or ip.startswith("192.168.") is False:
62
- descripcion.append(f"IP externa detectada: {ip}")
63
- riesgo = "MEDIO"
64
-
65
- # Comportamiento sin parámetros ni cabeceras
66
- if not datos_cliente.get("parametros"):
67
- descripcion.append("Petición sin parámetros ni cabeceras útiles.")
68
- riesgo = "BAJO"
69
-
70
- if not descripcion:
71
- descripcion.append("Acceso normal detectado.")
72
-
73
- return riesgo, " | ".join(descripcion)
74
-
75
-
76
- # =====================================================
77
- # === FUNCIÓN PRINCIPAL DE REGISTRO ===
78
- # =====================================================
79
- def registrar_evento(request, tipo: str = "ACCESO", extra: dict | None = None):
80
- """Registra un evento de auditoría detallado del cliente."""
81
- try:
82
- datos_cliente = capturar_datos_cliente(request)
83
- severidad, descripcion = analizar_comportamiento_cliente(datos_cliente)
84
-
85
- evento = {
86
- "fecha": datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
87
- "tipo": tipo,
88
- "descripcion": descripcion,
89
- "severidad": severidad,
90
- "cliente": datos_cliente,
91
- "extra": extra or {},
92
- }
93
-
94
- # Crear carpeta solo si hay directorio en la ruta
95
- log_dir = os.path.dirname(LOG_FILE)
96
- if log_dir:
97
- os.makedirs(log_dir, exist_ok=True)
98
-
99
- # Registrar en archivo
100
- with open(LOG_FILE, "a", encoding="utf-8") as f:
101
- f.write(json.dumps(evento, ensure_ascii=False) + "\n")
102
-
103
- # (Opcional) Log en consola
104
- print(f"[AUDITORÍA] Evento registrado: {evento['descripcion']} (nivel {severidad})")
105
-
106
- except Exception as e:
107
- print(f"[Auditoría] Error al registrar evento: {e}")
108
-
109
-
110
- # =====================================================
111
- # === CONSULTA DE REGISTROS ===
112
- # =====================================================
113
- def generar_reporte() -> str:
114
- """Devuelve todo el contenido del archivo de auditoría."""
115
- if not os.path.exists(LOG_FILE):
116
- return "No hay registros aún."
117
- with open(LOG_FILE, "r", encoding="utf-8") as f:
118
- return f.read()
@@ -1,57 +0,0 @@
1
- import requests
2
- from django.utils.timezone import now
3
- from user_agents import parse
4
-
5
- def obtener_datos_maquina(request):
6
- """Obtiene información detallada del cliente desde la petición"""
7
- try:
8
- # --- IP real ---
9
- ip = (
10
- request.META.get("HTTP_X_FORWARDED_FOR")
11
- or request.META.get("REMOTE_ADDR")
12
- or "0.0.0.0"
13
- )
14
- ip = ip.split(",")[0].strip()
15
-
16
- # --- User Agent ---
17
- user_agent_str = request.META.get("HTTP_USER_AGENT", "Desconocido")
18
- user_agent = parse(user_agent_str)
19
- navegador = f"{user_agent.browser.family} {user_agent.browser.version_string}"
20
- sistema = f"{user_agent.os.family} {user_agent.os.version_string}"
21
-
22
- # --- Geolocalización (usando ipinfo.io gratuita) ---
23
- geo_data = {}
24
- try:
25
- r = requests.get(f"https://ipinfo.io/{ip}/json", timeout=2)
26
- if r.status_code == 200:
27
- geo_data = r.json()
28
- except Exception:
29
- pass
30
-
31
- pais = geo_data.get("country", "Desconocido")
32
- ciudad = geo_data.get("city", "Desconocida")
33
- isp = geo_data.get("org", "Desconocido")
34
-
35
- # --- Usuario autenticado ---
36
- usuario = "Anónimo"
37
- if request.user and request.user.is_authenticated:
38
- usuario = request.user.username
39
-
40
- # --- Construir estructura ---
41
- datos = {
42
- "fecha": now().strftime("%Y-%m-%d %H:%M:%S"),
43
- "ip": ip,
44
- "pais": pais,
45
- "ciudad": ciudad,
46
- "isp": isp,
47
- "usuario": usuario,
48
- "user_agent": user_agent_str,
49
- "navegador": navegador,
50
- "sistema_operativo": sistema,
51
- "url": request.path,
52
- "metodo": request.method,
53
- }
54
-
55
- return datos
56
- except Exception as e:
57
- return {"error": str(e)}