GuardianUnivalle-Benito-Yucra 0.1.59__py3-none-any.whl → 0.1.61__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.

@@ -6,6 +6,9 @@ import logging
6
6
  import re
7
7
  from django.utils.deprecation import MiddlewareMixin
8
8
  from django.conf import settings
9
+ import urllib.parse
10
+ import html
11
+ from typing import List, Tuple, Dict
9
12
 
10
13
  logger = logging.getLogger("sqlidefense")
11
14
  logger.setLevel(logging.INFO)
@@ -15,19 +18,97 @@ if not logger.handlers:
15
18
  logger.addHandler(handler)
16
19
 
17
20
  # =====================================================
18
- # === PATRONES DE ATAQUE SQL DEFINIDOS ===
21
+ # ===        PATRONES DE ATAQUE SQL DEFINIDOS       ===
19
22
  # =====================================================
20
- SQL_PATTERNS = [
21
- (re.compile(r"\bunion\b\s+(all\s+)?\bselect\b", re.I), "Uso de UNION SELECT", 0.7),
22
- (re.compile(r"\bor\b\s+'?\d+'?\s*=\s*'?\d+'?", re.I), "Tautología OR 1=1", 0.6),
23
- (re.compile(r"\bselect\b.+\bfrom\b", re.I), "Consulta SQL SELECT-FROM", 0.5),
24
- (re.compile(r"(--|#|/\*|\*/)", re.I), "Comentario SQL sospechoso", 0.4),
25
- (re.compile(r"\b(drop|truncate|delete|insert|update)\b", re.I), "Manipulación SQL", 0.5),
26
- (re.compile(r"exec\s*\(", re.I), "Ejecución de procedimiento almacenado", 0.6),
23
+ SQL_PATTERNS: List[Tuple[re.Pattern, str, float]] = [
24
+ # ------------------ In‑Band / Exfiltration (muy alto) ------------------
25
+ (re.compile(r"\bunion\b\s+(all\s+)?\bselect\b", re.I), "UNION SELECT (exfiltración)", 0.95),
26
+ (re.compile(r"\bselect\b\s+.*\bfrom\b\s+.+\bwhere\b", re.I | re.S), "SELECT ... FROM ... WHERE (consulta completa)", 0.7),
27
+ (re.compile(r"\binto\s+outfile\b|\binto\s+dumpfile\b", re.I), "INTO OUTFILE / INTO DUMPFILE (volcado a fichero)", 0.98),
28
+ (re.compile(r"\bload_file\s*\(", re.I), "LOAD_FILE() (lectura fichero MySQL)", 0.95),
29
+ (re.compile(r"\b(pg_read_file|pg_read_binary_file|pg_ls_dir)\s*\(", re.I), "pg_read_file / funciones lectura Postgres", 0.95),
30
+ (re.compile(r"\bfile_read\b|\bfile_get_contents\b", re.I), "Indicadores de lectura de fichero en código", 0.85),
31
+
32
+ # ------------------ Time‑based / Blind (muy alto) ------------------
33
+ (re.compile(r"\b(sleep|benchmark|pg_sleep|dbms_lock\.sleep|waitfor\s+delay)\b\s*\(", re.I), "SLEEP/pg_sleep/WAITFOR DELAY (time‑based blind)", 0.98),
34
+ (re.compile(r"\bbenchmark\s*\(", re.I), "BENCHMARK() MySQL (time/DoS)", 0.9),
35
+
36
+ # ------------------ Error‑based extraction (muy alto) ------------------
37
+ (re.compile(r"\b(updatexml|extractvalue|xmltype|utl_http\.request|dbms_xmlquery)\b\s*\(", re.I), "Funciones que devuelven errores con contenido (error‑based)", 0.95),
38
+ (re.compile(r"\bconvert\(\s*.*\s+using\s+.*\)", re.I), "CONVERT ... USING (encoding conversions potenciales)", 0.7),
39
+
40
+ # ------------------ OOB / Callbacks / Exfiltration (muy alto) ------------------
41
+ (re.compile(r"\b(nslookup|dnslookup|xp_dirtree|xp_dirtree\(|xp_regread|xp\w+)\b", re.I),
42
+ "Funciones/procs que pueden generar exfiltración OOB (DNS/SMB/SMB callbacks)", 0.95),
43
+ (re.compile(r"\b(utl_http\.request|utl_tcp\.socket|http_client|apex_web_service\.make_rest_request)\b", re.I),
44
+ "UTL_HTTP/HTTP callbacks (Oracle/PLSQL HTTP OOB)", 0.95),
45
+
46
+ # ------------------ Execution / OS commands (muy alto) ------------------
47
+ (re.compile(r"\bxp_cmdshell\b|\bexec\s+xp\w+|\bsp_oacreate\b", re.I), "xp_cmdshell / sp_oacreate (ejecución OS MSSQL/Oracle)", 0.98),
48
+ (re.compile(r"\b(exec\s+master\..*xp\w+|sp_executesql|execute\s+immediate|EXEC\s+UTE)\b", re.I), "Ejecución dinámica / sp_executesql / EXECUTE IMMEDIATE", 0.95),
49
+
50
+ # ------------------ Metadata / Recon (alto) ------------------
51
+ (re.compile(r"\binformation_schema\b", re.I), "INFORMATION_SCHEMA (recon meta‑datos)", 0.92),
52
+ (re.compile(r"\b(information_schema\.tables|information_schema\.columns)\b", re.I), "INFORMATION_SCHEMA.tables/columns", 0.92),
53
+ (re.compile(r"\b(sys\.tables|sys\.objects|sys\.databases|pg_catalog|pg_tables|pg_user)\b", re.I), "Catalogos del sistema (MSSQL/Postgres)", 0.9),
54
+
55
+ # ------------------ DML/DDL Destructivo (alto) ------------------
56
+ (re.compile(r"\b(drop\s+table|truncate\s+table|drop\s+database|drop\s+schema)\b", re.I), "DROP/TRUNCATE (DDL destructivo)", 0.95),
57
+ (re.compile(r"\b(delete\s+from|update\s+.+\s+set|insert\s+into)\b", re.I), "DML (DELETE/UPDATE/INSERT potencialmente destructivo)", 0.85),
58
+
59
+ # ------------------ Stacked queries (medio‑alto) ------------------
60
+ (re.compile(r";\s*(select|insert|update|delete|drop|create|truncate)\b", re.I), "Stacked queries (uso de ';' para apilar)", 0.88),
61
+
62
+ # ------------------ Tautologías / Boolean Blind (medio‑alto) ------------------
63
+ (re.compile(r"\b(or|and)\b\s+(['\"]?\d+['\"]?)\s*=\s*\1", re.I), "Tautología OR/AND 'x'='x' o 1=1", 0.85),
64
+ (re.compile(r"(['\"]).{0,10}\1\s*or\s*['\"][^']*['\"]\s*=\s*['\"][^']*['\"]", re.I), "Tautología clásica en cadenas (OR '1'='1')", 0.8),
65
+
66
+ # ------------------ Blind‑boolean extraction functions (medio) ------------------
67
+ (re.compile(r"\b(substring|substr|mid|left|right)\b\s*\(", re.I), "SUBSTRING/SUBSTR/LEFT/RIGHT (blind extraction)", 0.82),
68
+ (re.compile(r"\b(ascii|char|chr|nchr)\b\s*\(", re.I), "ASCII/CHAR/CHR (byte/char extraction)", 0.8),
69
+
70
+ # ------------------ Error / XPATH / XML (alto) ------------------
71
+ (re.compile(r"\b(updatexml|extractvalue|xmltype|xmlelement)\b\s*\(", re.I), "updatexml/extractvalue/xmltype (error/XPath leaks)", 0.93),
72
+
73
+ # ------------------ File system / I/O (alto) ------------------
74
+ (re.compile(r"\binto\s+outfile\b|\binto\s+dumpfile\b", re.I), "INTO OUTFILE / DUMPFILE (escritura en servidor)", 0.97),
75
+ (re.compile(r"\bopenrowset\b|\bbulk\s+insert\b|\bcopy\s+to\b", re.I), "OPENROWSET / BULK INSERT / COPY TO (exportación)", 0.92),
76
+
77
+ # ------------------ Encoding / Obfuscation (medio) ------------------
78
+ (re.compile(r"0x[0-9a-fA-F]+", re.I), "Hex literal (0x...) (ofuscación)", 0.6),
79
+ (re.compile(r"\\x[0-9a-fA-F]{2}", re.I), "Escapes hex tipo \\xNN (ofuscación)", 0.6),
80
+ (re.compile(r"&#x[0-9a-fA-F]+;|&#\d+;", re.I), "Entidades HTML / entidades numéricas (ofuscación)", 0.6),
81
+ (re.compile(r"\bchar\s*\(\s*\d+\s*\)", re.I), "CHAR(n) usado para construir cadenas (ofuscación)", 0.65),
82
+ (re.compile(r"\bconcat\(", re.I), "CONCAT() (construcción dinámica de strings)", 0.6),
83
+
84
+ # ------------------ SQL in attributes / URL encoded (medio) ------------------
85
+ (re.compile(r"%3[dD]|%27|%22|%3C|%3E|%3B", re.I), "URL encoding típico (%27, %3C, etc.)", 0.4),
86
+
87
+ # ------------------ Comments / terminators (informativo) ------------------
88
+ (re.compile(r"(--\s|#\s|/\*[\s\S]*\*/)", re.I), "Comentarios SQL (--) o /* */ o #", 0.45),
89
+
90
+ # ------------------ ORM / NonSQL indicators (informativo) ------------------
91
+ (re.compile(r"\b\$where\b|\b\$ne\b|\b\$regex\b", re.I), "NoSQL / MongoDB indicators ($where/$ne/$regex)", 0.5),
92
+
93
+ # ------------------ Tool fingerprints (informativo) ------------------
94
+ (re.compile(r"sqlmap", re.I), "Indicador de herramienta sqlmap en payload", 0.5),
95
+ (re.compile(r"hydra|nmap|nikto", re.I), "Indicador de herramientas de auditoría/scan", 0.3),
96
+
97
+ # ------------------ Misc risky tokens (informativo) ------------------
98
+ (re.compile(r"\bexecute\b\s*\(", re.I), "execute(...) (ejecución dinámica)", 0.7),
99
+ (re.compile(r"\bdeclare\b\s+@?\w+", re.I), "DECLARE variable (MSSQL/PLSQL declarations)", 0.7),
100
+
101
+ # ------------------ Low‑level heuristics (bajo) ------------------
102
+ (re.compile(r"\bselect\b\s+.*\bfrom\b", re.I), "Estructura SELECT FROM (heurístico)", 0.25),
103
+ (re.compile(r"\binsert\b\s+into\b", re.I), "INSERT INTO (heurístico)", 0.3),
104
+
105
+ # ------------------ Catch‑all aggressive patterns (usar con cuidado) ------------------
106
+ (re.compile(r"(['\"]).*?;\s*(drop|truncate|delete|update|insert)\b", re.I | re.S), "Cadena con terminador y DDL/DML (potencial ataque)", 0.9),
107
+ (re.compile(r"\b(or)\b\s+1\s*=\s*1\b", re.I), "OR 1=1 tautology", 0.85),
27
108
  ]
28
109
 
29
- IGNORED_FIELDS = ["password", "csrfmiddlewaretoken", "token", "auth"]
30
110
 
111
+ IGNORED_FIELDS = ["password", "csrfmiddlewaretoken", "token", "auth"]
31
112
 
32
113
  def get_client_ip(request):
33
114
  """
@@ -66,16 +147,88 @@ def extract_payload(request):
66
147
  return " ".join(parts)
67
148
 
68
149
 
69
- def detect_sql_injection(value):
70
- """Detecta patrones sospechosos en una cadena."""
150
+ # ----------------------------
151
+ # Normalización / preprocesamiento
152
+ # ----------------------------
153
+ def normalize_input(s: str) -> str:
154
+ """
155
+ Normaliza la entrada:
156
+ - decode URL encoding
157
+ - unescape HTML entities
158
+ - sustituye escapes de hex (\xNN) por su literal
159
+ - colapsa múltiples espacios y newlines
160
+ - lower() opcional (NO se hace porque algunos patrones usan case-insensitive)
161
+ """
162
+ if not s:
163
+ return ""
164
+ try:
165
+ # URL decode
166
+ s_dec = urllib.parse.unquote_plus(s)
167
+ except Exception:
168
+ s_dec = s
169
+ try:
170
+ # Unescape HTML entities
171
+ s_dec = html.unescape(s_dec)
172
+ except Exception:
173
+ pass
174
+ # Replace \xNN sequences visually (keep raw as text; we don't convert binary)
175
+ s_dec = re.sub(r"\\x([0-9a-fA-F]{2})", r"\\x\1", s_dec)
176
+ # Collapse whitespace
177
+ s_dec = re.sub(r"\s+", " ", s_dec)
178
+ return s_dec.strip()
179
+ # ----------------------------
180
+ # Detector: retorna score, matches y detalles
181
+ # ----------------------------
182
+ def detect_sql_injection(text: str) -> Dict:
183
+ """
184
+ Detecta coincidencias con SQL_PATTERNS en el texto normalizado.
185
+ Devuelve:
186
+ {
187
+ "score": float,
188
+ "matches": [("Etiqueta", "regex pattern string", weight), ...],
189
+ "descriptions": [ "Etiqueta", ... ],
190
+ "sample": excerpt (primeros 1200 chars)
191
+ }
192
+ """
193
+ norm = normalize_input(text or "")
71
194
  score = 0.0
72
- descripciones = []
195
+ matches = []
196
+ descriptions = []
73
197
  for pattern, desc, weight in SQL_PATTERNS:
74
- if pattern.search(value):
198
+ if pattern.search(norm):
75
199
  score += weight
76
- descripciones.append(desc)
77
- return score, descripciones
200
+ matches.append((desc, pattern.pattern, weight))
201
+ descriptions.append(desc)
202
+
203
+ return {
204
+ "score": round(score, 3),
205
+ "matches": matches,
206
+ "descriptions": list(dict.fromkeys(descriptions)), # unique
207
+ "sample": norm[:1200],
208
+ }
209
+
210
+ # ----------------------------
211
+ # Umbrales sugeridos
212
+ # ----------------------------
213
+ # - >= 1.8 : ALTA (bloquear + registrar)
214
+ # - 1.0 - <1.8 : MEDIA (registrar, desafío/2FA, throttling)
215
+ # - 0.5 - <1.0 : BAJA (registrar, monitorear)
216
+ # - <0.5 : INFORMATIVO (log heurístico)
217
+ DEFAULT_THRESHOLDS = {
218
+ "HIGH": 1.8,
219
+ "MEDIUM": 1.0,
220
+ "LOW": 0.5,
221
+ }
78
222
 
223
+ # ----------------------------
224
+ # Ejemplo de uso (snippet)
225
+ # ----------------------------
226
+ # payload = extract_payload(request) # tu función actual
227
+ # result = detect_sql_injection(payload)
228
+ # if result["score"] >= DEFAULT_THRESHOLDS["HIGH"]:
229
+ # bloquear_y_registrar()
230
+ # else:
231
+ # registrar_solo()
79
232
  class SQLIDefenseMiddleware(MiddlewareMixin):
80
233
  """Middleware de detección SQL Injection."""
81
234
 
@@ -33,17 +33,67 @@ except Exception:
33
33
  # - pesos mayores = más severo (por ejemplo <script> o javascript:)
34
34
  # - esto permite un scoring acumulativo y menos falsos positivos
35
35
  # -------------------------------------------------
36
+
36
37
  XSS_PATTERNS: List[Tuple[re.Pattern, str, float]] = [
37
- (re.compile(r"<\s*script\b", re.I), "Etiqueta <script>", 0.8),
38
- (re.compile(r"javascript\s*:", re.I), "URI javascript:", 0.7),
39
- (re.compile(r"<\s*iframe\b", re.I), "Etiqueta <iframe>", 0.7),
40
- (re.compile(r"<\s*embed\b", re.I), "Etiqueta <embed>", 0.7),
41
- (re.compile(r"<\s*object\b", re.I), "Etiqueta <object>", 0.7),
42
- (re.compile(r"on\w+\s*=", re.I), "Atributo de evento (on*)", 0.5),
43
- (re.compile(r"document\.cookie", re.I), "Acceso a document.cookie", 0.6),
44
- (re.compile(r"alert\s*\(", re.I), "Uso de alert() potencial", 0.4),
45
- # patrón para imágenes con onerror u onload (caso común)
46
- (re.compile(r"<\s*img\b[^>]*on\w+\s*=", re.I), "Imagen con evento on*", 0.6),
38
+ # ---------- Máxima severidad / ejecución directa ----------
39
+ (re.compile(r"<\s*script\b", re.I), "Etiqueta <script> (directa)", 0.95),
40
+ (re.compile(r"<\s*s\s*c\s*r\s*i\s*p\s*t\b", re.I), "Etiqueta <script> ofuscada", 0.90),
41
+ (re.compile(r"\b(document\.cookie|document\.write|document\.location|location\.href|window\.location)\b", re.I),
42
+ "Acceso a document / location (cookie/location/write)", 0.90),
43
+ (re.compile(r"\b(eval|setTimeout|setInterval|Function|new Function)\s*\(", re.I),
44
+ "Ejecución dinámica (eval/Function/setTimeout)", 0.88),
45
+
46
+ # ---------- URIs peligrosas ----------
47
+ (re.compile(r"\bjavascript\s*:", re.I), "URI javascript:", 0.85),
48
+ (re.compile(r"\bdata\s*:\s*text\/html\b", re.I), "URI data:text/html", 0.82),
49
+ (re.compile(r"\bdata\s*:\s*text\/html;base64\b", re.I), "URI data:text/html;base64", 0.82),
50
+ (re.compile(r"\bvbscript\s*:", re.I), "URI vbscript:", 0.7),
51
+
52
+ # ---------- Etiquetas y vectores alternativos ----------
53
+ (re.compile(r"<\s*(iframe|embed|object|svg|math|meta)\b", re.I), "IFrame/Embed/Object/SVG/Meta", 0.88),
54
+ (re.compile(r"<\s*img\b[^>]*\bonerror\b", re.I), "<img ... onerror>", 0.86),
55
+ (re.compile(r"<\s*svg\b[^>]*\bonload\b", re.I), "SVG con onload/on* (SVG vector)", 0.84),
56
+
57
+ # ---------- Atributos de evento (on*) ----------
58
+ (re.compile(r"\s+on[a-zA-Z]+\s*=", re.I), "Atributo de evento (on*)", 0.80),
59
+ (re.compile(r"<\s*(a|img|body|div|span|form|input|button)\b[^>]*on[a-zA-Z]+\s*=", re.I),
60
+ "Elemento con evento on* (a,img,body,...)", 0.82),
61
+
62
+ # ---------- Inyección en contextos JS / JSON / script ----------
63
+ (re.compile(r"<\s*script[^>]*>.*?</\s*script\s*>", re.I | re.S), "Script inline completo", 0.92),
64
+ (re.compile(r"'\s*;\s*alert\s*\(|\"\s*;\s*alert\s*\(", re.I), "Inyección en cadenas JS (breakout + alert)", 0.78),
65
+ (re.compile(r"\bJSON\.parse\(|\beval\(\s*JSON", re.I), "JSON parse/eval inseguro", 0.75),
66
+
67
+ # ---------- Encodings, entidades y mutaciones ----------
68
+ (re.compile(r"&#x[0-9a-fA-F]+;|&#\d+;", re.I), "Entidades HTML / encoding (posible bypass)", 0.70),
69
+ (re.compile(r"%3C\s*script|%3Cscript%3E", re.I), "Tags URL-encoded (%3Cscript)", 0.68),
70
+ (re.compile(r"(?:\\x3C|\\u003C)\s*script", re.I), "Escapes JS/Unicode que forman <script>", 0.68),
71
+
72
+ # ---------- DOM clobbering / nombres reservados ----------
73
+ (re.compile(r'\bid\s*=\s*"(?:form|image|submit|action|location|name)"', re.I), "IDs que causan DOM clobbering", 0.65),
74
+ (re.compile(r'\bname\s*=\s*"(?:form|submit|action|location)"', re.I), "Names que pueden clobber", 0.65),
75
+
76
+ # ---------- Atributos URI en tags (href/src) ----------
77
+ (re.compile(r'<\s*a\b[^>]*\bhref\s*=\s*[\'"]\s*javascript\s*:', re.I), "<a href=\"javascript:...\">", 0.84),
78
+ (re.compile(r'<\s*(img|script|iframe)\b[^>]*\bsrc\s*=\s*[\'"]\s*javascript\s*:', re.I),
79
+ "src=javascript: en tags", 0.84),
80
+
81
+ # ---------- Vectores en CSS / style ----------
82
+ (re.compile(r"\bstyle\s*=\s*[\"'][^\"']*(expression\s*\(|url\s*\(\s*javascript:)", re.I), "Estilo con expression() o url(javascript:)", 0.66),
83
+ (re.compile(r"@import\s+url\s*\(", re.I), "CSS @import posibles vectores", 0.45),
84
+
85
+ # ---------- Comentarios y CDATA para evasión ----------
86
+ (re.compile(r"<!\[CDATA\[|\/\/\s*<\s*!\s*\[CDATA\[", re.I), "CDATA o comentarios para evasión", 0.48),
87
+ (re.compile(r"<!--|-->", re.I), "Comentarios HTML (posible ofuscación/evitación)", 0.30),
88
+
89
+ # ---------- Polyglot / mutation / browser quirks ----------
90
+ (re.compile(r"(?:<\s*svg[^>]*>.*?<\s*/\s*svg\s*>)|(?:<\s*math[^>]*>)", re.I | re.S),
91
+ "SVG/MathML polyglot (vectores mutables)", 0.75),
92
+ (re.compile(r"(?:\balert\s*\(|\bconsole\.log\s*\()", re.I), "Indicadores de prueba (alert/console.log)", 0.40),
93
+
94
+ # ---------- Heurísticos de baja severidad (informativo) ----------
95
+ (re.compile(r"<\s*form\b", re.I), "Form (posible vector de ataque relacionado)", 0.25),
96
+ (re.compile(r"(onmouseover|onfocus|onmouseenter|onmouseleave)\b", re.I), "Eventos UI (mouseover/focus)", 0.45),
47
97
  ]
48
98
 
49
99
  # -------------------------------------------------
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: GuardianUnivalle-Benito-Yucra
3
- Version: 0.1.59
3
+ Version: 0.1.61
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
@@ -7,14 +7,14 @@ GuardianUnivalle_Benito_Yucra/criptografia/kdf.py,sha256=_sbepEY1qHEKga0ExrX2WRg
7
7
  GuardianUnivalle_Benito_Yucra/detectores/detector_csrf.py,sha256=q7-UsVseTtIYZz4bbpx2X0kzpDmu2Cetm7eYPJtsruA,7608
8
8
  GuardianUnivalle_Benito_Yucra/detectores/detector_dos.py,sha256=Jy4fhI-6n9wQR0quzpondcUyCA2447lDq4fmOFeM1jA,14989
9
9
  GuardianUnivalle_Benito_Yucra/detectores/detector_keylogger.py,sha256=L5RQ0Sdgg7hTU1qkZYwt7AcDqtAzT6u-jwBGo7YWfsw,8078
10
- GuardianUnivalle_Benito_Yucra/detectores/detector_sql.py,sha256=EEbnn5J7sZxnsA2a0cT1VAB4ZS7BMhQiHSeqrR2SU3A,4820
11
- GuardianUnivalle_Benito_Yucra/detectores/detector_xss.py,sha256=EDxGDaOosFJCyWTS_HkB300qL30ArxAEi-i0cVrzXyU,11027
10
+ GuardianUnivalle_Benito_Yucra/detectores/detector_sql.py,sha256=SRqnJMyLeyxrtdL3p0SxH2t1xVOtVqbj0zie5fkgCJ4,13507
11
+ GuardianUnivalle_Benito_Yucra/detectores/detector_xss.py,sha256=Cirjf1fo0j-wOO2baG8GFehAvjPy5JUF9krUg5AtofU,14452
12
12
  GuardianUnivalle_Benito_Yucra/middleware_web/middleware_web.py,sha256=23pLLYqliUoMrIC6ZEwz3hKXeDjWfHSm9vYPWGmDDik,495
13
13
  GuardianUnivalle_Benito_Yucra/mitigacion/limitador_peticion.py,sha256=ipMOebYhql-6mSyHs0ddYXOcXq9w8P_IXLlpiIqGncw,246
14
14
  GuardianUnivalle_Benito_Yucra/mitigacion/lista_bloqueo.py,sha256=6AYWII4mrmwCLHCvGTyoBxR4Oasr4raSHpFbVjqn7d8,193
15
15
  GuardianUnivalle_Benito_Yucra/puntuacion/puntuacion_amenaza.py,sha256=Wx5XfcII4oweLvZsTBEJ7kUc9pMpP5-36RfI5C5KJXo,561
16
- guardianunivalle_benito_yucra-0.1.59.dist-info/licenses/LICENSE,sha256=5e4IdL542v1E8Ft0A24GZjrxZeTsVK7XrS3mZEUhPtM,37
17
- guardianunivalle_benito_yucra-0.1.59.dist-info/METADATA,sha256=NBMpEaQRxULhvSVkUdDBOkPFOnvMwS-wBpjdKGB5nRc,1893
18
- guardianunivalle_benito_yucra-0.1.59.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
19
- guardianunivalle_benito_yucra-0.1.59.dist-info/top_level.txt,sha256=HTWfZM64WAV_QYr5cnXnLuabQt92dvlxqlR3pCwpbDQ,30
20
- guardianunivalle_benito_yucra-0.1.59.dist-info/RECORD,,
16
+ guardianunivalle_benito_yucra-0.1.61.dist-info/licenses/LICENSE,sha256=5e4IdL542v1E8Ft0A24GZjrxZeTsVK7XrS3mZEUhPtM,37
17
+ guardianunivalle_benito_yucra-0.1.61.dist-info/METADATA,sha256=xfq_vXhBpJYPh6baQowWC5dOtnLZaLDj208dhj4evVg,1893
18
+ guardianunivalle_benito_yucra-0.1.61.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
19
+ guardianunivalle_benito_yucra-0.1.61.dist-info/top_level.txt,sha256=HTWfZM64WAV_QYr5cnXnLuabQt92dvlxqlR3pCwpbDQ,30
20
+ guardianunivalle_benito_yucra-0.1.61.dist-info/RECORD,,