
Middleware Laravel passivo que detecta e registra injeção de SQL, XSS, RCE, scanners de bot e mais de 175 padrões de ataque. Inclui painel integrado, alertas do Slack, API REST e enriquecimento geográfico. IDS, não WAF.
<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&style=flat-square&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
**Monitoramento de segurança e registro de ataques para Laravel. Detecte e registre injeção de SQL,
XSS, RCE, directory traversal, scanners de bots e sondagens de reconhecimento no estilo `/wp-admin` —
cada requisição hostil registrada no seu banco de dados com o contexto completo da aplicação.
É um IDS, não um WAF: ele nunca bloqueia, filtra ou modifica uma requisição.**
<p align="center">
<img src="https://raw.githubusercontent.com/jay123anta/laravel-threat-detection/main/art/demo.gif" alt="Instale o pacote, envie três ataques — injeção de SQL, directory traversal, XSS — todos retornam HTTP 200 porque nada é bloqueado, e os três já estão contabilizados em threat-detection:stats" width="100%">
</p>
### Você está aqui porque viu algo parecido com isto?
```
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
```
Essas requisições já estão chegando ao seu aplicativo Laravel. Seu log de acesso mostra a URL
e o código de status, e nada mais — nem o payload decodificado, nem qual das suas
rotas foi alvo, nem se o mesmo IP já tentou outras quarenta coisas nesta hora.
Este pacote responde a essas perguntas. Coloque-o em qualquer aplicativo Laravel 10–13 e ele começa
a escanear cada requisição HTTP em busca de mais de 150 padrões de ataque, pontuando cada correspondência por
confiança e gravando-a no seu banco de dados — com um dashboard integrado, alertas no Slack,
enriquecimento geográfico e exportações para fail2ban/blocklist. Nenhuma requisição é bloqueada. Pense
em câmera de segurança, não em fechadura: ela mostra exatamente quem está sondando suas rotas, com que
frequência e com quais técnicas.
> Extraído de um aplicativo em produção e testado em batalha com tráfego real. Mais de 2.400 testes, sem dependências
> de runtime além do próprio Laravel, e nenhuma conexão com a internet necessária para detecção.
>
> Atualizando? Veja [UPGRADING.md](https://github.com/jay123anta/laravel-threat-detection/blob/main/UPGRADING.md). Quer contribuir? Veja [CONTRIBUTING.md](https://github.com/jay123anta/laravel-threat-detection/blob/main/CONTRIBUTING.md).
## Comece em menos de um minuto
```bash
composer require jayanta/laravel-threat-detection
php artisan vendor:publish --tag=threat-detection-migrations
php artisan migrate
```
Em seguida, adicione o middleware ao seu grupo `web` (uma linha em `bootstrap/app.php` no Laravel 11+,
ou `app/Http/Kernel.php` no Laravel 10) — trecho completo em [Quick Start](#quick-start) abaixo.
É isso; a detecção está ativa.
```bash
php artisan threat-detection:doctor # confirms it is actually recording
```
---
## Onde se encaixa: IDS vs WAF vs edge
Este pacote é um **IDS passivo, ao nível da aplicação** — observa e registra, não
bloqueia. Ele foi feito para ficar *ao lado* de um WAF ou serviço de edge, não para substituí-lo. Cada camada vê
algo que as outras não conseguem:
| | **Este pacote** (IDS de app) | **WAF** (ModSecurity + OWASP CRS, Cloudflare WAF) | **Edge / CDN** (Cloudflare) |
|---|:---:|:---:|:---:|
| Bloqueia requisições maliciosas | ❌ apenas registra | ✅ | ✅ |
| Contexto completo da app (URL exata, payload decodificado, usuário autenticado) | ✅ | ⚠️ parcial | ❌ |
| Dashboard integrado + log de ameaças no seu banco | ✅ | ⚠️ varia | ⚠️ apenas no edge |
| Detecções específicas da app (ex.: PII de Aadhaar / PAN / IFSC) | ✅ integrado + personalizado | ⚠️ escreva suas próprias regras | ⚠️ regras personalizadas, dependente do plano |
| Funciona offline / sem serviço externo | ✅ | ⚠️ depende | ❌ |
| Interrompe o tráfego antes de chegar ao seu servidor | ❌ | ⚠️ apenas WAF em nuvem | ✅ |
| Configuração | `composer require`, migrar, uma linha de middleware | média–alta | baixa–média |
| Custo | gratuito, MIT | varia | camada gratuita + pago |
**Resumindo:** um edge/WAF é a fechadura da sua porta; isto é a câmera de segurança
*do lado de dentro*, com o contexto da app para lhe dizer exatamente o que está sendo tentado em qual rota, por
quem, e com que frequência. Use-o para alimentar decisões reais — bans do fail2ban, limites de taxa,
geo-bloqueio — com dados que sua camada de edge nunca vê.
### O que ele deliberadamente NÃO é
- **Não é um WAF.** Ele nunca bloqueia, filtra ou modifica uma requisição. Use Cloudflare,
mod_security, ou um WAF de verdade para aplicação de políticas. (Sem camada de edge para delegar? Os
[helpers do lado do operador](#acting-on-the-data-operator-side-blocking) expõem as
decisões do pacote para que você possa escrever seu próprio middleware de bloqueio de cinco linhas —
o código de aplicação de políticas continua sendo seu, não do pacote.)
- **Não substitui a codificação segura.** Consultas parametrizadas, validação de entrada e
escape de saída são suas defesas reais. Este pacote assume que seu código já é
seguro e lhe dá *visibilidade*, não proteção.
- **Não é um serviço de edge.** Se você puder colocar o Cloudflare na frente, faça — depois adicione isto para o
detalhamento ao nível da aplicação que os serviços de edge não conseguem ver.
- **Não é um detector completo, e não pode ser.** Correspondência de padrões captura ataques que
*parecem* ataques conhecidos. Uma técnica nova, ou uma familiar reescrita o suficiente, vai
passar sem ser registrada — e você não será avisado de que isso aconteceu. Silêncio aqui significa
"nada correspondeu", nunca "nada aconteceu". Onde ele ganha seu lugar é no
tráfego de alto volume e baixo esforço que compõe a maior parte do que realmente atinge uma aplicação
Laravel pública: scanners, sondagens de reconhecimento, strings de injeção prontas, pulverização de
credenciais. Trate um log silencioso como ausência de evidência, não como evidência de ausência.
### Espere que ele sinalize seu próprio conteúdo no primeiro dia
Uma instalação não ajustada dispara em conteúdo legítimo, e você deveria saber disso antes
de instalar, não depois. Estes são medidos, não hipotéticos. As linhas
abaixo são uma amostra do piso fixado por
[`LegitimateTrafficCorpusTest`](https://github.com/jay123anta/laravel-threat-detection/blob/main/tests/Feature/LegitimateTrafficCorpusTest.php);
cada uma lista *tudo* que aquela requisição registra, e
[`ReadmeNoiseFloorTest`](https://github.com/jay123anta/laravel-threat-detection/blob/main/tests/Feature/ReadmeNoiseFloorTest.php) falha a
build se qualquer linha deixar de corresponder ao que a suíte mede para ela.
<!-- noise-floor:start -->
| Requisição perfeitamente legítima | O que uma instalação não ajustada registra |
|---|---|
| `how to write a UNION SELECT in postgres` digitado em uma caixa de busca <!-- case: sql tutorial in a search box --> | `SQL Injection UNION` / high |
| Um post de blog contendo `<script>window.dataLayer=[];</script>` <!-- case: javascript snippet in a blog post --> | `XSS Script Tag` / high · `Command Chain Injection` / medium |
| Um ticket de suporte com um erro `SELECT * FROM users WHERE id = 1` colado <!-- case: a pasted sql error in a support ticket --> | `SQLi Variant` / high · `SQL SELECT Query` / low |
| Documentação explicando que `../../etc/passwd` é o payload clássico de traversal <!-- case: a traversal explainer in documentation --> | `Directory Traversal` / medium · `Sensitive File Access` / medium |
| Um formulário de perfil coletando um número de celular indiano genuíno e PAN <!-- case: a profile form collecting genuine indian pii --> | `PAN Number Detected` / high · `Bank Account Number Detected` / high · `Mobile Number Detected` / low |
<!-- noise-floor:end -->
**Nenhum destes são bugs.** Um post de blog contendo `<script>` é, byte a byte, um
payload de XSS armazenado; uma busca por `UNION SELECT` é indistinguível de uma tentativa
de fazê-lo; um número de celular de dez dígitos também é um número de conta bancária plausível. Nada
além do contexto da aplicação os separa, e nenhum motor de padrões pode fornecer esse
contexto para você.
Fornecê-lo é uma mudança de configuração de uma linha: nomeie o campo que legitimamente carrega
tal conteúdo em `safe_fields` (ou `safe_paths`, para um caminho dentro de JSON aninhado) e
ele não será mais escaneado. Esse é o interruptor que silencia as linhas acima — e é
uma troca real, já que um ataque entregue através desse campo também passa despercebido.
`content_paths` e o modo `relaxed` são ferramentas diferentes. Eles descartam ruído de
severidade baixa e média, e **deliberadamente continuam registrando correspondências de alta severidade** —
então eles não vão silenciar as linhas de alta severidade nesta tabela, por design. Veja
[Reduzindo Falsos Positivos](#reducing-false-positives) para saber qual usar em cada caso.
**Se sua app aceita rich text, exemplos de código ou consultas de busca, faça isso antes de
julgar a saída.** O padrão é deliberadamente ruidoso-mas-honesto em vez de
silencioso-e-incompleto: é mais fácil silenciar uma correspondência conhecida do que descobrir uma que
nunca disparou.
### Então o que você realmente faz com isso?
A pergunta mais comum sobre um detector que nunca bloqueia. Quatro respostas, em
ordem crescente de esforço:
| Você quer | Use | Esforço |
|---|---|---|
| Ver o que está te atingindo | O [dashboard](#dashboard) ou `threat-detection:stats` | nenhum, já está rodando |
| Banir reincidentes no firewall | [`threat-detection:export-fail2ban`](#artisan-commands) — canalize para um cron | uma linha |
| Negar no servidor web | [`threat-detection:export-blocklist`](#artisan-commands) → diretivas nginx/apache | uma linha |
| Recusar requisições na app | [Helpers do lado do operador](#acting-on-the-data-operator-side-blocking) — `isBlocklisted()`, `isDdosThresholdExceeded()` | ~10 linhas do seu próprio middleware |
| Reagir em tempo real | O [evento `ThreatDetected`](#threatdetected-event) — Telegram, SIEM, PagerDuty | um listener |
O pacote fornece a inteligência; você fornece a recusa. Essa divisão é
deliberada — código de aplicação de políticas que vive na sua app é código que você pode ler,
testar e desligar, e significa que um bug de detecção nunca pode derrubar seu site.
### Como se compara a outros pacotes de segurança para Laravel
Estes resolvem problemas diferentes e se compõem bem — a tabela é sobre escolher a
ferramenta certa, não sobre ganhar.
| Pacote | O que faz | Bloqueia? | Use quando |
|---|---|:---:|---|
| **este pacote** | Escaneia cada requisição contra 150+ padrões, registra com contexto completo da app | ❌ | Você quer *ver* o que está sendo tentado na sua app |
| `spatie/laravel-honeypot` | Campo de formulário oculto que captura bots de spam | ✅ apenas formulário | Você tem formulários públicos recebendo spam |
| `graham-campbell/security` | Remove marcação do tipo XSS da entrada | ✅ modifica | Você quer sanitização ingênua de entrada |
| `spatie/laravel-csp` | Envia cabeçalhos Content-Security-Policy | ✅ navegador | Você quer restringir o que o navegador carrega |
| `laravel/fortify` + limites de taxa | Throttling e bloqueio de autenticação | ✅ | Você precisa de proteção contra força bruta no login |
| Cloudflare / mod_security | WAF de edge, bloqueia antes da sua app | ✅ | Você quer o tráfego interrompido antes de chegar |
O resumo honesto: um honeypot captura spam de formulário, um WAF bloqueia tráfego conhecido como malicioso
no edge, e o CSP restringe o navegador. **Nenhum deles lhe diz o que um
atacante tentou contra suas rotas específicas, com o payload decodificado e o
usuário autenticado anexado.** Essa lacuna é o que isto preenche — e é por isso que o
pacote deliberadamente não bloqueia: você pode executá-lo junto com todos os acima
sem que nenhum deles entre em conflito.
---
## Requisitos
- PHP 8.2+ (Laravel 13 requer PHP 8.3+)
- Laravel 10.x, 11.x, 12.x ou 13.x
- Qualquer banco de dados suportado pelo Laravel (MySQL, PostgreSQL, SQLite, SQL Server)
- Qualquer driver de cache - **nenhum Redis ou worker de fila é necessário**. Redis/Memcached é
apenas *recomendado* para habilitar a verificação opcional de DDoS (que se desativa automaticamente em
drivers não atômicos). Escritas enfileiradas são opt-in e desativadas por padrão.
---
## Como Funciona
1. Um middleware escaneia cada requisição HTTP recebida
2. A requisição é verificada contra 158 padrões regex cobrindo injeção SQL, XSS, RCE, travessia de arquivos, SSRF, LDAP, XPath, SSTI e mais
3. Se um padrão de ameaça corresponder, um registro é gravado na sua tabela de banco de dados `threat_logs` com o IP, URL, tipo de ameaça, nível de severidade e uma pontuação de confiança
4. Opcionalmente, um alerta no Slack é enviado para ameaças de alta severidade
5. A requisição prossegue normalmente - **nada é bloqueado**
Nenhuma conexão com a internet é necessária para a detecção.
---
## Início Rápido
### 1. Instale o pacote
```bash
composer require jayanta/laravel-threat-detection
```
### 2. Publique as migrations e execute-as
> **Este passo é obrigatório.** Sem ele, o pacote detectará ameaças, mas não poderá armazená-las no banco de dados. Se você pular este passo, sua tabela `threat_logs` não existirá e todas as detecções serão silenciosamente perdidas (você verá apenas erros em `storage/logs/laravel.log`).
```bash
php artisan vendor:publish --tag=threat-detection-migrations
php artisan migrate
```
Isso cria duas tabelas: `threat_logs` (armazena ameaças detectadas) e `threat_exclusion_rules` (armazena regras de falsos positivos).
**Verifique se as tabelas foram criadas:**
```bash
php artisan migrate:status
```
Procure por `create_threat_logs_table`, `add_confidence_to_threat_logs_table` e `create_threat_exclusion_rules_table` - todos devem mostrar `Ran`.
### 3. Registre o middleware
O middleware é o que escaneia as requisições. Você precisa adicioná-lo ao seu grupo de middleware `web`.
**Se você usa Laravel 11 ou 12** - abra `bootstrap/app.php`:
```php
->withMiddleware(function (Middleware $middleware) {
$middleware->web(append: [
\JayAnta\ThreatDetection\Http\Middleware\ThreatDetectionMiddleware::class,
]);
})
```
> **Como verificar a sua versão do Laravel:** Execute `php artisan --version` no seu terminal.
**Se você usa Laravel 10** - abra `app/Http/Kernel.php`:
```php
protected $middlewareGroups = [
'web' => [
// ... existing middleware
\JayAnta\ThreatDetection\Http\Middleware\ThreatDetectionMiddleware::class,
],
];
```
### 4. (Opcional) Publicar o arquivo de configuração
```bash
php artisan vendor:publish --tag=threat-detection-config
```
O pacote funciona com padrões sensatos. Publicar a configuração permite personalizar padrões de deteção, modos de sensibilidade, notificações do Slack e muito mais. Se ignorar este passo, tudo continua a funcionar.
**É isso.** A sua aplicação está agora a detetar ameaças.
---
## Verificar se funciona
Após a instalação, acione uma ameaça de teste e confirme que foi registada.
### Passo 1: Inicie a sua aplicação
```bash
php artisan serve
```
### Passo 2: Abra uma URL de teste no seu navegador
Anexe um parâmetro de consulta malicioso a **qualquer rota existente** no seu app (sua página inicial, uma página de produto, etc.). Por exemplo:
**Injeção de SQL:**
```
http://localhost:8000/?q=' UNION SELECT * FROM users--
```
**XSS (Cross-Site Scripting):**
```
http://localhost:8000/?q=<script>alert(1)</script>
```
**Directory Traversal:**
```
http://localhost:8000/?file=../../etc/passwd
```
**RCE (Execução Remota de Código):**
```
http://localhost:8000/?cmd=system('ls -la')
```
**Shellshock (CVE-2014-6271):**
```
http://localhost:8000/?cmd=() { :;}; /bin/bash
```
**Injeção de Comandos no Windows:**
```
http://localhost:8000/?cmd=powershell -c whoami
```
**DROP TABLE (SQL DDL):**
```
http://localhost:8000/?q=DROP TABLE users
```
> Use uma rota que realmente exista na sua aplicação (como `/`). Se a URL retornar um 404, o middleware pode não ter sido executado.
### Passo 3: Verifique se as ameaças foram registradas
**Opção A - Comando Artisan (mais rápido):**
```bash
php artisan threat-detection:stats
```
Você deve ver uma tabela com `Recorded Detections`, contagens de severidade e os principais
IPs. Esse número conta *linhas*, não tentativas: uma detecção é escrita uma vez por
IP por tipo de ameaça a cada cinco minutos, e repetições dentro dessa janela são
deduplicadas em vez de contadas novamente.
**Opção B - Tinker:**
```bash
php artisan tinker
```
```php
DB::table('threat_logs')->latest()->take(5)->get(['ip_address', 'type', 'threat_level', 'confidence_score']);
```
**Opção C - Arquivo de log do Laravel:**
Cada ameaça detectada é registrada como um aviso em `storage/logs/laravel.log`:
```
[high] Threat Detected: [middleware] SQL Injection UNION from 127.0.0.1 (http://localhost:8000/?q=...) [confidence: 50%]
```
### O que saber ao testar
| Comportamento | Explicação |
|----------|-------------|
| A mesma ameaça só é registada uma vez a cada 5 minutos | Deduplicação: o mesmo IP + o mesmo tipo de ameaça é colocado em cache durante 5 minutos. Use **tipos de ataque diferentes** para cada teste, ou aguarde entre testes. |
| Pedidos `curl` desencadeiam deteção adicional | Usar `curl` também regista uma deteção de user-agent "cURL Command" (gravidade baixa). Isto é esperado - o pacote deteta ferramentas automatizadas. |
| O pacote nunca bloqueia pedidos | A sua aplicação continua a funcionar normalmente. A deteção é passiva. |
| Não é necessária configuração do Slack | As notificações estão desativadas por predefinição. |
| Não é necessária ligação à internet | A deteção principal é 100% local. Apenas o comando opcional `threat-detection:enrich` chama uma API externa para geo-dados. |
### Resolução de problemas
**Comece aqui — um comando responde à maior parte disto:**
```bash
php artisan threat-detection:doctor
```
Ele verifica as coisas que fazem a deteção falhar *silenciosamente* — onde o dashboard
permanece vazio, o que parece idêntico a "sem ataques" — e imprime a correção exata
para cada uma. Termina com código diferente de zero numa falha real, por isso é seguro executá-lo em CI ou num
passo de deploy.
```
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.
```
O que cobre: deteção ativada para este ambiente; todas as colunas de que o writer
necessita (uma coluna em falta descarta **todas** as ameaças); colunas do dashboard/API; a
tabela de regras de exclusão; se o middleware está realmente ligado a uma rota ou
grupo; configuração publicada anterior a esta versão; padrões personalizados que fazem sombra aos
incorporados; um driver de cache que não consegue fazer contagem de DDoS; e um dashboard ou
API deixado aberto sem autenticação.
**"Testei mas `threat-detection:stats` mostra zero ameaças" / "As ameaças não são armazenadas na base de dados"**
Se o doctor passou, a instalação está bem e o problema é o próprio pedido de
teste. Três coisas que ele não consegue verificar por ti:
| Verificação | Como verificar |
|-------|---------------|
| O IP não está na whitelist | Se adicionaste `THREAT_DETECTION_WHITELISTED_IPS` ao `.env`, remove-o durante os testes |
| Usaste uma rota existente | O URL de teste tem de corresponder a uma rota real (por exemplo, `/`). Um 404 significa que o middleware nunca correu |
| Cache de deduplicação | O mesmo IP + o mesmo tipo de ataque é colocado em cache durante 5 minutos - tenta um tipo de ataque diferente |
> Executar apenas `php artisan migrate` nunca é suficiente: os ficheiros de migração vivem
> dentro do pacote e têm de ser publicados primeiro em `database/migrations/` da tua app.
> O doctor imprime o comando exato quando este é o problema.
**"A API devolve 401 Unauthorized"**
Ver [Autenticação da API](#api-authentication) abaixo.
**"O dashboard mostra 404"**
O dashboard está desativado por predefinição. Adiciona `THREAT_DETECTION_DASHBOARD=true` ao `.env` e limpa a cache de rotas:
```bash
php artisan route:clear
```
---
## Recursos
- **Mais de 150 Padrões de Detecção** - Injeção SQL (UNION, DDL, DML, operações de arquivo), XSS (script, SVG, expressão CSS), RCE, travessia de diretório, SSRF, XXE, Log4Shell, injeção NoSQL, injeção de comando (Linux + Windows), injeção LDAP, injeção XPath, SSTI, injeção CRLF, desserialização Java, e mais
- **83 Assinaturas de Bots/Scanners** - SQLMap, Nikto, Nmap, Burp Suite, FeroxBuster, FFUF, XSStrike, Dalfox, Netsparker, e mais de 70 outras assinaturas de scanners e bots
- **Detecção de Scrapers de IA** - GPTBot, ClaudeBot, ByteSpider, Common Crawl, e outros bots de treinamento de IA
- **Detecção de Navegadores Headless** - HeadlessChrome, PhantomJS, Selenium, Puppeteer, Playwright
- **Rastreamento de Sondagens 404** - Detecta sondagens de reconhecimento atingindo caminhos vulneráveis conhecidos (`/wp-admin`, `/.env`, `/phpmyadmin`, `/actuator`, etc.) com mais de 50 caminhos de sondagem padrão, além de um [pacote opcional de infraestrutura de IA](#ai-infrastructure-probes-opt-in) para gateways LLM expostos
- **Monitoramento de DDoS** - Detecção de limiar baseada em taxa com janelas configuráveis
- **Pontuação de Confiança** - Cada ameaça recebe uma pontuação de confiança de 0 a 100 baseada na contagem de padrões, contexto e sinais
- **Resistência a Evasão** - O pipeline de normalização derrota inserção de comentários SQL, codificação dupla de URL, codificação de entidades HTML, escapes Unicode, escapes hexadecimais e codificação IIS `%uXXXX` antes da correspondência de padrões — repetido até que o payload pare de mudar, de modo que empilhar duas técnicas não consegue contorná-lo
- **Detecção de CVE** - Shellshock (CVE-2014-6271), Spring4Shell (CVE-2022-22965), PHPUnit RCE (CVE-2017-9841), Drupalgeddon, Log4Shell
- **Detecção Sensível ao Contexto** - Padrões encontrados em strings de consulta pontuam mais alto do que aqueles no corpo da requisição
- **Varredura do Corpo da Requisição** - Tanto corpos de requisição codificados em formulário quanto JSON (`application/json`) são inspecionados
- **Campos Seguros** - Exclui campos de formulário específicos da varredura (para editores de CMS, entradas de código, campos de busca)
- **Relatório de Falsos Positivos** - Marque ameaças como falsos positivos no painel; cria automaticamente regras de exclusão
- **Três Modos de Detecção** - `strict`, `balanced` (padrão) e `relaxed` - sensibilidade ajustável
- **Supressão de Caminhos de Conteúdo** - Coloque caminhos de CMS/blog na lista de permissões para suprimir alertas de baixa/média severidade provenientes de conteúdo rico
- **Detecção de PII** - Padrões de exposição de dados sensíveis (configurável por região)
- **Enriquecimento Geográfico** - Identificação de país, cidade, ISP, provedor de nuvem via API gratuita
- **Alertas no Slack** - Notificações em tempo real para ameaças de alta severidade (funciona no Laravel 10 e 11+)
- **Painel Integrado** - Painel Blade em modo escuro (Alpine.js e Tailwind, estilos pré-compilados, sem etapa de build)
- **Proteção de Autenticação do Painel** - Autenticação configurável para o painel e API (nenhuma, auth, role ou baseada em IP)
- **15 Endpoints de API** - API REST completa para construir painéis personalizados em Vue/React/mobile
- **Exportação para Fail2ban** - Exporta IPs detectados em formato compatível com fail2ban ou blocklist simples
- **Exportação de Blocklist** - Exporta IPs em formato nginx deny, Apache deny, CSV ou simples
- **Exportação CSV** - Exportação do log de ameaças com um clique (até 10.000 linhas)
- **Análise de Correlação** - Detecta ataques coordenados e campanhas de ataque entre IPs
- **Desempenho Otimizado** - Carregamento preguiçoso de padrões baseado em categoria (executa regex apenas para categorias de ataque relevantes), saída antecipada para requisições limpas, curto-circuito de UA de navegador (pula mais de 70 verificações para navegadores normais), busca por hash de caminho de sondagem, inserções em lote no BD, máximo de detecções configurável por requisição
- **Agnóstico de Banco de Dados** - MySQL, PostgreSQL, SQLite, SQL Server
- **Zero Configuração** - Funciona imediatamente com padrões sensatos
- **Seguro por Design** - O middleware captura seus próprios erros. Se a detecção falhar, sua aplicação continua funcionando. Requisições nunca são bloqueadas.
---
## Configuração
O pacote funciona sem nenhuma alteração no `.env`. Todos os valores abaixo são opcionais - adicione-os apenas se quiser sobrescrever os padrões.
```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 Detecção
| Modo | Limite de Confiança | Comportamento |
|------|---------------------|----------|
| `strict` | 0 (registra tudo) | Todos os padrões ativos, limites mais baixos. Captura tudo, mas pode sinalizar tráfego legítimo. |
| `balanced` | 10 | Padrão. Pontuação de confiança ativa, limites padrão. Bom para a maioria das aplicações. |
| `relaxed` | 25 | Apenas padrões de alta severidade são executados. Melhor para sites com muito conteúdo e falsos positivos frequentes. (Era 40 antes da v1.8.0 — um piso que nenhuma detecção individual conseguia atingir, então o modo silenciosamente não registrava nada.) |
### Ambientes Habilitados
Por padrão, a detecção é executada em `production`, `staging` e `local`. Para alterar, publique a configuração e edite:
```php
'enabled_environments' => ['production', 'staging', 'local'],
```
Para desativar a deteção na sua suite de testes, defina `APP_ENV=testing` (não está na lista acima) ou adicione ao seu `phpunit.xml`:
```xml
<env name="THREAT_DETECTION_ENABLED" value="false"/>
```
### Referência de Configuração
Publique o arquivo de configuração para ver todas as opções disponíveis:
```bash
php artisan vendor:publish --tag=threat-detection-config
```
---
[Read more](https://github.com/jay123anta/laravel-threat-detection)