
Middleware Laravel passivo che rileva e registra SQL injection, XSS, RCE, scanner bot e oltre 175 pattern di attacco. Include una dashboard integrata, avvisi Slack, API REST e arricchimento geografico. IDS, non 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
**Monitoraggio della sicurezza e registrazione degli attacchi per Laravel. Rileva e registra SQL injection,
XSS, RCE, directory traversal, bot scanner e sonde di ricognizione in stile `/wp-admin` —
ogni richiesta ostile viene registrata nel tuo database con il contesto completo dell'applicazione.
È un IDS, non un WAF: non blocca, filtra o modifica mai una richiesta.**
<p align="center">
<img src="https://raw.githubusercontent.com/jay123anta/laravel-threat-detection/main/art/demo.gif" alt="Installa il pacchetto, invia tre attacchi — SQL injection, directory traversal, XSS — ognuno restituisce HTTP 200 perché nulla viene bloccato, e tutti e tre sono già conteggiati in threat-detection:stats" width="100%">
</p>
### Sei qui perché hai visto qualcosa del genere?
```
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
```
Quelle richieste stanno già raggiungendo la tua app Laravel. Il tuo access log mostra l'URL
e il codice di stato, e nient'altro — non il payload decodificato, non quale delle tue
route è stata presa di mira, non se lo stesso IP ha provato quaranta altre cose in questa ora.
Questo pacchetto risponde a queste domande. Inseriscilo in qualsiasi app Laravel 10–13 e inizia
a scansionare ogni richiesta HTTP contro oltre 150 pattern di attacco, assegnando un punteggio a ogni corrispondenza in base
alla confidenza e scrivendolo nel tuo database — con una dashboard integrata, avvisi Slack,
geo-arricchimento ed esportazioni fail2ban/blocklist. Nessuna richiesta viene mai bloccata. Pensa a
una telecamera di sicurezza, non a una serratura: ti mostra esattamente chi sta sondando le tue route, quanto
spesso e con quali tecniche.
> Estratto da un'app di produzione e collaudato su traffico reale. Oltre 2.400 test, nessuna dipendenza
> runtime oltre a Laravel stesso, e nessuna connessione internet richiesta per il rilevamento.
>
> Stai aggiornando? Vedi [UPGRADING.md](https://github.com/jay123anta/laravel-threat-detection/blob/main/UPGRADING.md). Vuoi contribuire? Vedi [CONTRIBUTING.md](https://github.com/jay123anta/laravel-threat-detection/blob/main/CONTRIBUTING.md).
## Inizia in meno di un minuto
```bash
composer require jayanta/laravel-threat-detection
php artisan vendor:publish --tag=threat-detection-migrations
php artisan migrate
```
Poi aggiungi il middleware al tuo gruppo `web` (una riga in `bootstrap/app.php` su Laravel 11+,
o `app/Http/Kernel.php` su Laravel 10) — lo snippet completo è in [Quick Start](#quick-start) qui sotto.
Tutto qui; il rilevamento è attivo.
```bash
php artisan threat-detection:doctor # confirms it is actually recording
```
---
## Dove si colloca: IDS vs WAF vs edge
Questo pacchetto è un **IDS passivo a livello applicativo** — osserva e registra, non
blocca. È pensato per affiancare un WAF o un servizio edge, non per sostituirli. Ogni livello vede
qualcosa che gli altri non possono vedere:
| | **Questo pacchetto** (app IDS) | **WAF** (ModSecurity + OWASP CRS, Cloudflare WAF) | **Edge / CDN** (Cloudflare) |
|---|:---:|:---:|:---:|
| Blocca richieste malevole | ❌ solo log | ✅ | ✅ |
| Contesto completo dell'app (URL esatto, payload decodificato, utente autenticato) | ✅ | ⚠️ parziale | ❌ |
| Dashboard integrata + log delle minacce nel tuo DB | ✅ | ⚠️ variabile | ⚠️ solo edge |
| Rilevamenti specifici dell'app (es. PII Aadhaar / PAN / IFSC) | ✅ integrato + personalizzato | ⚠️ scrivi le tue regole | ⚠️ regole personalizzate, dipende dal piano |
| Funziona offline / nessun servizio esterno | ✅ | ⚠️ dipende | ❌ |
| Ferma il traffico prima che raggiunga il tuo server | ❌ | ⚠️ solo WAF cloud | ✅ |
| Configurazione | `composer require`, migrate, una riga di middleware | media–alta | bassa–media |
| Costo | gratuito, MIT | variabile | piano gratuito + a pagamento |
**In breve:** un edge/WAF è la serratura sulla porta; questo è la telecamera di
sicurezza *all'interno*, con il contesto dell'app per dirti esattamente cosa viene tentato su quale route, da
chi, e con quale frequenza. Usalo per alimentare decisioni reali — ban fail2ban, rate limit,
geo-blocking — con dati che il tuo livello edge non vede mai.
### Cosa deliberatamente NON è
- **Non è un WAF.** Non blocca, filtra o modifica mai una richiesta. Usa Cloudflare,
mod_security, o un vero WAF per l'enforcement. (Nessun livello edge a cui delegare? Gli
[helper lato operatore](#acting-on-the-data-operator-side-blocking) espongono le
decisioni del pacchetto così puoi scrivere il tuo middleware di blocco in cinque righe —
il codice di enforcement resta tuo, non del pacchetto.)
- **Non è un sostituto della programmazione sicura.** Query parametrizzate, validazione dell'input e
escaping dell'output sono le tue vere difese. Questo pacchetto presuppone che il tuo codice sia già
sicuro e ti offre *visibilità*, non protezione.
- **Non è un servizio edge.** Se puoi mettere Cloudflare davanti, fallo — poi aggiungi questo per il
dettaglio a livello applicativo che i servizi edge non possono vedere.
- **Non è un rilevatore completo, e non può esserlo.** Il pattern matching intercetta attacchi che
*sembrano* attacchi noti. Una tecnica nuova, o una familiare riscritta abbastanza, passerà
senza essere registrata — e non ti verrà detto che è successo. Il silenzio qui significa
"nulla ha corrisposto", mai "nulla è accaduto". Dove si guadagna il suo posto è nel
traffico ad alto volume e basso sforzo che costituisce la maggior parte di ciò che effettivamente colpisce un'app
Laravel pubblica: scanner, sonde di ricognizione, stringhe di injection pronte all'uso, credential
spray. Tratta un log silenzioso come assenza di prove, non come prova di assenza.
### Aspettati che segnali i tuoi stessi contenuti dal primo giorno
Un'installazione non ottimizzata scatta su contenuti legittimi, e dovresti saperlo prima
di installare piuttosto che dopo. Questi sono misurati, non ipotetici. Le righe
sotto sono un campione del livello minimo fissato da
[`LegitimateTrafficCorpusTest`](https://github.com/jay123anta/laravel-threat-detection/blob/main/tests/Feature/LegitimateTrafficCorpusTest.php);
ognuna elenca *tutto* ciò che quella richiesta registra, e
[`ReadmeNoiseFloorTest`](https://github.com/jay123anta/laravel-threat-detection/blob/main/tests/Feature/ReadmeNoiseFloorTest.php) fa fallire la
build se una qualsiasi riga smette di corrispondere a ciò che la suite misura per essa.
<!-- noise-floor:start -->
| Richiesta perfettamente legittima | Cosa registra un'installazione non ottimizzata |
|---|---|
| `how to write a UNION SELECT in postgres` digitato in un campo di ricerca <!-- case: sql tutorial in a search box --> | `SQL Injection UNION` / high |
| Un post di blog contenente `<script>window.dataLayer=[];</script>` <!-- case: javascript snippet in a blog post --> | `XSS Script Tag` / high · `Command Chain Injection` / medium |
| Un ticket di supporto con un errore `SELECT * FROM users WHERE id = 1` incollato <!-- case: a pasted sql error in a support ticket --> | `SQLi Variant` / high · `SQL SELECT Query` / low |
| Documentazione che spiega che `../../etc/passwd` è il classico payload di traversal <!-- case: a traversal explainer in documentation --> | `Directory Traversal` / medium · `Sensitive File Access` / medium |
| Un form di profilo che raccoglie un numero di cellulare indiano e un PAN autentici <!-- case: a profile form collecting genuine indian pii --> | `PAN Number Detected` / high · `Bank Account Number Detected` / high · `Mobile Number Detected` / low |
<!-- noise-floor:end -->
**Nessuno di questi è un bug.** Un post di blog contenente `<script>` è, byte per byte, un
payload di stored-XSS; una ricerca di `UNION SELECT` è indistinguibile da un tentativo
di injection; un numero di cellulare di dieci cifre è anche un plausibile numero di conto bancario. Nulla
tranne il contesto applicativo li separa, e nessun motore di pattern può fornirti quel
contesto.
Fornirlo è una modifica di configurazione di una riga: indica il campo che legittimamente contiene
tale contenuto in `safe_fields` (o `safe_paths`, per un percorso all'interno di JSON annidato) e
non viene più scansionato. Questo è l'interruttore che silenzia le righe sopra — ed è
un vero compromesso, dato che anche un attacco veicolato attraverso quel campo passa inosservato.
`content_paths` e la modalità `relaxed` sono strumenti diversi. Eliminano il rumore di
severità bassa e media, e **continuano deliberatamente a registrare le corrispondenze di severità alta** —
quindi non silenzieranno le righe high in questa tabella, per design. Vedi
[Riduzione dei falsi positivi](#reducing-false-positives) per capire a quale ricorrere e quando.
**Se la tua app accetta rich text, esempi di codice o query di ricerca, fallo prima di
giudicare l'output.** Il default è deliberatamente rumoroso-ma-onesto piuttosto che
silenzioso-e-incompleto: è più facile silenziare una corrispondenza nota che scoprirne una che
non è mai scattata.
### Quindi cosa ci fai effettivamente?
La domanda più comune su un rilevatore che non blocca mai. Quattro risposte, in
ordine crescente di sforzo:
| Vuoi | Usa | Sforzo |
|---|---|---|
| Vedere cosa ti sta colpendo | La [dashboard](#dashboard) o `threat-detection:stats` | nessuno, è già in esecuzione |
| Bandire i recidivi a livello di firewall | [`threat-detection:export-fail2ban`](#artisan-commands) — pipe verso un cron | una riga |
| Negare a livello di web server | [`threat-detection:export-blocklist`](#artisan-commands) → direttive nginx/apache | una riga |
| Rifiutare le richieste in-app | [Helper lato operatore](#acting-on-the-data-operator-side-blocking) — `isBlocklisted()`, `isDdosThresholdExceeded()` | ~10 righe del tuo middleware |
| Reagire in tempo reale | L'[evento `ThreatDetected`](#threatdetected-event) — Telegram, SIEM, PagerDuty | un listener |
Il pacchetto fornisce l'intelligence; tu fornisci il rifiuto. Questa separazione è
deliberata — il codice di enforcement che vive nella tua app è codice che puoi leggere,
testare e disattivare, e significa che un bug nel rilevamento non può mai mandare giù il tuo sito.
### Come si confronta con altri pacchetti di sicurezza Laravel
Questi risolvono problemi diversi e si compongono bene — la tabella riguarda la scelta dello
strumento giusto, non la vittoria.
| Pacchetto | Cosa fa | Blocca? | Usalo quando |
|---|---|:---:|---|
| **questo pacchetto** | Scansiona ogni richiesta contro oltre 150 pattern, registra con il contesto completo dell'app | ❌ | Vuoi *vedere* cosa viene tentato sulla tua app |
| `spatie/laravel-honeypot` | Campo form nascosto che intercetta bot di spam | ✅ solo form | Hai form pubblici che ricevono spam |
| `graham-campbell/security` | Rimuove markup simil-XSS dall'input | ✅ modifica | Vuoi una sanificazione dell'input ingenua |
| `spatie/laravel-csp` | Invia header Content-Security-Policy | ✅ browser | Vuoi limitare ciò che il browser carica |
| `laravel/fortify` + rate limit | Throttling e lockout dell'autenticazione | ✅ | Ti serve protezione brute-force sul login |
| Cloudflare / mod_security | WAF edge, blocca prima della tua app | ✅ | Vuoi fermare il traffico prima che arrivi |
Il riassunto onesto: un honeypot intercetta lo spam dei form, un WAF blocca il traffico noto-malevolo
all'edge, e la CSP limita il browser. **Nessuno di essi ti dice cosa un
attaccante ha tentato contro le tue route specifiche, con il payload decodificato e l'utente
autenticato allegato.** Quel vuoto è ciò che questo riempie — ed è per questo che il
pacchetto deliberatamente non blocca: puoi eseguirlo insieme a tutti i suddetti
senza che nessuno di essi si combatta a vicenda.
---
## Requisiti
- PHP 8.2+ (Laravel 13 richiede PHP 8.3+)
- Laravel 10.x, 11.x, 12.x, o 13.x
- Qualsiasi database supportato da Laravel (MySQL, PostgreSQL, SQLite, SQL Server)
- Qualsiasi driver di cache - **nessun Redis o queue worker richiesto**. Redis/Memcached è
solo *consigliato* per abilitare il controllo DDoS opzionale (che si disabilita automaticamente su
driver non atomici). Le scritture in coda sono opt-in e disattivate di default.
---
## Come funziona
1. Un middleware scansiona ogni richiesta HTTP in ingresso
2. La richiesta viene verificata contro 158 pattern regex che coprono SQL injection, XSS, RCE, file traversal, SSRF, LDAP, XPath, SSTI e altro
3. Se un pattern di minaccia corrisponde, un record viene scritto nella tua tabella di database `threat_logs` con IP, URL, tipo di minaccia, livello di severità e un punteggio di confidenza
4. Opzionalmente, viene inviato un avviso Slack per le minacce di severità alta
5. La richiesta procede normalmente - **nulla viene bloccato**
Nessuna connessione internet è necessaria per il rilevamento.
---
## Avvio rapido
### 1. Installa il pacchetto
```bash
composer require jayanta/laravel-threat-detection
```
### 2. Pubblicare le migrazioni ed eseguirle
> **Questo passaggio è obbligatorio.** Senza di esso, il pacchetto rileverà le minacce ma non potrà memorizzarle nel database. Se salti questo passaggio, la tua tabella `threat_logs` non esisterà e tutte le rilevazioni andranno perse silenziosamente (vedrai solo errori in `storage/logs/laravel.log`).
```bash
php artisan vendor:publish --tag=threat-detection-migrations
php artisan migrate
```
Questo crea due tabelle: `threat_logs` (memorizza le minacce rilevate) e `threat_exclusion_rules` (memorizza le regole per i falsi positivi).
**Verifica che le tabelle siano state create:**
```bash
php artisan migrate:status
```
Cerca `create_threat_logs_table`, `add_confidence_to_threat_logs_table` e `create_threat_exclusion_rules_table` - tutti dovrebbero mostrare `Ran`.
### 3. Registra il middleware
Il middleware è ciò che analizza le richieste. Devi aggiungerlo al tuo gruppo di middleware `web`.
**Se usi Laravel 11 o 12** - apri `bootstrap/app.php`:
```php
->withMiddleware(function (Middleware $middleware) {
$middleware->web(append: [
\JayAnta\ThreatDetection\Http\Middleware\ThreatDetectionMiddleware::class,
]);
})
```
> **Come verificare la tua versione di Laravel:** Esegui `php artisan --version` nel tuo terminale.
**Se usi Laravel 10** - apri `app/Http/Kernel.php`:
```php
protected $middlewareGroups = [
'web' => [
// ... existing middleware
\JayAnta\ThreatDetection\Http\Middleware\ThreatDetectionMiddleware::class,
],
];
```
### 4. (Opzionale) Pubblicare il file di configurazione
```bash
php artisan vendor:publish --tag=threat-detection-config
```
Il pacchetto funziona con impostazioni predefinite sensate. Pubblicando la configurazione puoi personalizzare i pattern di rilevamento, le modalità di sensibilità, le notifiche Slack e altro ancora. Se salti questo passaggio, tutto continua a funzionare.
**Fatto.** La tua app ora rileva le minacce.
---
## Verifica che funzioni
Dopo l'installazione, attiva una minaccia di test e conferma che sia stata registrata.
### Passaggio 1: Avvia la tua app
```bash
php artisan serve
```
### Passaggio 2: Apri un URL di test nel tuo browser
Aggiungi un parametro di query malevolo a **qualsiasi route esistente** nella tua app (la tua homepage, una pagina prodotto, ecc.). Ad esempio:
**SQL Injection:**
```
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 (Remote Code Execution):**
```
http://localhost:8000/?cmd=system('ls -la')
```
**Shellshock (CVE-2014-6271):**
```
http://localhost:8000/?cmd=() { :;}; /bin/bash
```
**Iniezione di comandi Windows:**
```
http://localhost:8000/?cmd=powershell -c whoami
```
**DROP TABLE (SQL DDL):**
```
http://localhost:8000/?q=DROP TABLE users
```
> Usa una route che esiste effettivamente nella tua app (come `/`). Se l'URL restituisce un 404, il middleware potrebbe non essere stato eseguito.
### Passaggio 3: Verifica che le minacce siano state registrate
**Opzione A - Comando Artisan (il più rapido):**
```bash
php artisan threat-detection:stats
```
Dovresti vedere una tabella con `Recorded Detections`, i conteggi di gravità e gli IP
principali. Quel numero conta le *righe*, non i tentativi: una detection viene scritta una volta per
IP per tipo di minaccia ogni cinque minuti, e le ripetizioni all'interno di quella finestra vengono
deduplicate anziché conteggiate di nuovo.
**Opzione B - Tinker:**
```bash
php artisan tinker
```
```php
DB::table('threat_logs')->latest()->take(5)->get(['ip_address', 'type', 'threat_level', 'confidence_score']);
```
**Opzione C - File di log di Laravel:**
Ogni minaccia rilevata viene scritta come avviso in `storage/logs/laravel.log`:
```
[high] Threat Detected: [middleware] SQL Injection UNION from 127.0.0.1 (http://localhost:8000/?q=...) [confidence: 50%]
```
### Cose da sapere durante i test
| Comportamento | Spiegazione |
|----------|-------------|
| La stessa minaccia viene registrata una sola volta ogni 5 minuti | Deduplicazione: lo stesso IP + lo stesso tipo di minaccia viene memorizzato nella cache per 5 minuti. Usa **tipi di attacco diversi** per ogni test, oppure attendi tra un test e l'altro. |
| Le richieste `curl` attivano un rilevamento aggiuntivo | L'uso di `curl` registra anche un rilevamento dello user-agent "cURL Command" (gravità bassa). Questo è previsto - il pacchetto rileva gli strumenti automatizzati. |
| Il pacchetto non blocca mai le richieste | La tua app continua a funzionare normalmente. Il rilevamento è passivo. |
| Nessuna configurazione di Slack necessaria | Le notifiche sono disattivate per impostazione predefinita. |
| Nessuna connessione a Internet necessaria | Il rilevamento principale è 100% locale. Solo il comando opzionale `threat-detection:enrich` chiama un'API esterna per i geo-dati. |
### Risoluzione dei problemi
**Inizia da qui — un solo comando risponde alla maggior parte di questi:**
```bash
php artisan threat-detection:doctor
```
Controlla le cose che fanno fallire il rilevamento *silenziosamente* — dove la dashboard
rimane vuota, il che sembra identico a "nessun attacco" — e stampa la correzione esatta
per ciascuna. Esce con codice diverso da zero in caso di un vero fallimento, quindi è sicuro da eseguire in CI o in
una fase di 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.
```
Cosa copre: rilevamento abilitato per questo ambiente; ogni colonna di cui lo
scrittore ha bisogno (una mancante scarta **ogni** minaccia); colonne dashboard/API; la
tabella delle regole di esclusione; se il middleware è effettivamente collegato a una route o
a un gruppo; configurazione pubblicata precedente a questa versione; pattern personalizzati che oscurano
quelli integrati; un driver di cache che non può eseguire il conteggio DDoS; e una dashboard o
API lasciata aperta senza autenticazione.
**"Ho testato ma `threat-detection:stats` mostra zero minacce" / "Le minacce non vengono memorizzate nel database"**
Se il doctor è passato, l'installazione è a posto e il problema è la richiesta di test
stessa. Tre cose che non può verificare per te:
| Verifica | Come controllare |
|-------|---------------|
| L'IP non è in whitelist | Se hai aggiunto `THREAT_DETECTION_WHITELISTED_IPS` a `.env`, rimuovilo durante il test |
| Hai usato una route esistente | L'URL di test deve corrispondere a una route reale (es. `/`). Un 404 significa che il middleware non è mai stato eseguito |
| Cache di deduplicazione | Stesso IP + stesso tipo di attacco è in cache per 5 minuti - prova un tipo di attacco diverso |
> Eseguire solo `php artisan migrate` non è mai sufficiente: i file di migrazione risiedono
> all'interno del pacchetto e devono prima essere pubblicati in `database/migrations/`
> della tua app. Il doctor stampa il comando esatto quando questo è il problema.
**"L'API restituisce 401 Unauthorized"**
Vedi [Autenticazione API](#api-authentication) di seguito.
**"La dashboard mostra 404"**
La dashboard è disabilitata per impostazione predefinita. Aggiungi `THREAT_DETECTION_DASHBOARD=true` a `.env` e svuota la cache delle route:
```bash
php artisan route:clear
```
---
## Funzionalità
- **Oltre 150 pattern di rilevamento** - SQL injection (UNION, DDL, DML, operazioni su file), XSS (script, SVG, espressione CSS), RCE, directory traversal, SSRF, XXE, Log4Shell, NoSQL injection, command injection (Linux + Windows), LDAP injection, XPath injection, SSTI, CRLF injection, deserializzazione Java e altro ancora
- **83 firme di bot/scanner** - SQLMap, Nikto, Nmap, Burp Suite, FeroxBuster, FFUF, XSStrike, Dalfox, Netsparker e oltre 70 altre firme di scanner e bot
- **Rilevamento scraper AI** - GPTBot, ClaudeBot, ByteSpider, Common Crawl e altri bot di addestramento AI
- **Rilevamento browser headless** - HeadlessChrome, PhantomJS, Selenium, Puppeteer, Playwright
- **Tracciamento sonde 404** - Rileva sonde di ricognizione che colpiscono percorsi vulnerabili noti (`/wp-admin`, `/.env`, `/phpmyadmin`, `/actuator`, ecc.) con oltre 50 percorsi di sonda predefiniti, più un [pacchetto per infrastrutture AI](#ai-infrastructure-probes-opt-in) opzionale per gateway LLM esposti
- **Monitoraggio DDoS** - Rilevamento basato su soglia di frequenza con finestre configurabili
- **Punteggio di confidenza** - Ogni minaccia riceve un punteggio di confidenza da 0 a 100 basato su numero di pattern, contesto e segnali
- **Resistenza all'evasione** - La pipeline di normalizzazione sconfigge l'inserimento di commenti SQL, la doppia codifica URL, la codifica di entità HTML, gli escape Unicode, gli escape esadecimali e la codifica IIS `%uXXXX` prima del pattern matching — ripetuta finché il payload smette di cambiare, così impilare due tecniche non riesce a superarla
- **Rilevamento CVE** - Shellshock (CVE-2014-6271), Spring4Shell (CVE-2022-22965), PHPUnit RCE (CVE-2017-9841), Drupalgeddon, Log4Shell
- **Rilevamento context-aware** - I pattern trovati nelle query string ottengono un punteggio più alto rispetto a quelli nel corpo della richiesta
- **Scansione del corpo della richiesta** - Vengono ispezionati sia i corpi delle richieste form-encoded che JSON (`application/json`)
- **Campi sicuri** - Escludi campi modulo specifici dalla scansione (per editor CMS, input di codice, campi di ricerca)
- **Segnalazione falsi positivi** - Contrassegna le minacce come falsi positivi dalla dashboard; crea automaticamente regole di esclusione
- **Tre modalità di rilevamento** - `strict`, `balanced` (predefinita) e `relaxed` - sensibilità regolabile
- **Soppressione percorsi di contenuto** - Inserisci in whitelist percorsi CMS/blog per sopprimere avvisi di livello basso/medio da contenuti ricchi
- **Rilevamento PII** - Pattern di esposizione di dati sensibili (configurabili per regione)
- **Geo-arricchimento** - Identificazione di paese, città, ISP, provider cloud tramite API gratuita
- **Avvisi Slack** - Notifiche in tempo reale per minacce ad alta severità (funziona su Laravel 10 e 11+)
- **Dashboard integrata** - Dashboard Blade in modalità scura (Alpine.js e Tailwind, stili precompilati, zero build step)
- **Protezione autenticazione dashboard** - Autenticazione configurabile per dashboard e API (nessuna, auth, ruolo o basata su IP)
- **15 endpoint API** - API REST completa per costruire dashboard personalizzate Vue/React/mobile
- **Esportazione Fail2ban** - Esporta gli IP rilevati in formato compatibile con fail2ban o come blocklist semplice
- **Esportazione blocklist** - Esporta gli IP in formato nginx deny, Apache deny, CSV o semplice
- **Esportazione CSV** - Esportazione del registro minacce con un clic (fino a 10.000 righe)
- **Analisi di correlazione** - Rileva attacchi coordinati e campagne di attacco tra IP
- **Prestazioni ottimizzate** - Caricamento lazy dei pattern basato su categorie (esegue le regex solo per le categorie di attacco rilevanti), uscita anticipata per richieste pulite, short-circuit per UA browser (salta oltre 70 controlli per browser normali), ricerca hash dei percorsi di sonda, inserimenti DB in batch, numero massimo di rilevamenti per richiesta configurabile
- **Indipendente dal database** - MySQL, PostgreSQL, SQLite, SQL Server
- **Zero configurazione** - Funziona subito con impostazioni predefinite sensate
- **Sicuro per progettazione** - Il middleware intercetta i propri errori. Se il rilevamento fallisce, la tua app continua a funzionare. Le richieste non vengono mai bloccate.
---
## Configurazione
Il pacchetto funziona senza alcuna modifica al file `.env`. Tutti i valori seguenti sono opzionali - aggiungili solo se vuoi sovrascrivere le impostazioni predefinite.
```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
```
### Modalità di Rilevamento
| Modalità | Soglia di Confidenza | Comportamento |
|------|---------------------|----------|
| `strict` | 0 (registra tutto) | Tutti i pattern attivi, soglie minime. Cattura tutto ma può segnalare traffico legittimo. |
| `balanced` | 10 | Predefinita. Punteggio di confidenza attivo, soglie standard. Adatta alla maggior parte delle app. |
| `relaxed` | 25 | Vengono eseguiti solo i pattern ad alta severità. Ideale per siti ricchi di contenuti con frequenti falsi positivi. (Era 40 prima della v1.8.0 — un limite che nessun singolo rilevamento poteva raggiungere, quindi la modalità non registrava nulla silenziosamente.) |
### Ambienti Abilitati
Per impostazione predefinita, il rilevamento viene eseguito in `production`, `staging` e `local`. Per modificare, pubblica la configurazione e modifica:
```php
'enabled_environments' => ['production', 'staging', 'local'],
```
Per disabilitare il rilevamento nella tua suite di test, imposta `APP_ENV=testing` (non presente nell'elenco sopra) oppure aggiungi al tuo `phpunit.xml`:
```xml
<env name="THREAT_DETECTION_ENABLED" value="false"/>
```
### Riferimento alla configurazione
Pubblica il file di configurazione per vedere tutte le opzioni disponibili:
```bash
php artisan vendor:publish --tag=threat-detection-config
```
---
[Read more](https://github.com/jay123anta/laravel-threat-detection)