Skip to content
KitploitKITPLOIT
HerramientasBlog
Enviar
HerramientasBlog
Enviar

¡Herramientas de Hacking, PenTest y Ciberseguridad para tu Arsenal de Seguridad!

Kitploit es un directorio de herramientas de hacking, ciberseguridad y pentesting. Descubre las últimas actualizaciones de proyectos para encontrar vulnerabilidades, analizar sistemas, automatizar pruebas y fortalecer tu seguridad.

··Feeds·Contacto·Privacidad·© 2026 Kitploit

Directorio de Herramientas

Categorías

Ver todas las categorías
Loading categories
laravel-threat-detection — Middleware pasivo de Laravel que detecta y registra inyección SQL, XSS, RCE, escáneres de bots y más de 175 patrones de ataque. Incluye un panel integrado, alertas de Slack, API REST y enriquecimiento geográfico. IDS, no WAF. | Kitploit
Herramientas/GitHubGitHub/jay123anta/laravel-threat-detection
Herramientas DefensivasEscáneres de VulnerabilidadesSeguridad WebInteligencia de AmenazasDetección de IntrusionesRespuesta a IncidentesSeguridad de APIsAnti-BotAnálisis de Registros

Más Populares

Ver todos →

Descubre las herramientas más usadas por nuestra comunidad.

Explora todas las herramientas

Explora nuestra colección de herramientas

Ver todas las herramientas →
Compartir
GitHubjay123anta/laravel-threat-detection

laravel-threat-detection

Middleware pasivo de Laravel que detecta y registra inyección SQL, XSS, RCE, escáneres de bots y más de 175 patrones de ataque. Incluye un panel integrado, alertas de Slack, API REST y enriquecimiento geográfico. IDS, no WAF.

Ver RepositorioSitio web
3121hace 1 díaRevisado por Kitploit

Latest Version Tests Total Downloads PHP Version License

Laravel Threat Detection

Detección pasiva de intrusiones para Laravel — observa cada inyección SQL, XSS, escáner y sonda de bot que golpea tu aplicación, registrada con contexto completo. Es un IDS, no un WAF: nunca bloquea, filtra ni modifica una solicitud.

Threat Detection Dashboard — stats, 7-day timeline, live threat log, top offending IPs, and threats by country

Introdúcelo en cualquier aplicación Laravel 10–13 y empieza a escanear cada solicitud HTTP contra más de 150 patrones de ataque, puntuando cada coincidencia por confianza y registrándola en tu base de datos — con un panel integrado, alertas de Slack, geo-enriquecimiento y exportaciones para fail2ban/listas de bloqueo. Ninguna solicitud es bloqueada jamás. Piensa en una cámara de seguridad, no en un candado: te muestra exactamente quién está sondeando tus rutas, con qué frecuencia y con qué técnicas.

Extraído de una aplicación de producción y probado en tráfico real. 335 pruebas, sin dependencias en tiempo de ejecución más allá del propio Laravel, y no se requiere conexión a internet para la detección.

Comienza en menos de un minuto```bash

composer require jayanta/laravel-threat-detection php artisan vendor:publish --tag=threat-detection-migrations php artisan migrate

root@kitploit:~
Luego añade el middleware a tu grupo `web` (una línea en `bootstrap/app.php` en Laravel 11+,
o `app/Http/Kernel.php` en Laravel 10) — fragmento completo en [Quick Start](#quick-start) más abajo.
Eso es todo; la detección ya está activa.```bash
php artisan threat-detection:doctor   # confirms it is actually recording

Dónde encaja: IDS vs WAF vs edge

Este paquete es un IDS pasivo a nivel de aplicación — observa y registra, no bloquea. Está pensado para situarse junto a un WAF o un servicio edge, no para sustituir a ninguno. Cada capa ve algo que las demás no pueden ver:

La versión corta: un edge/WAF es tu cerradura en la puerta; esto es la cámara de seguridad en el interior, con el contexto de la app para decirte exactamente qué se está intentando en cada ruta, quién lo intenta y con qué frecuencia. Úsalo para alimentar decisiones reales — bloqueos de fail2ban, límites de tasa, geobloqueos — con datos que tu capa edge nunca ve.

Lo que deliberadamente NO es

  • No es un WAF. Nunca bloquea, filtra ni modifica una petición. Usa Cloudflare, mod_security o un WAF real para hacer cumplir las reglas. (¿No tienes una capa edge a la que delegar el bloqueo? Los ayudantes del lado del operador exponen las decisiones del paquete para que puedas escribir tu propio middleware de bloqueo de cinco líneas — el código de bloqueo sigue siendo tuyo, no del paquete.)
  • No sustituye a la codificación segura. Las consultas parametrizadas, la validación de entrada y el escape de salida son tus defensas reales. Este paquete asume que tu código ya es seguro y te da visibilidad, no protección.
  • No es un servicio edge. Si puedes poner Cloudflare delante, hazlo — y añade esto para el detalle a nivel de aplicación que los servicios edge no pueden ver.

Entonces, ¿qué haces realmente con él?

La pregunta más habitual sobre un detector que nunca bloquea. Cuatro respuestas, en orden creciente de esfuerzo:

El paquete aporta la inteligencia; tú aportas el rechazo. Esa separación es deliberada — el código de bloqueo que vive en tu app es código que puedes leer, probar y desactivar, y significa que un fallo de detección nunca puede tumbar tu sitio.


Requisitos

  • PHP 8.2+ (Laravel 13 requiere PHP 8.3+)
  • Laravel 10.x, 11.x, 12.x o 13.x
  • Cualquier base de datos compatible con Laravel (MySQL, PostgreSQL, SQLite, SQL Server)
  • Cualquier driver de caché - no se requiere Redis ni worker de colas. Redis/Memcached solo se recomienda para habilitar la comprobación opcional de DDoS (que se desactiva automáticamente en drivers no atómicos). Las escrituras en cola son opcionales y están desactivadas por defecto.

Cómo funciona

  1. Un middleware escanea cada petición HTTP entrante
  2. La petición se compara con 158 patrones regex que cubren inyección SQL, XSS, RCE, recorrido de archivos, SSRF, LDAP, XPath, SSTI y más
  3. Si un patrón de amenaza coincide, se escribe un registro en la tabla threat_logs de tu base de datos con la IP, la URL, el tipo de amenaza, el nivel de gravedad y una puntuación de confianza
  4. Opcionalmente, se envía una alerta de Slack para amenazas de alta gravedad
  5. La petición continúa con normalidad - no se bloquea nada

No se necesita conexión a internet para la detección.


Inicio rápido

1. Instalar el paquete```bash

composer require jayanta/laravel-threat-detection

root@kitploit:~
### 2. Publicar migraciones y ejecutarlas

> **Este paso es obligatorio.** Sin él, el paquete detectará amenazas pero no podrá almacenarlas en la base de datos. Si omites este paso, tu tabla `threat_logs` no existirá y todas las detecciones se perderán silenciosamente (solo verás errores en `storage/logs/laravel.log`).```bash
php artisan vendor:publish --tag=threat-detection-migrations
php artisan migrate

Esto crea dos tablas: threat_logs (almacena amenazas detectadas) y threat_exclusion_rules (almacena reglas de falsos positivos).

Verificar que las tablas fueron creadas:```bash php artisan migrate:status

root@kitploit:~
Busca `create_threat_logs_table`, `add_confidence_to_threat_logs_table` y `create_threat_exclusion_rules_table` -  todas deberían mostrar `Ran`.

### 3. Registrar el middleware

El middleware es lo que analiza las solicitudes. Debes añadirlo a tu grupo de middleware `web`.

**Si usas Laravel 11 o 12** -  abre `bootstrap/app.php`:```php
->withMiddleware(function (Middleware $middleware) {
    $middleware->web(append: [
        \JayAnta\ThreatDetection\Http\Middleware\ThreatDetectionMiddleware::class,
    ]);
})

Cómo comprobar tu versión de Laravel: Ejecuta php artisan --version en tu terminal.

Si usas Laravel 10 - abre app/Http/Kernel.php:```php protected $middlewareGroups = [ 'web' => [ // ... existing middleware \JayAnta\ThreatDetection\Http\Middleware\ThreatDetectionMiddleware::class, ], ];

root@kitploit:~
### 4. (Opcional) Publicar el archivo de configuración```bash
php artisan vendor:publish --tag=threat-detection-config

El paquete funciona con valores predeterminados sensatos. Publicar la configuración te permite personalizar los patrones de detección, los modos de sensibilidad, las notificaciones de Slack y más. Si te saltas este paso, todo sigue funcionando.

Eso es todo. Tu aplicación ahora está detectando amenazas.


Verifica que funciona

Después de la instalación, activa una amenaza de prueba y confirma que se haya registrado.

Paso 1: Inicia tu aplicación```bash

php artisan serve

root@kitploit:~
### Paso 2: Abre una URL de prueba en tu navegador

Añade un parámetro de consulta malicioso a **cualquier ruta existente** en tu aplicación (tu página de inicio, una página de producto, etc.). Por ejemplo:

**Inyección SQL:**```
http://localhost:8000/?q=' UNION SELECT * FROM users--

XSS (Cross-Site Scripting):``` http://localhost:8000/?q=

root@kitploit:~
**Recorrido de directorios:**```
http://localhost:8000/?file=../../etc/passwd

RCE (Ejecución remota de código):``` http://localhost:8000/?cmd=system('ls -la')

root@kitploit:~
**Shellshock (CVE-2014-6271):**```
http://localhost:8000/?cmd=() { :;}; /bin/bash

Inyección de comandos en Windows:``` http://localhost:8000/?cmd=powershell -c whoami

root@kitploit:~
**DROP TABLE (SQL DDL):**```
http://localhost:8000/?q=DROP TABLE users

Usa una ruta que realmente exista en tu aplicación (como /). Si la URL devuelve un 404, es posible que el middleware no se haya ejecutado.

Paso 3: Comprueba que las amenazas se registraron

Opción A - Comando de Artisan (la más rápida):```bash php artisan threat-detection:stats

root@kitploit:~
Deberías ver una tabla con `Total Threats`, recuentos de severidad y las principales IPs.

**Opción B -  Tinker:**```bash
php artisan tinker
root@kitploit:~
DB::table('threat_logs')->latest()->take(5)->get(['ip_address', 'type', 'threat_level', 'confidence_score']);

Opción C - archivo de registro de Laravel: Cada amenaza detectada se escribe como una advertencia en storage/logs/laravel.log:``` [high] Threat Detected: [middleware] SQL Injection UNION from 127.0.0.1 (http://localhost:8000/?q=...) [confidence: 50%]

root@kitploit:~
### Cosas que debes saber al probar

| Comportamiento | Explicación |
|----------|-------------|
| La misma amenaza solo se registra una vez cada 5 minutos | Deduplicación: la misma IP + el mismo tipo de amenaza se almacenan en caché durante 5 minutos. Usa **diferentes tipos de ataque** para cada prueba, o espera entre pruebas. |
| Las peticiones con `curl` activan detección adicional | Usar `curl` también registra una detección de user-agent "cURL Command" (severidad baja). Esto es esperado: el paquete detecta herramientas automatizadas. |
| El paquete nunca bloquea peticiones | Tu aplicación sigue funcionando con normalidad. La detección es pasiva. |
| No se necesita configurar Slack | Las notificaciones están desactivadas por defecto. |
| No se necesita conexión a internet | La detección principal es 100% local. Solo el comando opcional `threat-detection:enrich` llama a una API externa para los datos geográficos. |

### Solución de problemas

**Empieza aquí: un comando responde la mayor parte de esto:**```bash
php artisan threat-detection:doctor

Comprueba las cosas que hacen que la detección falle silenciosamente — donde el panel permanece vacío, lo que parece idéntico a "sin ataques" — e imprime la solución exacta para cada una. Sale con un código distinto de cero ante un fallo real, por lo que es seguro ejecutarlo en CI o en un paso de despliegue.``` Threat Detection — health check

PASS Detection is enabled for this environment FAIL 'threat_logs' is missing confidence_label — EVERY threat is being discarded Run: php artisan vendor:publish --tag=threat-detection-migrations && php artisan migrate WARN 1 custom pattern(s) shadow a built-in: Localhost SSRF Your copy runs instead of the maintained one, so later fixes to it never reach you.

root@kitploit:~
Qué cubre: la detección habilitada para este entorno; cada columna que el escritor necesita (una que falte descarta **todas** las amenazas); las columnas del panel/API; la tabla de reglas de exclusión; si el middleware está realmente conectado a una ruta o grupo; una configuración publicada que precede a esta versión; patrones personalizados que ocultan los integrados; un controlador de caché que no puede hacer el conteo de DDoS; y un panel o API que quedó abierto sin autenticación.

**"Probé pero `threat-detection:stats` muestra cero amenazas" / "Las amenazas no se almacenan en la base de datos"**

Si el doctor pasó, la instalación está bien y el problema es la propia solicitud de prueba. Tres cosas que no puede comprobar por ti:

| Comprobación | Cómo verificar |
|-------|---------------|
| La IP no está en la lista blanca | Si añadiste `THREAT_DETECTION_WHITELISTED_IPS` a `.env`, elimínala durante las pruebas |
| Se usó una ruta existente | La URL de prueba debe coincidir con una ruta real (p. ej., `/`). Un 404 significa que el middleware nunca se ejecutó |
| Caché de deduplicación | Misma IP + mismo tipo de ataque se almacena en caché durante 5 minutos -  prueba con un tipo de ataque diferente |

> Ejecutar `php artisan migrate` por sí solo nunca es suficiente: los archivos de migración
> viven dentro del paquete y deben publicarse en `database/migrations/` de tu aplicación
> primero. El doctor imprime el comando exacto cuando este es el problema.

**"La API devuelve 401 Unauthorized"**

Consulta [Autenticación de API](#api-authentication) a continuación.

**"El panel muestra 404"**

El panel está deshabilitado por defecto. Añade `THREAT_DETECTION_DASHBOARD=true` a `.env` y limpia la caché de rutas:```bash
php artisan route:clear

Features

  • 150+ Patrones de Detección - Inyección SQL (UNION, DDL, DML, operaciones de archivo), XSS (script, SVG, expresión CSS), RCE, directory traversal, SSRF, XXE, Log4Shell, inyección NoSQL, inyección de comandos (Linux + Windows), inyección LDAP, inyección XPath, SSTI, inyección CRLF, deserialización de Java, y más
  • 83 Firmas de Bots/Escáneres - SQLMap, Nikto, Nmap, Burp Suite, FeroxBuster, FFUF, XSStrike, Dalfox, Netsparker, y más de 70 otras firmas de escáneres y bots
  • Detección de Scrapers de IA - GPTBot, ClaudeBot, ByteSpider, Common Crawl, y otros bots de entrenamiento de IA
  • Detección de Navegadores Headless - HeadlessChrome, PhantomJS, Selenium, Puppeteer, Playwright
  • Seguimiento de Sondas 404 - Detecta sondas de reconocimiento que golpean rutas vulnerables conocidas (/wp-admin, /.env, /phpmyadmin, /actuator, etc.) con más de 50 rutas de sonda predeterminadas
  • Monitoreo de DDoS - Detección de umbral basada en tasa con ventanas configurables
  • Puntuación de Confianza - Cada amenaza recibe una puntuación de confianza de 0 a 100 basada en el número de patrones, el contexto y las señales
  • Resistencia a la Evasión - La canalización de normalización neutraliza la inserción de comentarios SQL, el doble codificado de URL, la codificación de entidades HTML, los escapes Unicode y los escapes hexadecimales antes del emparejamiento de patrones
  • Detección de CVEs - Shellshock (CVE-2014-6271), Spring4Shell (CVE-2022-22965), PHPUnit RCE (CVE-2017-9841), Drupalgeddon, Log4Shell
  • Detección Consciente del Contexto - Los patrones encontrados en cadenas de consulta obtienen una puntuación mayor que los del cuerpo de la solicitud
  • Escaneo del Cuerpo de la Solicitud - Se inspeccionan tanto los cuerpos de solicitud codificados como formulario como los JSON (application/json)

Configuration

El paquete funciona sin realizar cambios en .env. Todos los valores a continuación son opcionales: agrégalos solo si deseas anular los valores predeterminados.```env

Enable/disable detection globally (default: true)

THREAT_DETECTION_ENABLED=true

Detection sensitivity (default: balanced)

Options: strict, balanced, relaxed

THREAT_DETECTION_MODE=balanced

Custom table name (default: threat_logs)

THREAT_DETECTION_TABLE=threat_logs

Whitelist IPs to skip detection entirely (default: empty)

Supports CIDR notation. Comma-separated.

THREAT_DETECTION_WHITELISTED_IPS=10.0.0.0/8,192.168.1.0/24

Static operator denylist read by ThreatDetection::isBlocklisted() (default: empty)

The package itself never blocks — see "Acting on the Data" for the

enforcement recipe. Supports CIDR. Whitelist wins on overlap.

THREAT_DETECTION_BLOCKLISTED_IPS=203.0.113.0/24,198.51.100.7

DDoS detection thresholds (defaults shown)

THREAT_DETECTION_DDOS_THRESHOLD=300

THREAT_DETECTION_DDOS_WINDOW=60

Minimum confidence score to log a threat (default: 0)

Threats below this score are silently ignored.

THREAT_DETECTION_MIN_CONFIDENCE=0

Slack notifications (disabled by default)

THREAT_DETECTION_NOTIFICATIONS=true

THREAT_DETECTION_SLACK_WEBHOOK=https://hooks.slack.com/services/YOUR/WEBHOOK/URL

THREAT_DETECTION_SLACK_CHANNEL=#threat-alerts

Dashboard (disabled by default)

THREAT_DETECTION_DASHBOARD=true

API endpoints (enabled by default)

THREAT_DETECTION_API=true

API rate limiting (default: 60 requests per minute)

THREAT_DETECTION_API_THROTTLE=60,1

Queue support - offload DB writes to a queue (disabled by default).

OPTIONAL: only enable if your app already runs a queue worker. When false

(default), threats are written synchronously with a plain DB insert - no

Redis, no worker, nothing extra to run.

THREAT_DETECTION_QUEUE=false

THREAT_DETECTION_QUEUE_CONNECTION=redis

THREAT_DETECTION_QUEUE_NAME=default

Auto-purge old logs (disabled by default)

Requires Laravel scheduler to be running.

THREAT_DETECTION_RETENTION=false

THREAT_DETECTION_RETENTION_DAYS=90

404 probe tracking (enabled by default)

Detects bots hitting /wp-admin, /.env, /phpmyadmin, etc.

THREAT_DETECTION_PROBE_TRACKING=true

Max detections per request (default: 0 = unlimited)

Stop scanning after N pattern matches per request.

THREAT_DETECTION_MAX_DETECTIONS=0

Dashboard auth guard (default: none)

Options: none, auth, role, ip

THREAT_DETECTION_DASHBOARD_GUARD=none

THREAT_DETECTION_DASHBOARD_ROLE=admin

THREAT_DETECTION_DASHBOARD_IPS=127.0.0.1

API auth guard (default: none - uses existing middleware config)

THREAT_DETECTION_API_GUARD=none

root@kitploit:~
### Modos de detección

| Mode | Confidence Threshold | Behavior |
|------|---------------------|----------|
| `strict` | 0 (registra todo) | Todos los patrones activos, umbrales más bajos. Detecta todo, pero puede marcar tráfico legítimo. |
| `balanced` | 10 | Predeterminado. Puntuación de confianza activa, umbrales estándar. Adecuado para la mayoría de las aplicaciones. |
| `relaxed` | 40 | Solo se activan patrones de alta gravedad. Mejor para sitios con mucho contenido y falsos positivos frecuentes. |

### Entornos habilitados

De forma predeterminada, la detección se ejecuta en `production`, `staging` y `local`. Para cambiarlo, publique la configuración y edite:```php
'enabled_environments' => ['production', 'staging', 'local'],

Para desactivar la detección en tu suite de pruebas, establece APP_ENV=testing (no en la lista anterior) o añade a tu phpunit.xml:```xml

root@kitploit:~
### Referencia de configuración

Publica el archivo de configuración para ver todas las opciones disponibles:```bash
php artisan vendor:publish --tag=threat-detection-config

Secciones de configuración clave: skip_paths (rutas a omitir), only_paths (modo de lista blanca), auth_paths (detección inteligente de rutas de inicio de sesión), content_paths (suprimir alertas no altas), safe_fields (excluir campos específicos del escaneo), safe_paths (exclusión de campos basada en rutas para JSON anidado), probe_tracking (detección de sondas 404), context_weights (multiplicadores de puntuación), threat_levels (mapeo de palabras clave de severidad), api_route_filtering (suprimir baja/media en rutas de API), queue (procesamiento asíncrono), retention (purga automática), max_detections_per_request (límite de rendimiento), / (modo de autenticación).

Lista blanca de rutas (only_paths)

Si tu aplicación tiene muchas rutas pero solo te interesan unas pocas, usa only_paths para escanear solo esas rutas. Todas las demás rutas se omiten automáticamente - sin sobrecarga de middleware en absoluto.```php // config/threat-detection.php 'only_paths' => [ 'admin/', 'api/', 'login', 'register', ],

root@kitploit:~
Déjalo vacío (predeterminado) para escanear todas las rutas (sujeto a `skip_paths`). Cuando ambos están configurados, `only_paths` se comprueba primero, luego `skip_paths` se aplica dentro del conjunto coincidente.

### Soporte de colas

Por defecto, el registro de amenazas se realiza sincrónicamente en el ciclo de solicitud. Para aplicaciones de alto tráfico, puedes descargar las escrituras de la base de datos y las notificaciones de Slack a una cola:```env
THREAT_DETECTION_QUEUE=true
THREAT_DETECTION_QUEUE_CONNECTION=redis
THREAT_DETECTION_QUEUE_NAME=threat-logs

Esto envía un trabajo StoreThreatLog (3 reintentos, backoff 10s/30s). La detección sigue ocurriendo en tiempo real - solo se difiere la escritura.

Auto-purga (Política de retención)

Eliminar automáticamente los registros de amenazas antiguos en un horario diario:```env THREAT_DETECTION_RETENTION=true THREAT_DETECTION_RETENTION_DAYS=90

root@kitploit:~
Requiere que el programador de tareas de Laravel esté en ejecución (`php artisan schedule:run`). Se ejecuta diariamente a las 02:00 mediante `threat-detection:purge`.

### Evento ThreatDetected

Cada amenaza confirmada despacha un evento `ThreatDetected` que puedes escuchar:```php
// app/Providers/EventServiceProvider.php
use JayAnta\ThreatDetection\Events\ThreatDetected;

protected $listen = [
    ThreatDetected::class => [
        YourCustomListener::class,
    ],
];

El evento lleva $threatLog (array completo de la fila de la BD), $ipAddress y $threatLevel. Úsalo para desencadenar acciones personalizadas - enviar alertas de Telegram, actualizar una lista de bloqueo, alimentar un SIEM, etc.

Evento DdosThresholdExceeded

Cuando un cliente supera el umbral DDoS configurado (ddos.threshold solicitudes en ddos.window segundos), se despacha un evento DdosThresholdExceeded junto con la entrada del registro de amenazas:```php use JayAnta\ThreatDetection\Events\DdosThresholdExceeded;

protected $listen = [ DdosThresholdExceeded::class => [ YourFloodListener::class, ], ];

root@kitploit:~
El evento lleva `$ipAddress`, `$requestCount`, `$threshold` y `$windowSeconds`. Se
limita a una vez por IP por ventana de deduplicación (el mismo límite que la fila de registro), para que una inundación no
ahogue a tus receptores. Úsalo para alertar o para alimentar un almacén de baneo externo; para *rechazar*
clientes por encima del umbral, usa `ThreatDetection::isDdosThresholdExceeded($ip)` desde tu propio
middleware en su lugar — consulta [Actuar sobre los datos](#acting-on-the-data-operator-side-blocking).

---

## Notificaciones de Slack

Las alertas de Slack están deshabilitadas por defecto. Para habilitarlas:```env
THREAT_DETECTION_NOTIFICATIONS=true
THREAT_DETECTION_SLACK_WEBHOOK=https://hooks.slack.com/services/YOUR/WEBHOOK/URL
THREAT_DETECTION_SLACK_CHANNEL=#threat-alerts

Solo las amenazas de alta severidad activan notificaciones por defecto (configurable mediante notify_levels en la configuración).

Laravel 10: Utiliza la clase de notificación integrada SlackMessage. No se necesita ningún paquete adicional.

Laravel 11+: El canal integrado de Slack fue eliminado. El paquete detecta esto automáticamente y envía webhooks HTTP POST sin procesar a tu URL de Slack. No se necesita ningún paquete adicional. Si prefieres el canal de notificación completo, instala:```bash composer require laravel/slack-notification-channel

root@kitploit:~
---

## Panel de control

El paquete incluye un panel de control integrado con modo oscuro (Alpine.js + Tailwind CDN -  no se requiere compilación).```
+-------------------------------------------------------------------------+
|  Threat Detection Dashboard                                              |
+-------------------------------------------------------------------------+
|  Total: 847  |  High: 23  |  Med: 156  |  Low: 668  |  IPs: 94         |
+-------------------------------------------------------------------------+
|  [Timeline Chart - 7 Day Stacked Bar]                                   |
+-------------------------------------------------------------------------+
|  Search: [___________]  Level: [All]                                    |
|  Time         IP             Type            Level  Confidence  Actions  |
|  Mar 2 14:02  185.220.101.4  SQL Injection   HIGH   80%         [FP]    |
|  Mar 2 13:58  45.33.32.156   XSS Script Tag  HIGH   65%         [FP]    |
|  Mar 2 13:45  192.168.1.10   Scanner: Nikto  MED    35%         [FP]    |
+-------------------------------------------------------------------------+
|  Top IPs              |  Threats by Country                              |
|  185.220.101.4  [23]  |  US  234                                        |
|  45.33.32.156   [18]  |  CN  156                                        |
|  103.152.220.1  [12]  |  RU  98                                         |
+-------------------------------------------------------------------------+

Habilita el panel

Agrega a .env:```env THREAT_DETECTION_DASHBOARD=true

root@kitploit:~
Visita: `http://your-app.test/threat-detection`

### Acceso durante el desarrollo local

El panel usa el middleware `['web', 'auth']` por defecto, por lo que los usuarios deben iniciar sesión. Si tu aplicación aún no tiene autenticación, restríngelo a tu propia máquina:```env
THREAT_DETECTION_DASHBOARD_GUARD=ip
THREAT_DETECTION_DASHBOARD_IPS=127.0.0.1

Todas las opciones de guard, y el guard separado en los endpoints que desactivan las detecciones, se tratan en Dashboard y autenticación de API.

Si el dashboard muestra datos vacíos, la página cargó pero sus llamadas a la API no. Consulta Autenticación de API.


Endpoints de la API

El paquete proporciona 15 endpoints REST para crear dashboards personalizados o integraciones.

Autenticación de la API

Las rutas de la API utilizan el middleware auth:sanctum por defecto. El paquete maneja esto de forma elegante:

  • Sanctum instalado: La API requiere autenticación mediante tokens de Sanctum o autenticación de sesión SPA.
  • Sanctum NO instalado: El paquete detecta automáticamente que Sanctum no está presente y recurre únicamente a ['api']. La API funciona sin autenticación.

Si no utilizas Sanctum pero quieres proteger tu API, tienes dos opciones:

Opción 1 - Usa el guard de autenticación integrado:```env THREAT_DETECTION_API_GUARD=auth

root@kitploit:~
**Opción 2 -  Cambiar el middleware directamente:**```php
// config/threat-detection.php
'api' => [
    'enabled' => true,
    'prefix' => 'api/threat-detection',
    'middleware' => ['api', 'auth'],  // or 'auth:your-guard'
],

Para pruebas locales (si Sanctum bloquea el acceso), cambia temporalmente:```php 'middleware' => ['api'], // remove 'auth:sanctum'

root@kitploit:~
> Restablezca la autenticación antes de implementar en producción.

### Referencia de Endpoints

| Method | Endpoint | Description |
|--------|----------|-------------|
| GET | `/api/threat-detection/threats` | Listar amenazas (paginado, filtrable) |
| GET | `/api/threat-detection/threats/{id}` | Detalles de una amenaza individual |
| POST | `/api/threat-detection/threats/{id}/false-positive` | Marcar amenaza como falso positivo |
| GET | `/api/threat-detection/stats` | Estadísticas generales |
| GET | `/api/threat-detection/summary` | Desglose detallado por tipo, nivel, IP |
| GET | `/api/threat-detection/live-count` | Amenazas en la última hora |
| GET | `/api/threat-detection/by-country` | Agrupado por país |
| GET | `/api/threat-detection/by-cloud-provider` | Agrupado por proveedor de nube |
| GET | `/api/threat-detection/top-ips` | Principales IPs infractoras |
| GET | `/api/threat-detection/timeline` | Cronología de amenazas (para gráficos) |
| GET | `/api/threat-detection/ip-stats?ip=x.x.x.x` | Estadísticas para una IP específica |
| GET | `/api/threat-detection/correlation` | Análisis de correlación |
| GET | `/api/threat-detection/export` | Exportar a CSV |
| GET | `/api/threat-detection/exclusion-rules` | Listar reglas de exclusión |
| DELETE | `/api/threat-detection/exclusion-rules/{id}` | Eliminar una regla de exclusión |

### Parámetros de consulta para `/threats`

| Parameter | Description |
|-----------|-------------|
| `keyword` | Buscar en IP, URL, tipo |
| `ip` | Filtrar por dirección IP |
| `level` | Filtrar por nivel de amenaza (`high`, `medium`, `low`) |
| `type` | Filtrar por tipo de amenaza |
| `country` | Filtrar por código de país |
| `is_foreign` | Filtrar IPs extranjeras (`true`/`false`) |
| `cloud_provider` | Filtrar por proveedor de nube |
| `is_false_positive` | Filtrar por estado de falso positivo (`true`/`false`) |
| `date_from` / `date_to` | Filtro de rango de fechas |
| `per_page` | Elementos por página (predeterminado: 20, máximo: 100) |

### Ejemplo de respuesta de la API

**GET `/api/threat-detection/stats`:**```json
{
  "success": true,
  "data": {
    "total_threats": 847,
    "high_severity": 23,
    "medium_severity": 156,
    "low_severity": 668,
    "unique_ips": 94,
    "foreign_ips": 67,
    "cloud_attacks": 12,
    "today": 34,
    "last_hour": 5
  }
}

Construyendo frontends personalizados

Vue.js:```javascript async mounted() { const response = await fetch('/api/threat-detection/stats'); this.stats = await response.json();

root@kitploit:~
const threats = await fetch('/api/threat-detection/threats?per_page=20');
this.threats = await threats.json();

}

root@kitploit:~
**React:**```jsx
useEffect(() => {
    fetch('/api/threat-detection/stats')
        .then(res => res.json())
        .then(data => setStats(data));
}, []);

Si tu API usa auth:sanctum, incluye los encabezados de autenticación o configura la autenticación SPA de Sanctum para solicitudes basadas en cookies.


Comandos Artisan```bash

Check that detection is installed, wired up and actually recording.

Exits non-zero on a real failure, so it works in CI or a deploy step.

php artisan threat-detection:doctor

View threat stats summary in the terminal

php artisan threat-detection:stats

Enrich existing logs with geo-data (country, city, ISP, cloud provider)

Uses the free ip-api.com service (rate-limited to 45 req/min, auto-throttled)

php artisan threat-detection:enrich --days=7

Purge old logs to keep the database clean

php artisan threat-detection:purge --days=30

Export threat IPs for fail2ban (pipe to file or run directly)

php artisan threat-detection:export-fail2ban --level=high --since=24h --min-hits=5 php artisan threat-detection:export-fail2ban --format=plain > /tmp/banlist.txt

Export blocklist in various formats

php artisan threat-detection:export-blocklist --format=nginx > /etc/nginx/blocklist.conf php artisan threat-detection:export-blocklist --format=apache > .htaccess-deny php artisan threat-detection:export-blocklist --format=csv --since=7d

root@kitploit:~
---

## Actuando sobre los datos (Bloqueo del lado del operador)

El paquete nunca bloquea una solicitud: esa es su identidad, no un valor predeterminado. Las exportaciones anteriores alimentan las capas de aplicación que ya ejecutas (fail2ban, nginx, un WAF perimetral). Pero algunos despliegues no tienen esa capa a la que alimentar: hosting compartido, PaaS, contenedores detrás de un balanceador de carga que no controlas. Para esos, el paquete expone sus *decisiones* como ayudantes, y tú escribes el middleware de aplicación tú mismo. Misma arquitectura que las exportaciones: **nosotros aportamos la inteligencia, tú aportas la denegación.**```php
// app/Http/Middleware/EnforceThreatDecisions.php
namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use JayAnta\ThreatDetection\Facades\ThreatDetection;

class EnforceThreatDecisions
{
    public function handle(Request $request, Closure $next)
    {
        $ip = (string) $request->ip();

        // Static operator denylist (config: blocklisted_ips).
        // CIDR supported; whitelisted_ips wins on overlap.
        if (ThreatDetection::isBlocklisted($ip)) {
            abort(403);
        }

        // Volumetric flood: refuse over-threshold clients until the window resets.
        if (ThreatDetection::isDdosThresholdExceeded($ip)) {
            return response('Too Many Requests', 429, [
                'Retry-After' => (string) config('threat-detection.ddos.window', 60),
            ]);
        }

        return $next($request);
    }
}

Antes de aplicar restricciones por IP, configura TrustProxies.

Todo lo anterior se basa en $request->ip(). Detrás de un balanceador de carga, CDN o proxy inverso, eso devuelve la IP del cliente solo cuando Laravel sabe qué proxies debe confiar. Si no es así, dos cosas se rompen a la vez: cada solicitud parece venir del proxy, por lo que una entrada en la lista de denegación bloquea todo tu tráfico o nada — y peor aún, si la aplicación confía en una cabecera reenviada que no debería, un atacante establece X-Forwarded-For y atraviesa directamente la lista de bloqueo.

Esto importa más aquí que para whitelisted_ips. Una coincidencia incorrecta en la lista blanca solo significa que el paquete escanea una solicitud que podría haber omitido: falla de forma segura. Una lista de denegación usada para rechazar tráfico falla en abierto — crees que una dirección está bloqueada cuando no lo está. Revisa app/Http/Middleware/TrustProxies.php (o la llamada trustProxies en bootstrap/app.php en Laravel 11+) antes de confiar en cualquiera de las dos ayudas para imponer restricciones.

Regístralo globalmente (antes del middleware de detección está bien — las ayudas leen la configuración y la caché, no dependen del orden del middleware):```php // bootstrap/app.php (Laravel 11+) ->withMiddleware(function ($middleware) { $middleware->prepend(\App\Http\Middleware\EnforceThreatDecisions::class); })

root@kitploit:~
Los helpers:

| Helper | Returns | Backed by |
|---|---|---|
| `ThreatDetection::isBlocklisted($ip)` | `bool` | config `blocklisted_ips` (CIDR mediante `IpUtils`; la lista blanca gana) |
| `ThreatDetection::isWhitelisted($ip)` | `bool` | config `whitelisted_ips` |
| `ThreatDetection::ddosRequestCount($ip)` | `int` | el contador de inundación que mantiene el middleware de detección |
| `ThreatDetection::isDdosThresholdExceeded($ip)` | `bool` | ese contador frente a `ddos.threshold` |

Notas:

- **La lista de denegación es estática y la mantiene el operador.** Nada en el paquete la modifica jamás: ejecuta la misma decisión que tomaría una jail de fail2ban («He leído el panel; este /24 es hostil»), solo dentro de la aplicación.
- El contador de DDoS solo cuenta las peticiones que llegaron a la detección (`skip_paths`, IPs en lista blanca y entornos deshabilitados nunca se cuentan), y permanece en 0 en los controladores de caché donde la detección de DDoS está deshabilitada (`file`, `database`, `null`).
- Cuando un cliente supera el umbral, también se despacha un [`DdosThresholdExceeded` evento](#ddosthresholdexceeded-event), útil para alertar o alimentar una lista de baneo externa. Sin embargo, no llames a `abort()` desde el listener: los listeners se ejecutan dentro del `try/catch` de fallo abierto del middleware de detección, por lo que el rechazo corresponde a tu propio middleware, como se indicó antes.

---

## Seguimiento de Sondas 404

El paquete detecta sondas de reconocimiento -  bots que golpean rutas vulnerables conocidas como `/wp-admin`, `/.env` o `/phpmyadmin` en tu sitio que no es WordPress ni phpMyAdmin. Estas no tienen carga maliciosa; la propia ruta es la señal.

Se registran con una etiqueta de tipo `[probe]`, separada de la detección basada en cargas maliciosas. Si una petición de sonda también contiene una carga maliciosa, ambas se registran de forma independiente.

Habilitado por defecto con más de 50 rutas de sonda. Personalízalo en `config/threat-detection.php`:```php
'probe_tracking' => [
    'enabled' => true,
    'default_level' => 'medium',
    'paths' => [
        '/wp-admin' => 'WordPress Admin',
        '/wp-admin/*' => 'WordPress Admin',
        '/.env' => 'Environment File',
        '/phpmyadmin' => 'phpMyAdmin',
        '/actuator/*' => 'Spring Actuator',
        // Add your own probe paths...
    ],
],

Desactivar con THREAT_DETECTION_PROBE_TRACKING=false.


Campos seguros (Reducción de falsos positivos)

Si campos de formulario específicos contienen legítimamente HTML, palabras clave SQL o código (por ejemplo, editores de CMS, entradas de fragmentos de código), puedes excluirlos del escaneo:```php // config/threat-detection.php 'safe_fields' => ['content', 'body', 'html', 'description', 'code'],

root@kitploit:~
Los campos enumerados aquí se omiten de los parámetros de consulta y del cuerpo de la solicitud, tanto en formato `application/x-www-form-urlencoded` como JSON (`application/json`), antes de que se ejecute la detección. Los demás campos de la misma solicitud se siguen escaneando por completo.

### Rutas seguras (sensibles a la ruta, para API JSON anidadas)

`safe_fields` coincide con un nombre de clave **en cualquier lugar** donde aparezca. Para API JSON anidadas, eso suele ser demasiado amplio: puede que quieras eximir el valor de un campo específico sin eximir esa clave en todos lados. Usa `safe_paths`, que coincide mediante la **ruta** en notación de puntos y admite comodines `fnmatch`:```php
// config/threat-detection.php
'safe_paths' => ['search.query', 'filters.*.value'],

Por ejemplo, search.query exime el valor de {"search": {"query": "..."}} (un cuadro de búsqueda cuyo texto contiene legítimamente palabras como SELECT), mientras que un campo query en cualquier otro lugar de la solicitud sigue siendo escaneado. Todo lo que no esté listado se escanea exactamente igual que antes.

Validadores posteriores a la coincidencia (reducción de falsos positivos basada en suma de verificación)

Una regex por sí sola no puede expresar todas las restricciones: cualquier secuencia de 12 dígitos coincide con el patrón de Aadhaar, pero un número Aadhaar real también pasa la suma de verificación de Verhoeff. Asigna una etiqueta de patrón (predeterminada o personalizada) a un validador con nombre, y una coincidencia de regex solo cuenta como detección cuando al menos un valor coincidente pasa el validador:```php // config/threat-detection.php 'pattern_validators' => [ 'Aadhaar Number Detected' => 'verhoeff', // shipped default ],

root@kitploit:~
Validadores disponibles:

| Validador  | Suma de verificación | Uso típico |
|------------|----------|-------------|
| `verhoeff` | Verhoeff | Números Aadhaar |
| `luhn`     | Luhn     | Números de tarjetas de crédito/débito |

Con el mapeo incluido, las marcas de tiempo, los IDs de pedidos y los códigos de barras que resultan tener 12 dígitos ya no se registran como PII — mientras que los números Aadhaar genuinos sí se siguen registrando. Si varios valores coinciden y solo uno pasa la suma de verificación, la detección igualmente se activa: un número real entre el ruido sigue siendo una fuga.

Combina un validador con tu propio patrón para la detección de tarjetas controlada por suma de verificación:```php
'custom_patterns'    => ['/\b(?:\d[ -]?){13,19}\b/' => 'Card Number Detected'],
'pattern_validators' => ['Card Number Detected' => 'luhn'],

Un nombre de validador desconocido falla en abierto — la coincidencia se cuenta sin validar y se registra una advertencia una sola vez — de modo que un error tipográfico nunca puede desactivar silenciosamente un patrón de detección. Las configuraciones publicadas antes de esta función simplemente no tienen la clave y mantienen exactamente su comportamiento actual.


Redacción (Detectar no es almacenar)

Detectar datos sensibles solía significar almacenarlos. Un formulario de perfil que llevara un número de móvil, PAN y cuenta bancaria activaría tres patrones de PII, y cada una de las tres filas escritas conservaba el cuerpo completo de la solicitud tal cual - retenido durante todo el período de retención, legible por cualquiera con acceso al panel o a la base de datos. Un valor en una cadena de consulta también acababa en la columna url. El detector se convertía en una segunda copia concentrada de exactamente aquello sobre lo que te advierte.

Activado por defecto desde v1.7.0. Cuando un patrón cuya etiqueta aparece en la lista se dispara, el valor que coincidió se enmascara en la carga útil almacenada y en la URL:``` BODY: {"name":"Jane Doe","mobile":"[REDACTED]","pan":"[REDACTED]","bank_account":"[REDACTED]"}

root@kitploit:~
La alerta, el endpoint, los nombres de los campos y la IP atacante sobreviven -  solo desaparece el valor. La redacción se ejecuta *después* de la detección, por lo que no se pierde nada.```php
// config/threat-detection.php
'redact' => [
    'enabled' => env('THREAT_DETECTION_REDACT', true),
    'mask'    => '[REDACTED]',
    'labels'  => ['Aadhaar Number Detected', 'PAN Number Detected', /* ... */],
],

Los payloads de ataque se dejan intactos deliberadamente - una cadena de inyección es evidencia, no un secreto, y enmascararla destruiría la investigación. Solo se modifican las etiquetas que enumeres.

Esto no reemplaza a Safe Fields. Esos evitan que un campo sea escaneado; la redacción te permite seguir escaneando y dejar de almacenar. Establece THREAT_DETECTION_REDACT=false si necesitas payloads completos para fines forenses.


Autenticación del panel y la API

El panel y la API admiten guardas de autenticación configurables a través de .env:```env

Options: none (default), auth, role, ip

THREAT_DETECTION_DASHBOARD_GUARD=auth

For role-based guard (Spatie compatible):

THREAT_DETECTION_DASHBOARD_GUARD=role THREAT_DETECTION_DASHBOARD_ROLE=admin

For IP-based guard:

THREAT_DETECTION_DASHBOARD_GUARD=ip THREAT_DETECTION_DASHBOARD_IPS=127.0.0.1,10.0.0.0/8

root@kitploit:~
Las mismas opciones están disponibles para las rutas de API con `THREAT_DETECTION_API_GUARD`.

Cuando `guard=none` (por defecto), el paquete registra una advertencia una vez al día para recordarte que configures la autenticación.

La protección **falla en modo cerrado**: un valor de guard no reconocido (por ejemplo, un error tipográfico) se deniega con un 403 y una advertencia registrada en lugar de conceder acceso silenciosamente, y `guard=role` deniega (con una advertencia) cuando el modelo de usuario autenticado no tiene un método `hasRole()`.

### Deshabilitar una detección requiere algo más que acceso de lectura

Marcar una amenaza como falso positivo y eliminar una regla de exclusión silencian un tipo de detección para todos, lo cual es un privilegio distinto a leer el registro. Esos dos endpoints se comprueban contra una protección separada:```env
# Options: none, auth, role, ip. Default: role
THREAT_DETECTION_API_WRITE_GUARD=role

Se aplica solo a esas rutas, por lo que la lectura y el panel se comportan exactamente como indica THREAT_DETECTION_API_GUARD. Sin él, cualquier usuario autenticado de tu aplicación podría desactivar una detección.

Si tu modelo de usuario no tiene hasRole(), usa =auth. Para restaurar el comportamiento anterior a la 1.7.0 en el que cualquier usuario autenticado podía deshabilitar detecciones, usa =none; threat-detection:doctor mostrará una advertencia mientras eso esté configurado.

Nota sobre el panel ↔ API: el panel integrado obtiene sus datos de las rutas de la API utilizando la cookie de sesión del navegador. Si tus rutas de API están protegidas con auth:sanctum, configura la autenticación stateful/SPA de Sanctum (o apunta el panel a un guard autenticado por cookie) para que esas llamadas AJAX estén autorizadas; de lo contrario, el panel se renderiza vacío.


Patrones personalizados

Añade tus propios patrones de expresión regular de detección en config/threat-detection.php:```php 'custom_patterns' => [ '/your-regex-here/i' => 'Your Threat Label', ],

root@kitploit:~
**Ejemplo -  detectar una sonda de endpoint de administración personalizado:**```php
'/\/my-admin-panel/i' => 'Custom Admin Panel Probe',

Forma de array (opciones por patrón)

Junto a la forma clásica de cadena, el valor de un patrón puede ser un array para tener control total:```php 'custom_patterns' => [ '/\b(?:\d[ -]?){13,19}\b/' => [ 'label' => 'Card Number Detected', // required 'level' => 'high', // low|medium|high — overrides keyword derivation 'contexts' => ['query', 'body'], // query|body|headers — default: all segments 'validator' => 'luhn', // post-match checksum, wins over pattern_validators ], ],

root@kitploit:~
- **`level`** establece el nivel de amenaza directamente en lugar de derivarlo de las palabras clave de `threat_levels` en la etiqueta.
- **`contexts`** restringe el escaneo a segmentos específicos de la solicitud; por ejemplo, un patrón de tarjeta que solo tiene sentido en el cuerpo deja de coincidir con secuencias de dígitos en las cabeceras.
- **`validator`** designa una comprobación en línea posterior a la coincidencia (ver [Validadores posteriores a la coincidencia](#post-match-validators-checksum-aware-false-positive-reduction)); tiene prioridad sobre el mapa de etiquetas `pattern_validators`.

Las entradas de cadena y array se combinan libremente en la misma configuración. Las opciones malformadas **fail open** — el patrón sigue escaneando sin restricciones y se registra una advertencia —, por lo que un error de configuración nunca puede deshabilitar silenciosamente una detección.

> **Nota:** Las rutas de sonda comunes como `/wp-login.php`, `/.env`, `/phpmyadmin` ahora se manejan automáticamente mediante la función [Seguimiento de sondas 404](#404-probe-tracking). No necesitas patrones personalizados para ellas.

El nivel de amenaza de cada patrón se determina automáticamente comparando las palabras clave de la etiqueta con la configuración `threat_levels`:```php
'threat_levels' => [
    'high' => ['XSS', 'SQL Injection', 'SQL DDL', 'SQL DML', 'SQL File', 'SQL Hex', 'RCE', ..., 'Shellshock', 'Spring4Shell', 'PowerShell', 'CRLF', 'Null Byte', 'SSTI', 'Java', 'LDAP', 'XPath', 'PHP assert', ...],
    'medium' => ['Directory Traversal', 'LFI', 'SSRF', 'Sensitive', 'Config', ..., 'Open Redirect', 'LF Injection', 'GraphQL', 'Spring Boot Actuator', ...],
    'low' => ['User-Agent', 'JS Redirect', 'SEO Bot', 'Empty', 'Rate', 'Command-line Downloader', 'DNS Rebinding'],
],

Si la etiqueta no coincide con ninguna palabra clave, la amenaza toma por defecto severidad low.

Los patrones de regex no válidos se omiten automáticamente y se registran como advertencias - no harán fallar tu aplicación.


Usando la Fachada

Para acceso programático a los datos de amenazas fuera del middleware:```php use JayAnta\ThreatDetection\Facades\ThreatDetection;

// Get attack statistics for a specific IP $stats = ThreatDetection::getIpStatistics('192.168.1.1');

// Detect coordinated attacks (multiple IPs targeting same URL within 15 minutes) $attacks = ThreatDetection::detectCoordinatedAttacks(15, 3);

// Detect attack campaigns (same threat type from 5+ IPs in last 24 hours) $campaigns = ThreatDetection::detectAttackCampaigns(24);

// Get a summary of all correlation data $summary = ThreatDetection::getCorrelationSummary();

// Operator-side decision helpers (see "Acting on the Data") $blocked = ThreatDetection::isBlocklisted('203.0.113.7'); // static denylist, CIDR, whitelist wins $trusted = ThreatDetection::isWhitelisted('10.0.0.5'); $count = ThreatDetection::ddosRequestCount('203.0.113.7'); // requests in the current DDoS window $flooded = ThreatDetection::isDdosThresholdExceeded('203.0.113.7');

root@kitploit:~
---

## Puesta en Producción

El paquete es pasivo por diseño: nunca bloquea, rechaza ni altera una solicitud, y el middleware de detección envuelve todo su cuerpo en `try/catch`, por lo que un fallo de detección nunca puede romper tu aplicación. Incluye valores predeterminados sensatos y no necesita servicios externos para funcionar. Antes de salir a producción, merece la pena revisar esta breve lista:

1. **Protege el panel de control y la API.** Ambos usan por defecto `guard = none` para un primer arranque sin configuración, y registran una advertencia diaria mientras no estén protegidos. Antes de producción, establece un guard: `THREAT_DETECTION_DASHBOARD_GUARD` y `THREAT_DETECTION_API_GUARD` (`auth`, `role` o `ip`). Un valor no reconocido o un guard `role` en un modelo de usuario sin `hasRole()` ahora **falla de forma segura** (403), de modo que un error tipográfico no expondrá datos silenciosamente. La desactivación de una detección está controlada por separado mediante `THREAT_DETECTION_API_WRITE_GUARD`, que por defecto es `role`. Consulta [Autenticación del panel y la API](#dashboard-and-api-authentication).
2. **Ejecuta las migraciones** (`vendor:publish --tag=threat-detection-migrations && migrate`). Volver a publicar es seguro: las migraciones ya publicadas se omiten.
3. **Elige un modo de detección.** `balanced` (predeterminado) se adapta a la mayoría de las aplicaciones; usa `relaxed` para sitios con mucho contenido, `strict` para superficies de alta seguridad. Ajusta con `content_paths`, `safe_fields` y `min_confidence`; consulta [Reducción de falsos positivos](#reducing-false-positives).
4. **Revisa los patrones regionales de PII / patrones personalizados.** Los valores predeterminados están centrados en la India (Aadhaar, PAN, IFSC) y los patrones numéricos amplios (p. ej., cuentas bancarias) pueden coincidir con identificadores numéricos largos fuera de las rutas de autenticación. Reemplaza o recorta `custom_patterns` para tu región y aplicación, y añade rutas con mucho contenido a `auth_paths` / `content_paths`.
5. **Activa la retención** si esperas volumen: `THREAT_DETECTION_RETENTION=true` (purga automática mediante el programador). Requiere que el programador de Laravel (`schedule:run`) esté gestionado por cron.
6. **Extras opcionales, todos desactivados por defecto:** alertas de Slack (`THREAT_DETECTION_NOTIFICATIONS`), enriquecimiento geográfico (`php artisan threat-detection:enrich`, la única función que realiza una llamada saliente, al gratuito ip-api.com), y escrituras en cola (`THREAT_DETECTION_QUEUE`: actívalo solo si ya ejecutas un worker de colas; de lo contrario, las escrituras son síncronas y no necesitan Redis).

No se requieren Redis, ni worker de colas, ni llamadas de red salientes para la detección y el registro principales.

---

## Reducción de Falsos Positivos

El paquete ofrece varias herramientas para reducir los falsos positivos. Usa la que mejor se adapte a tu situación:

### Campos Seguros y Rutas Seguras

Excluye un campo del escaneo por completo, ya sea por nombre en todas partes (`safe_fields`) o mediante notación de puntos para JSON anidado (`safe_paths`). Es el enfoque más sencillo y el más contundente: el campo se omite, por lo que no se ejecuta ninguna detección sobre él.

Detalles completos y ejemplos: [Campos Seguros](#safe-fields-false-positive-reduction).

### Supresión por Rutas de Contenido

Si tienes editores CMS, formularios de entradas de blog o secciones de comentarios donde los usuarios envían contenido enriquecido, esas rutas suelen provocar falsos positivos (p. ej., una entrada de blog que contenga ejemplos de código `<script>`). Añade esas rutas para suprimir alertas de baja/media gravedad:```php
// config/threat-detection.php
'content_paths' => [
    'admin/posts/*',
    'admin/pages/*',
    'blog/*/edit',
    'comments',
],

En estas rutas, solo se registran las amenazas de alta severidad.

Reporte de Falsos Positivos

Haz clic en el botón FP en cualquier amenaza del panel para marcarla como falso positivo. Esto:

  1. Marca la amenaza como is_false_positive = true
  2. Crea automáticamente una regla de exclusión para que amenazas similares de la misma URL/tipo se supriman en adelante

Administra las reglas de exclusión mediante la API:```bash GET /api/threat-detection/exclusion-rules DELETE /api/threat-detection/exclusion-rules/{id}

root@kitploit:~
### Puntuación de Confianza

Cada amenaza recibe una puntuación de confianza (0-100) basada en:
- Número de coincidencias de patrones en la misma solicitud
- Gravedad del patrón coincidente
- Dónde se encontró el patrón (cadena de consulta > cabeceras > cuerpo)
- Si el user-agent coincide con una herramienta de ataque conocida
- Modo de detección actual

Las amenazas por debajo del umbral de confianza para tu modo de detección no se registran (consulta [Modos de Detección](#detection-modes)).

---

## Tipos de Ataque Detectados

| Categoría | Ejemplos |
|----------|---------|
| **Inyección SQL** | UNION, booleano, basado en tiempo, codificación CHAR, DDL (DROP/ALTER/CREATE), DML (INSERT/UPDATE/DELETE), operaciones de archivo (INTO OUTFILE, LOAD_FILE), enumeración ORDER BY, cadenas hexadecimales, UNHEX |
| **Inyección NoSQL** | Operadores MongoDB $ne, $gt, $regex, $where |
| **XSS** | Etiquetas script, manejadores de eventos SVG (`<svg onload=`), manejadores de eventos HTML (`<body onload=`, `<img onerror=`), expresiones CSS, URIs JavaScript, manipulación del DOM |
| **Ejecución de Código** | Funciones shell RCE, deserialización PHP, deserialización Java (base64 + bytes mágicos hex), inyección de plantillas (Blade, JSP, ASP, Jinja2, Velocity), eval(), decodificación base64, assert() de PHP, create_function(), preg_replace /e |
| **SSTI** | Sondas matemáticas (`{{7*7}}`), import/config de Jinja2, plantillas Velocity, Expression Language |
| **Inyección de Comandos** | Linux (funciones shell, cadenas de comandos, curl, wget, nc), Windows (cmd.exe, PowerShell, wscript, cscript, net user) |
| **Acceso a Archivos** | Directory traversal, protocolos LFI/RFI, sondeos de archivos sensibles (.env, .git, composer.json) |
| **SSRF** | Localhost (127.0.0.1, 0.0.0.0, ::1), metadatos AWS/GCP, IPs privadas, localhost codificado en hex/decimal, DNS rebinding (xip.io, nip.io, sslip.io) |
| **Inyección LDAP** | Manipulación de filtros LDAP, inyección OR |
| **Inyección XPath** | Selectores de atributos, funciones XPath (contains, substring) |
| **Inyección CRLF / Cabeceras** | CRLF codificado en URL (`%0d%0a`), inyección LF, inyección de byte nulo |
| **Ataques de Protocolo** | HTTP request smuggling (CL+TE), inyección SSI |
| **Explotación de CVEs** | Shellshock (CVE-2014-6271), Spring4Shell (CVE-2022-22965), RCE PHPUnit (CVE-2017-9841), Drupalgeddon, Log4Shell |
| **Seguimiento de Sondas** | WordPress (`/wp-admin`, `/wp-login.php`), archivos de configuración (`/.env`, `/.git`), herramientas de bases de datos (`/phpmyadmin`), sondas de tecnología (`.asp`, `.jsp`), Spring actuator, documentos Swagger/API - más de 50 rutas |
| **Escáneres** | SQLMap, Nikto, Nmap, Burp Suite, FeroxBuster, FFUF, XSStrike, Dalfox, Netsparker, Qualys, Nuclei y más de 20 otros (53 en total) |
| **Rastreadores IA** | GPTBot, ClaudeBot, ChatGPT, ByteSpider, Cohere, Common Crawl |
| **Navegadores Headless** | HeadlessChrome, PhantomJS, Selenium, Puppeteer, Playwright |
| **Bots** | Scripts Python, clientes HTTP Go, cURL, wget, AhrefsBot, SEMRushBot, user agents vacíos |
| **Autenticación** | Detección de fuerza bruta, fugas de tokens, exposición de contraseñas, exposición de IDs de sesión |
| **DDoS** | Detección de solicitudes excesivas basada en tasas |
| **Evasión** | Inserción de comentarios SQL, doble codificación URL, codificación de entidades HTML, escapes Unicode, Unicode IIS, escapes hexadecimales |
| **Otros** | Introspección GraphQL, contaminación de prototipos, redirección abierta, XXE, web shells, minería criptográfica, detección de PII |

---

## Ejecutar la Suite de Pruebas```bash
composer test

El paquete incluye 335 pruebas (856 comprobaciones) que cubren patrones de detección, comportamiento del middleware, endpoints de API, puntuación de confianza, reglas de exclusión, detección de DDoS, resistencia a la evasión, patrones CVE, inyección LDAP/XPath/SSTI, detección de bots/escáneres, seguimiento de sondas, comandos de exportación, autenticación del panel, campos seguros, optimizaciones de rendimiento y verificación completa del ciclo HTTP a BD.


Licencia

Licencia MIT. Consulta LICENSE para más detalles.

Contribuciones

¡Las contribuciones son bienvenidas! Envía una Pull Request.

Créditos

  • Jay Anta - autor y mantenedor
  • David van der Tuijn - soporte para Laravel 13
  • Todos los contribuyentes
Descargar herramienta
Este paquete (IDS de app)WAF (mod_security, Cloudflare WAF)Edge / CDN (Cloudflare)
Bloquea peticiones maliciosas❌ solo registra✅✅
Contexto completo de la app (ruta exacta, payload decodificado, usuario autenticado)✅⚠️ parcial❌
Panel integrado + registro de amenazas en tu BD✅⚠️ varía⚠️ solo edge
Detecciones específicas de la app (p. ej. PII de Aadhaar / PAN / IFSC)✅ patrones personalizados❌❌
Funciona sin conexión / sin servicio externo✅⚠️ depende❌
Detiene el tráfico antes de que llegue a tu app❌✅ edge✅
Configuraciónun composer requiremedia–altabaja–media
Costegratis, MITvaríaplan gratuito + de pago
QuieresUsaEsfuerzo
Ver qué te está atacandoEl panel o threat-detection:statsninguno, ya está en marcha
Banear a los reincidentes en el cortafuegosthreat-detection:export-fail2ban — canalízalo a un cronuna línea
Denegar en el servidor webthreat-detection:export-blocklist → directivas de nginx/apacheuna línea
Rechazar peticiones en la appAyudantes del lado del operador — isBlocklisted(), isDdosThresholdExceeded()~10 líneas de tu propio middleware
Reaccionar en tiempo realEl evento ThreatDetected — Telegram, SIEM, PagerDutyun listener
  • Campos Seguros - Excluye campos de formulario específicos del escaneo (para editores CMS, entradas de código, campos de búsqueda)
  • Informe de Falsos Positivos - Marca amenazas como falsos positivos desde el panel; crea automáticamente reglas de exclusión
  • Tres Modos de Detección - strict, balanced (predeterminado) y relaxed - sensibilidad ajustable
  • Supresión de Rutas de Contenido - Lista blanca de rutas de CMS/blog para suprimir alertas bajas/medias de contenido enriquecido
  • Detección de PII - Patrones de exposición de datos sensibles (configurables por región)
  • Enriquecimiento Geográfico - Identificación de país, ciudad, ISP y proveedor de nube mediante API gratuita
  • Alertas de Slack - Notificaciones en tiempo real para amenazas de alta gravedad (funciona en Laravel 10 y 11+)
  • Panel Integrado - Panel Blade en modo oscuro (Alpine.js + Tailwind CDN, sin paso de compilación)
  • Guardia de Autenticación del Panel - Autenticación configurable para el panel y la API (ninguna, auth, rol o basada en IP)
  • 15 Endpoints de API - API REST completa para crear paneles personalizados en Vue/React/móviles
  • Exportación de Fail2ban - Exporta las IP detectadas en formato compatible con fail2ban o en lista de bloqueo simple
  • Exportación de Lista de Bloqueo - Exporta IPs en formato deny de nginx, deny de Apache, CSV o texto plano
  • Exportación CSV - Exportación del registro de amenazas con un clic (hasta 10 000 filas)
  • Análisis de Correlación - Detecta ataques coordinados y campañas de ataque entre IPs
  • Optimizado para el Rendimiento - Carga diferida de patrones por categoría (solo ejecuta regex para categorías de ataque relevantes), salida temprana para solicitudes limpias, cortocircuito de UA de navegador (omite más de 70 comprobaciones para navegadores normales), búsqueda hash de rutas de sonda, inserciones por lotes en la base de datos, máximo de detecciones configurable por solicitud
  • Independiente de la Base de Datos - MySQL, PostgreSQL, SQLite, SQL Server
  • Configuración Cero - Funciona de inmediato con valores predeterminados sensatos
  • Seguro por Diseño - El middleware captura sus propios errores. Si falla la detección, tu aplicación sigue funcionando. Las solicitudes nunca se bloquean.
  • dashboard.guard
    api.guard