Skip to content
KitploitKITPLOIT
HerramientasExploitsBlog
Log in
Enviar
HerramientasExploitsBlog
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.

FeedsContactoPrivacidad© 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 →
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
31256hace 21 díasRevisado por Kitploit
Compartir
<p align="center">
  <a href="https://packagist.org/packages/jayanta/laravel-threat-detection"><img src="https://img.shields.io/packagist/v/jayanta/laravel-threat-detection.svg?style=flat-square" alt="Latest Version"></a>
  <a href="https://github.com/jay123anta/laravel-threat-detection/actions/workflows/tests.yml"><img src="https://img.shields.io/github/actions/workflow/status/jay123anta/laravel-threat-detection/tests.yml?branch=main&amp;style=flat-square&amp;label=tests" alt="Tests"></a>
  <a href="https://github.com/jay123anta/laravel-threat-detection/actions/workflows/tests.yml"><img src="https://img.shields.io/badge/PHPStan-level%205-brightgreen?style=flat-square" alt="PHPStan Level 5"></a>
  <a href="https://github.com/jay123anta/laravel-threat-detection/actions/workflows/tests.yml"><img src="https://img.shields.io/badge/code%20style-Pint-orange?style=flat-square" alt="Code Style Pint"></a>
  <a href="https://packagist.org/packages/jayanta/laravel-threat-detection"><img src="https://img.shields.io/packagist/dt/jayanta/laravel-threat-detection.svg?style=flat-square" alt="Total Downloads"></a>
  <a href="https://packagist.org/packages/jayanta/laravel-threat-detection"><img src="https://img.shields.io/packagist/php-v/jayanta/laravel-threat-detection?style=flat-square" alt="PHP Version"></a>
  <a href="https://github.com/jay123anta/laravel-threat-detection/blob/main/LICENSE"><img src="https://img.shields.io/packagist/l/jayanta/laravel-threat-detection.svg?style=flat-square" alt="License"></a>
</p>

# Laravel Threat Detection

**Monitoreo de seguridad y registro de ataques para Laravel. Detecta y registra inyección SQL,
XSS, RCE, directory traversal, escáneres de bots y sondas de reconocimiento estilo `/wp-admin` —
cada solicitud hostil registrada en tu base de datos con el contexto completo de la aplicación.
Es un IDS, no un WAF: nunca bloquea, filtra ni modifica una solicitud.**

<p align="center">
  <img src="https://raw.githubusercontent.com/jay123anta/laravel-threat-detection/main/art/demo.gif" alt="Install the package, send three attacks — SQL injection, directory traversal, XSS — every one returns HTTP 200 because nothing is blocked, and all three are already counted in threat-detection:stats" width="100%">
</p>

### ¿Estás aquí porque viste algo como esto?

```
GET /wp-admin/setup-config.php          404   — on a site that isn't WordPress
GET /.env                               404   — someone wants your database password
GET /?id=1' UNION SELECT password FROM  200   — SQL injection against a real route
GET /phpmyadmin/index.php               404   — scanning for an admin panel
```

Esas solicitudes ya están llegando a tu aplicación Laravel. Tu registro de acceso muestra la URL
y el código de estado, y nada más — ni la carga útil decodificada, ni cuál de tus
rutas fue el objetivo, ni si la misma IP ha intentado cuarenta cosas más esta hora.

Este paquete responde a esas preguntas. Colócalo en cualquier aplicación Laravel 10–13 y comenzará
a escanear cada solicitud HTTP contra más de 150 patrones de ataque, puntuando cada coincidencia por
confianza y escribiéndola en tu base de datos — con un panel integrado, alertas de Slack,
enriquecimiento geográfico y exportaciones para fail2ban/listas de bloqueo. Ninguna solicitud se bloquea nunca. Piensa en una cámara de seguridad, no en una cerradura: te muestra exactamente quién está sondeando tus rutas, con qué frecuencia y con qué técnicas.

> Extraído de una aplicación en producción y probado en batalla con tráfico real. Más de 2.400 pruebas, sin dependencias
> en tiempo de ejecución más allá de Laravel mismo, y sin necesidad de conexión a internet para la detección.
>
> ¿Actualizando? Consulta [UPGRADING.md](https://github.com/jay123anta/laravel-threat-detection/blob/main/UPGRADING.md). ¿Contribuyendo? Consulta [CONTRIBUTING.md](https://github.com/jay123anta/laravel-threat-detection/blob/main/CONTRIBUTING.md).

## Comienza en menos de un minuto

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

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) — el fragmento completo está en [Quick Start](#quick-start) más abajo.
Eso es todo; la detección 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 de edge, no para reemplazarlos. Cada capa ve
algo que las demás no pueden:

| | **Este paquete** (IDS de aplicación) | **WAF** (ModSecurity + OWASP CRS, Cloudflare WAF) | **Edge / CDN** (Cloudflare) |
|---|:---:|:---:|:---:|
| Bloquea peticiones maliciosas | ❌ solo registra | ✅ | ✅ |
| Contexto completo de la app (URL exacta, payload decodificado, usuario autenticado) | ✅ | ⚠️ parcial | ❌ |
| Panel integrado + registro de amenazas en tu BD | ✅ | ⚠️ varía | ⚠️ solo en el edge |
| Detecciones específicas de la app (p. ej. PII de Aadhaar / PAN / IFSC) | ✅ integradas + personalizadas | ⚠️ escribe tus propias reglas | ⚠️ reglas personalizadas, según el plan |
| Funciona sin conexión / sin servicio externo | ✅ | ⚠️ depende | ❌ |
| Detiene el tráfico antes de que llegue a tu servidor | ❌ | ⚠️ solo WAF en la nube | ✅ |
| Configuración | `composer require`, migrar, una línea de middleware | media–alta | baja–media |
| Coste | gratis, MIT | varía | capa gratuita + de pago |

**La versión corta:** un edge/WAF es la cerradura de la puerta; esto es la cámara de seguridad
*de dentro*, con el contexto de la app para decirte exactamente qué se está intentando en qué ruta, por
quién y con qué frecuencia. Úsalo para alimentar decisiones reales — baneos de fail2ban, límites de tasa,
bloqueo geográfico — con datos que tu capa de 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 la aplicación de políticas. (¿No tienes una capa de edge a la que delegar? Los
  [helpers del lado del operador](#acting-on-the-data-operator-side-blocking) exponen las
  decisiones del paquete para que puedas escribir tu propio middleware de bloqueo de cinco líneas —
  el código de aplicación de políticas sigue siendo tuyo, no del paquete.)
- **No es un reemplazo de la codificación segura.** Las consultas parametrizadas, la validación de entrada y
  el escapado 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 de edge.** Si puedes poner Cloudflare delante, hazlo — luego añade esto para el
  detalle a nivel de aplicación que los servicios de edge no pueden ver.
- **No es un detector completo, y no puede serlo.** La coincidencia de patrones captura ataques que
  *parecen* ataques conocidos. Una técnica novedosa, o una conocida reescrita lo suficiente, pasará
  sin registrarse — y no se te avisará de que lo hizo. El silencio aquí significa
  "no coincidió nada", nunca "no pasó nada". Donde se gana su lugar es en el
  tráfico de alto volumen y bajo esfuerzo que constituye la mayor parte de lo que realmente golpea una app Laravel pública:
  escáneres, sondas de reconocimiento, cadenas de inyección listas para usar, ataques de credenciales.
  Trata un registro silencioso como ausencia de evidencia, no como evidencia de ausencia.

### Espera que marque tu propio contenido desde el primer día

Una instalación sin ajustar se dispara con contenido legítimo, y deberías saberlo antes
de instalar en lugar de después. Estos son medidos, no hipotéticos. Las filas
de abajo son una muestra del suelo fijado por
[`LegitimateTrafficCorpusTest`](https://github.com/jay123anta/laravel-threat-detection/blob/main/tests/Feature/LegitimateTrafficCorpusTest.php);
cada una lista *todo* lo que esa petición registra, y
[`ReadmeNoiseFloorTest`](https://github.com/jay123anta/laravel-threat-detection/blob/main/tests/Feature/ReadmeNoiseFloorTest.php) hace fallar la
compilación si alguna fila deja de coincidir con lo que la suite mide para ella.

<!-- noise-floor:start -->
| Petición perfectamente legítima | Lo que registra una instalación sin ajustar |
|---|---|
| `how to write a UNION SELECT in postgres` escrito en un cuadro de búsqueda <!-- case: sql tutorial in a search box --> | `SQL Injection UNION` / high |
| Una entrada de blog que contiene `<script>window.dataLayer=[];</script>` <!-- case: javascript snippet in a blog post --> | `XSS Script Tag` / high · `Command Chain Injection` / medium |
| Un ticket de soporte con un error `SELECT * FROM users WHERE id = 1` pegado <!-- case: a pasted sql error in a support ticket --> | `SQLi Variant` / high · `SQL SELECT Query` / low |
| Documentación que explica que `../../etc/passwd` es el payload clásico de traversal <!-- case: a traversal explainer in documentation --> | `Directory Traversal` / medium · `Sensitive File Access` / medium |
| Un formulario de perfil que recoge un número de móvil indio y un PAN genuinos <!-- case: a profile form collecting genuine indian pii --> | `PAN Number Detected` / high · `Bank Account Number Detected` / high · `Mobile Number Detected` / low |
<!-- noise-floor:end -->

**Ninguno de estos son errores.** Una entrada de blog que contiene `<script>` es, byte por byte, un
payload de XSS almacenado; una búsqueda de `UNION SELECT` es indistinguible de un intento
de ello; un número de móvil de diez dígitos también es un número de cuenta bancaria plausible. Nada
salvo el contexto de la aplicación los separa, y ningún motor de patrones puede aportarte ese
contexto.

Aportarlo es un cambio de configuración de una línea: nombra el campo que legítimamente contiene
tal contenido en `safe_fields` (o `safe_paths`, para una ruta dentro de JSON anidado) y
deja de escanearse. Ese es el interruptor que silencia las filas de arriba — y es
un intercambio real, ya que un ataque entregado a través de ese campo también pasa desapercibido.

`content_paths` y el modo `relaxed` son herramientas diferentes. Descartan el ruido de severidad baja y
media, y **deliberadamente siguen registrando coincidencias de severidad alta** —
así que no silenciarán las filas altas de esta tabla, por diseño. Consulta
[Reducing False Positives](#reducing-false-positives) para saber cuál usar según el caso.

**Si tu app acepta texto enriquecido, muestras de código o consultas de búsqueda, hazlo antes de
juzgar la salida.** El valor por defecto es deliberadamente ruidoso-pero-honesto en lugar de
silencioso-e-incompleto: es más fácil silenciar una coincidencia conocida que descubrir una que
nunca se disparó.

### Entonces, ¿qué haces realmente con esto?

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

| Quieres | Usa | Esfuerzo |
|---|---|---|
| Ver qué te está golpeando | El [panel](#dashboard) o `threat-detection:stats` | ninguno, ya está en marcha |
| Banear a los reincidentes en el firewall | [`threat-detection:export-fail2ban`](#artisan-commands) — canalizar a un cron | una línea |
| Denegar en el servidor web | [`threat-detection:export-blocklist`](#artisan-commands) → directivas de nginx/apache | una línea |
| Rechazar peticiones dentro de la app | [Helpers del lado del operador](#acting-on-the-data-operator-side-blocking) — `isBlocklisted()`, `isDdosThresholdExceeded()` | ~10 líneas de tu propio middleware |
| Reaccionar en tiempo real | El [evento `ThreatDetected`](#threatdetected-event) — Telegram, SIEM, PagerDuty | un listener |

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


### Cómo se compara con otros paquetes de seguridad de Laravel

Estos resuelven problemas diferentes y se componen bien — la tabla trata de elegir la
herramienta correcta, no de ganar.

| Paquete | Qué hace | ¿Bloquea? | Úsalo cuando |
|---|---|:---:|---|
| **este paquete** | Escanea cada petición contra más de 150 patrones, registra con contexto completo de la app | ❌ | Quieres *ver* qué se está intentando en tu app |
| `spatie/laravel-honeypot` | Campo de formulario oculto que atrapa bots de spam | ✅ solo formularios | Tienes formularios públicos recibiendo spam |
| `graham-campbell/security` | Elimina marcado tipo XSS de la entrada | ✅ muta | Quieres un saneamiento de entrada ingenuo |
| `spatie/laravel-csp` | Envía cabeceras Content-Security-Policy | ✅ navegador | Quieres restringir lo que carga el navegador |
| `laravel/fortify` + límites de tasa | Limitación y bloqueo de autenticación | ✅ | Necesitas protección contra fuerza bruta en el login |
| Cloudflare / mod_security | WAF de edge, bloquea antes de tu app | ✅ | Quieres detener el tráfico antes de que llegue |

El resumen honesto: un honeypot atrapa spam de formularios, un WAF bloquea tráfico conocido como malicioso
en el edge, y CSP restringe el navegador. **Ninguno de ellos te dice qué intentó un
atacante contra tus rutas específicas, con el payload decodificado y el
usuario autenticado adjunto.** Ese hueco es lo que esto llena — y es por lo que el
paquete deliberadamente no bloquea: puedes ejecutarlo junto a todo lo anterior
sin que ninguno se pelee con los demás.

---

## Requisitos

- PHP 8.2+ (Laravel 13 requiere PHP 8.3+)
- Laravel 10.x, 11.x, 12.x o 13.x
- Cualquier base de datos soportada por 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 comprueba contra 158 patrones regex que cubren inyección SQL, XSS, RCE, traversal de archivos, SSRF, LDAP, XPath, SSTI y más
3. Si coincide un patrón de amenaza, se escribe un registro en tu tabla de base de datos `threat_logs` con la IP, URL, tipo de amenaza, nivel de severidad y una puntuación de confianza
4. Opcionalmente, se envía una alerta a Slack para amenazas de severidad alta
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. Instala el paquete

```bash
composer require jayanta/laravel-threat-detection
```

### 2. Publicar las 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 las amenazas detectadas) y `threat_exclusion_rules` (almacena las reglas de falsos positivos).

**Verificar que las tablas fueron creadas:**
```bash
php artisan migrate:status
```
Busca `create_threat_logs_table`, `add_confidence_to_threat_logs_table` y `create_threat_exclusion_rules_table` - todos deberían mostrar `Ran`.

### 3. Registra el middleware

El middleware es lo que escanea las solicitudes. Necesitas agregarlo 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,
    ],
];
```

### 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 omites 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 registró.

### Paso 1: Inicia tu aplicación

```bash
php artisan serve
```

### 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=<script>alert(1)</script>
```

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

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

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

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

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

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

### Paso 3: Verificar que las amenazas se registraron

**Opción A - Comando Artisan (la más rápida):**
```bash
php artisan threat-detection:stats
```
Deberías ver una tabla con `Recorded Detections`, recuentos de severidad y las IPs
principales. Ese número cuenta *filas*, no intentos: una detección se escribe una vez por
IP por tipo de amenaza cada cinco minutos, y las repeticiones dentro de esa ventana se
deduplican en lugar de contarse de nuevo.

**Opción B - Tinker:**
```bash
php artisan tinker
```
```php
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%]
```

### Cosas que debes saber al realizar pruebas

| 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 almacena en caché durante 5 minutos. Usa **tipos de ataque diferentes** para cada prueba, o espera entre pruebas. |
| Las solicitudes `curl` activan una 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 solicitudes | 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 obtener geodatos. |

### Solución de problemas

**Empieza aquí — un solo comando responde a 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.
```

Qué cubre: detección habilitada para este entorno; cada columna que el escritor
necesita (una faltante descarta **cada** amenaza); columnas del dashboard/API; la
tabla de reglas de exclusión; si el middleware está realmente conectado a una ruta o
grupo; configuración publicada anterior a esta versión; patrones personalizados que
sustituyen a los integrados; un controlador de caché que no puede hacer conteo de DDoS; y un dashboard o
API dejado 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 solicitud de prueba
en sí. Tres cosas que no puede verificar por ti:

| Verificación | Cómo verificar |
|-------|---------------|
| La IP no está en la lista blanca | Si agregaste `THREAT_DETECTION_WHITELISTED_IPS` a `.env`, elimínalo 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 | La misma IP + el mismo tipo de ataque se almacena en caché durante 5 minutos - prueba con un tipo de ataque diferente |

> Ejecutar solo `php artisan migrate` nunca es suficiente: los archivos de migración viven
> dentro del paquete y deben publicarse primero en el `database/migrations/` de tu aplicación.
> 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 dashboard muestra 404"**

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

---

## Características

- **Más de 150 patrones de detección** -  Inyección SQL (UNION, DDL, DML, operaciones de archivos), 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 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 firmas de otros 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 sondeos 404** -  Detecta sondeos de reconocimiento que acceden a rutas vulnerables conocidas (`/wp-admin`, `/.env`, `/phpmyadmin`, `/actuator`, etc.) con más de 50 rutas de sondeo predeterminadas, además de un [paquete opcional de infraestructura de IA](#ai-infrastructure-probes-opt-in) para gateways LLM expuestos
- **Monitoreo de DDoS** -  Detección de umbrales 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 recuento de patrones, el contexto y las señales
- **Resistencia a la evasión** -  El pipeline de normalización neutraliza la inserción de comentarios SQL, la doble codificación URL, la codificación de entidades HTML, los escapes Unicode, los escapes hexadecimales y la codificación `%uXXXX` de IIS antes de la coincidencia de patrones — se repite hasta que el payload deja de cambiar, por lo que apilar dos técnicas no logra evadirlo
- **Detección de CVE** -  Shellshock (CVE-2014-6271), Spring4Shell (CVE-2022-22965), PHPUnit RCE (CVE-2017-9841), Drupalgeddon, Log4Shell
- **Detección sensible al contexto** -  Los patrones encontrados en las cadenas de consulta puntúan más alto 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`)
- **Campos seguros** -  Excluye campos de formulario específicos del escaneo (para editores de CMS, entradas de código, campos de búsqueda)
- **Reporte 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** -  Incluye en la lista blanca rutas de CMS/blog para suprimir alertas de nivel bajo/medio procedentes de contenido enriquecido
- **Detección de PII** -  Patrones de exposición de datos sensibles (configurables por región)
- **Geo-enriquecimiento** -  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 severidad (funciona en Laravel 10 y 11+)
- **Panel integrado** -  Panel Blade en modo oscuro (Alpine.js y Tailwind, estilos precompilados, sin paso de compilación)
- **Protección 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óvil
- **Exportación para Fail2ban** -  Exporta las IP detectadas en formato compatible con fail2ban o como lista de bloqueo simple
- **Exportación de listas de bloqueo** -  Exporta IP en formato nginx deny, Apache deny, 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 IP
- **Rendimiento optimizado** -  Carga diferida de patrones por categoría (solo ejecuta regex para las categorías de ataque relevantes), salida temprana para solicitudes limpias, cortocircuito por UA de navegador (omite más de 70 comprobaciones para navegadores normales), búsqueda por hash de rutas de sondeo, inserciones por lotes en la base de datos, máximo de detecciones configurable por solicitud
- **Agnóstico respecto a la base de datos** -  MySQL, PostgreSQL, SQLite, SQL Server
- **Configuración cero** -  Funciona desde el primer momento con valores predeterminados sensatos
- **Seguro por diseño** -  El middleware captura sus propios errores. Si la detección falla, tu aplicación sigue funcionando. Las solicitudes nunca se bloquean.

---

## Configuración

El paquete funciona sin ningún cambio en `.env`. Todos los valores a continuación son opcionales -  añádelos solo si deseas sobrescribir 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

# Your ISO 3166-1 alpha-2 country code (default: IN)
# Drives the is_foreign flag on every enriched row — set this or every
# non-Indian address is reported as foreign.
# THREAT_DETECTION_HOME_COUNTRY=IN

# Geo-enrichment provider used by threat-detection:enrich (default shown).
# HTTPS since v1.8.0. A failed lookup is never retried over cleartext, and a
# run in which every lookup failed exits non-zero rather than reporting
# success. Enrichment is opt-in either way.
#
# ip-api.com's free tier rejects HTTPS, so on the free tier this command will
# now fail rather than quietly sending your visitors' IP addresses in the
# clear. Either point it at a provider you hold a key for, or set it back
# explicitly and accept the disclosure.
# THREAT_DETECTION_GEO_ENDPOINT=https://ip-api.com/json

# Dashboard URL path (default: threat-detection)
# THREAT_DETECTION_DASHBOARD_PATH=threat-detection

# API route prefix (default: api/threat-detection)
# THREAT_DETECTION_API_PREFIX=api/threat-detection

# Role required when the API guard is 'role' (default: admin)
# THREAT_DETECTION_API_ROLE=admin

# Allowed IPs when the API guard is 'ip'. Comma-separated, CIDR supported.
# THREAT_DETECTION_API_IPS=127.0.0.1,10.0.0.0/8

# Username shown on Slack alerts (default: ThreatBot)
# THREAT_DETECTION_SLACK_USERNAME=ThreatBot

# 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
```

### Modos de detección

| Modo | Umbral de confianza | Comportamiento |
|------|---------------------|----------|
| `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` | 25 | Solo se ejecutan patrones de alta severidad. Ideal para sitios con mucho contenido y falsos positivos frecuentes. (Era 40 antes de v1.8.0 — un mínimo que ninguna detección individual podía alcanzar, por lo que el modo no registraba nada silenciosamente.) |

### Entornos habilitados

Por defecto, 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 deshabilitar la detección en tu suite de pruebas, establece `APP_ENV=testing` (no está en la lista anterior) o añade a tu `phpunit.xml`:
```xml
<env name="THREAT_DETECTION_ENABLED" value="false"/>
```

### Referencia de configuración

Publique el archivo de configuración para ver todas las opciones disponibles:

```bash
php artisan vendor:publish --tag=threat-detection-config
```

---

[Read more](https://github.com/jay123anta/laravel-threat-detection)
Descargar herramienta