PHPackages                             jayanta/laravel-threat-detection - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Logging &amp; Monitoring](/categories/logging)
4. /
5. jayanta/laravel-threat-detection

ActiveLibrary[Logging &amp; Monitoring](/categories/logging)

jayanta/laravel-threat-detection
================================

Real-time threat detection and security logging for Laravel applications. Detects SQL injection, XSS, DDoS, scanner bots, and more.

v1.2.0(2mo ago)2392↓50%1MITPHPPHP ^8.1CI passing

Since Mar 7Pushed 1mo ago1 watchersCompare

[ Source](https://github.com/jay123anta/laravel-threat-detection)[ Packagist](https://packagist.org/packages/jayanta/laravel-threat-detection)[ Docs](https://github.com/jay123anta/laravel-threat-detection)[ RSS](/packages/jayanta-laravel-threat-detection/feed)WikiDiscussions main Synced 1mo ago

READMEChangelogDependencies (16)Versions (4)Used By (0)

 [![Latest Version](https://camo.githubusercontent.com/a3f4fa9ae8f04a7a94664984fbddeffab771e871b5f310e17b214099ef7d7eb4/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6a6179616e74612f6c61726176656c2d7468726561742d646574656374696f6e2e7376673f7374796c653d666c61742d737175617265)](https://camo.githubusercontent.com/a3f4fa9ae8f04a7a94664984fbddeffab771e871b5f310e17b214099ef7d7eb4/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6a6179616e74612f6c61726176656c2d7468726561742d646574656374696f6e2e7376673f7374796c653d666c61742d737175617265) [![Tests](https://camo.githubusercontent.com/3d5ef888b458aeee72858378e031332ed8657368b48de4603e18233872200f37/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f6a6179313233616e74612f6c61726176656c2d7468726561742d646574656374696f6e2f74657374732e796d6c3f6272616e63683d6d61696e267374796c653d666c61742d737175617265266c6162656c3d7465737473)](https://camo.githubusercontent.com/3d5ef888b458aeee72858378e031332ed8657368b48de4603e18233872200f37/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f6a6179313233616e74612f6c61726176656c2d7468726561742d646574656374696f6e2f74657374732e796d6c3f6272616e63683d6d61696e267374796c653d666c61742d737175617265266c6162656c3d7465737473) [![Total Downloads](https://camo.githubusercontent.com/5cacb682c443d1f6762982e8bfcf14b17a274a126d495359a092843266ea1a8b/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f6a6179616e74612f6c61726176656c2d7468726561742d646574656374696f6e2e7376673f7374796c653d666c61742d737175617265)](https://camo.githubusercontent.com/5cacb682c443d1f6762982e8bfcf14b17a274a126d495359a092843266ea1a8b/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f6a6179616e74612f6c61726176656c2d7468726561742d646574656374696f6e2e7376673f7374796c653d666c61742d737175617265) [![License](https://camo.githubusercontent.com/ae027fe6fafbb1e713b01f414041b7aa9d3864fda2ae19ced65503240d613f09/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f6a6179616e74612f6c61726176656c2d7468726561742d646574656374696f6e2e7376673f7374796c653d666c61742d737175617265)](https://camo.githubusercontent.com/ae027fe6fafbb1e713b01f414041b7aa9d3864fda2ae19ced65503240d613f09/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f6a6179616e74612f6c61726176656c2d7468726561742d646574656374696f6e2e7376673f7374796c653d666c61742d737175617265) [![PHP Version](https://camo.githubusercontent.com/7f4a6050637f6681e47b2e3a75a9a206fa15ac31ce3abf5850de66b2abce6387/68747470733a2f2f696d672e736869656c64732e696f2f7068702d76657273696f6e2d737570706f72742f6a6179616e74612f6c61726176656c2d7468726561742d646574656374696f6e3f7374796c653d666c61742d737175617265)](https://camo.githubusercontent.com/7f4a6050637f6681e47b2e3a75a9a206fa15ac31ce3abf5850de66b2abce6387/68747470733a2f2f696d672e736869656c64732e696f2f7068702d76657273696f6e2d737570706f72742f6a6179616e74612f6c61726176656c2d7468726561742d646574656374696f6e3f7374796c653d666c61742d737175617265)

Laravel Threat Detection
========================

[](#laravel-threat-detection)

**Know who's attacking your Laravel app — without changing a single line of application code.**

A middleware-based threat detection and logging system for Laravel. Drop it in, and it starts scanning every HTTP request for SQL injection, XSS, RCE, scanner bots, DDoS patterns, and 40+ other attack types — logging everything to your database with full geo-enrichment and a built-in dashboard.

> Extracted from a production application. Battle-tested with real traffic.

**Important:** This package **never blocks** any request. It only **logs** and **alerts**. Your application continues to handle every request normally, even when threats are detected.

---

Requirements
------------

[](#requirements)

- PHP 8.1+
- Laravel 10.x, 11.x, or 12.x
- Any database supported by Laravel (MySQL, PostgreSQL, SQLite, SQL Server)

---

How It Works
------------

[](#how-it-works)

1. A middleware scans every incoming HTTP request
2. The request is checked against 130+ regex patterns covering SQL injection, XSS, RCE, file traversal, SSRF, and more
3. If a threat pattern matches, a record is written to your `threat_logs` database table with the IP, URL, threat type, severity level, and a confidence score
4. Optionally, a Slack alert is sent for high-severity threats
5. The request proceeds normally — **nothing is blocked**

No internet connection is needed for detection.

---

Quick Start
-----------

[](#quick-start)

### 1. Install the package

[](#1-install-the-package)

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

### 2. Publish migrations and run them

[](#2-publish-migrations-and-run-them)

> **This step is required.** Without it, the package will detect threats but cannot store them in the database. If you skip this step, your `threat_logs` table won't exist and all detections will be silently lost (you'll only see errors in `storage/logs/laravel.log`).

```
php artisan vendor:publish --tag=threat-detection-migrations
php artisan migrate
```

This creates two tables: `threat_logs` (stores detected threats) and `threat_exclusion_rules` (stores false positive rules).

**Verify tables were created:**

```
php artisan migrate:status
```

Look for `create_threat_logs_table`, `add_confidence_to_threat_logs_table`, and `create_threat_exclusion_rules_table` — all should show `Ran`.

### 3. Register the middleware

[](#3-register-the-middleware)

The middleware is what scans requests. You need to add it to your `web` middleware group.

**If you use Laravel 11 or 12** — open `bootstrap/app.php`:

```
->withMiddleware(function (Middleware $middleware) {
    $middleware->web(append: [
        \JayAnta\ThreatDetection\Http\Middleware\ThreatDetectionMiddleware::class,
    ]);
})
```

> **How to check your Laravel version:** Run `php artisan --version` in your terminal.

**If you use Laravel 10** — open `app/Http/Kernel.php`:

```
protected $middlewareGroups = [
    'web' => [
        // ... existing middleware
        \JayAnta\ThreatDetection\Http\Middleware\ThreatDetectionMiddleware::class,
    ],
];
```

### 4. (Optional) Publish the config file

[](#4-optional-publish-the-config-file)

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

The package works with sensible defaults. Publishing the config lets you customize detection patterns, sensitivity modes, Slack notifications, and more. If you skip this step, everything still works.

**That's it.** Your app is now detecting threats.

---

Verify It Works
---------------

[](#verify-it-works)

After installation, trigger a test threat and confirm it was logged.

### Step 1: Start your app

[](#step-1-start-your-app)

```
php artisan serve
```

### Step 2: Open a test URL in your browser

[](#step-2-open-a-test-url-in-your-browser)

Append a malicious query parameter to **any existing route** in your app (your homepage, a product page, etc.). For example:

**SQL Injection:**

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

```

**XSS (Cross-Site Scripting):**

```
http://localhost:8000/?q=alert(1)

```

**Directory Traversal:**

```
http://localhost:8000/?file=../../etc/passwd

```

**RCE (Remote Code Execution):**

```
http://localhost:8000/?cmd=system('ls -la')

```

> Use a route that actually exists in your app (like `/`). If the URL returns a 404, the middleware may not have run.

### Step 3: Check that threats were logged

[](#step-3-check-that-threats-were-logged)

**Option A — Artisan command (quickest):**

```
php artisan threat-detection:stats
```

You should see a table with `Total Threats`, severity counts, and top IPs.

**Option B — Tinker:**

```
php artisan tinker
```

```
DB::table('threat_logs')->latest()->take(5)->get(['ip_address', 'type', 'threat_level', 'confidence_score']);
```

**Option C — Laravel log file:**Each detected threat is written as a warning to `storage/logs/laravel.log`:

```
[high] Threat Detected: [middleware] SQL Injection UNION from 127.0.0.1 (http://localhost:8000/?q=...) [confidence: 50%]

```

### Things to know when testing

[](#things-to-know-when-testing)

BehaviorExplanationSame threat only logs once per 5 minutesDeduplication: same IP + same threat type is cached for 5 minutes. Use **different attack types** for each test, or wait between tests.`curl` requests trigger extra detectionUsing `curl` also logs a "cURL Command" user-agent detection (low severity). This is expected — the package detects automated tools.The package never blocks requestsYour app continues to function normally. Detection is passive.No Slack setup neededNotifications are off by default.No internet connection neededCore detection is 100% local. Only the optional `threat-detection:enrich` command calls an external API for geo-data.### Troubleshooting

[](#troubleshooting)

**"I tested but `threat-detection:stats` shows zero threats" / "Threats are not stored in the database"**

This is almost always because migrations were not published. The package detects threats but silently skips the DB write if the table doesn't exist (so your app keeps working). Check `storage/logs/laravel.log` for errors like `SQLSTATE: table threat_logs not found`.

CheckHow to verifyMigrations were **published**Run `php artisan migrate:status` — look for `create_threat_logs_table` and `create_threat_exclusion_rules_table`. If missing, you need to publish first (see below)Migrations were **run**Same command — status should show `Ran`, not `Pending`Middleware is registeredConfirm `ThreatDetectionMiddleware` is in your `web` middleware group (see [Step 3](#3-register-the-middleware) above)IP is not whitelistedIf you added `THREAT_DETECTION_WHITELISTED_IPS` to `.env`, remove it during testingEnvironment is enabledDefault enabled environments: `production`, `staging`, `local`. Check `APP_ENV` in `.env`Used an existing routeThe test URL must match a real route (e.g., `/`).Dedup cacheSame IP + same attack type is cached for 5 minutes — try a different attack type**"`threat-detection:stats` throws a database error" / "`threat_exclusion_rules` table not found"**

The tables don't exist yet. You need to **publish** the migrations first, then run them:

```
php artisan vendor:publish --tag=threat-detection-migrations
php artisan migrate
```

> **Note:** Running `php artisan migrate` alone is not enough — the migration files are inside the package and need to be published to your app's `database/migrations/` folder first.

**"API returns 401 Unauthorized"**

See [API Authentication](#api-authentication) below.

**"Dashboard shows 404"**

The dashboard is disabled by default. Add `THREAT_DETECTION_DASHBOARD=true` to `.env` and clear route cache:

```
php artisan route:clear
```

---

Features
--------

[](#features)

- **130+ Detection Patterns** — SQL injection, XSS, RCE, directory traversal, SSRF, XXE, Log4Shell, NoSQL injection, command injection, and more
- **Scanner Detection** — SQLMap, Nikto, Nmap, Burp Suite, Acunetix, WPScan, Nessus, Nuclei, Metasploit, and others
- **Bot Detection** — Suspicious user agents, automated scripts, headless browsers
- **DDoS Monitoring** — Rate-based threshold detection with configurable windows
- **Confidence Scoring** — Each threat gets a 0-100 confidence score based on pattern count, context, and signals
- **Evasion Resistance** — Payload normalization defeats SQL comment insertion (`UNION/**/SELECT`), double URL encoding (`%2527`), and CHAR encoding bypasses
- **Context-Aware Detection** — Patterns found in query strings score higher than those in POST body
- **False Positive Reporting** — Mark threats as false positives from the dashboard; auto-creates exclusion rules
- **Three Detection Modes** — `strict`, `balanced` (default), and `relaxed` — tunable sensitivity
- **Content Path Suppression** — Whitelist CMS/blog paths to suppress low/medium alerts from rich content
- **PII Detection** — Sensitive data exposure patterns (configurable per region)
- **Geo-Enrichment** — Country, city, ISP, cloud provider identification via free API
- **Slack Alerts** — Real-time notifications for high-severity threats (works on Laravel 10 and 11+)
- **Built-in Dashboard** — Dark-mode Blade dashboard (Alpine.js + Tailwind CDN, zero build step)
- **15 API Endpoints** — Full REST API for building custom Vue/React/mobile dashboards
- **CSV Export** — One-click threat log export (up to 10,000 rows)
- **Correlation Analysis** — Detect coordinated attacks and attack campaigns across IPs
- **Database Agnostic** — MySQL, PostgreSQL, SQLite, SQL Server
- **Zero Config** — Works out of the box with sensible defaults
- **Safe by Design** — The middleware catches its own errors. If detection fails, your app keeps running. Requests are never blocked.

---

Configuration
-------------

[](#configuration)

The package works without any `.env` changes. All values below are optional — add them only if you want to override the defaults.

```
# Enable/disable detection globally (default: true)
THREAT_DETECTION_ENABLED=true

# Detection sensitivity (default: balanced)
# Options: strict, balanced, relaxed
THREAT_DETECTION_MODE=balanced

# Custom table name (default: threat_logs)
# THREAT_DETECTION_TABLE=threat_logs

# Whitelist IPs to skip detection entirely (default: empty)
# Supports CIDR notation. Comma-separated.
# THREAT_DETECTION_WHITELISTED_IPS=10.0.0.0/8,192.168.1.0/24

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

### Detection Modes

[](#detection-modes)

ModeConfidence ThresholdBehavior`strict`0 (logs everything)All patterns active, lowest thresholds. Catches everything but may flag legitimate traffic.`balanced`10Default. Confidence scoring active, standard thresholds. Good for most apps.`relaxed`40Only high-severity patterns trigger. Best for content-heavy sites with frequent false positives.### Enabled Environments

[](#enabled-environments)

By default, detection runs in `production`, `staging`, and `local`. To change, publish the config and edit:

```
'enabled_environments' => ['production', 'staging', 'local'],
```

To disable detection in your test suite, set `APP_ENV=testing` (not in the list above) or add to your `phpunit.xml`:

```

```

### Config Reference

[](#config-reference)

Publish the config file to see all available options:

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

Key config sections: `skip_paths` (paths to skip), `only_paths` (whitelist mode), `auth_paths` (smart detection for login routes), `content_paths` (suppress non-high alerts), `context_weights` (scoring multipliers), `threat_levels` (severity keyword mapping), `api_route_filtering` (suppress low/medium on API routes), `queue` (async processing), `retention` (auto-purge).

### Route Whitelisting (`only_paths`)

[](#route-whitelisting-only_paths)

If your app has many routes but you only care about a few, use `only_paths` to scan **only** those routes. All other routes are automatically skipped — no middleware overhead at all.

```
// config/threat-detection.php
'only_paths' => [
    'admin/*',
    'api/*',
    'login',
    'register',
],
```

Leave empty (default) to scan all routes (subject to `skip_paths`). When both are configured, `only_paths` is checked first, then `skip_paths` applies within the matched set.

### Queue Support

[](#queue-support)

By default, threat logging happens synchronously in the request cycle. For high-traffic apps, you can offload DB writes and Slack notifications to a queue:

```
THREAT_DETECTION_QUEUE=true
THREAT_DETECTION_QUEUE_CONNECTION=redis
THREAT_DETECTION_QUEUE_NAME=threat-logs
```

This dispatches a `StoreThreatLog` job (3 retries, backoff 10s/30s). Detection still happens in real-time — only the write is deferred.

### Auto-Purge (Retention Policy)

[](#auto-purge-retention-policy)

Automatically delete old threat logs on a daily schedule:

```
THREAT_DETECTION_RETENTION=true
THREAT_DETECTION_RETENTION_DAYS=90
```

Requires Laravel's scheduler to be running (`php artisan schedule:run`). Runs daily at 02:00 via `threat-detection:purge`.

### ThreatDetected Event

[](#threatdetected-event)

Every confirmed threat dispatches a `ThreatDetected` event that you can listen to:

```
// app/Providers/EventServiceProvider.php
use JayAnta\ThreatDetection\Events\ThreatDetected;

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

The event carries `$threatLog` (full DB row array), `$ipAddress`, and `$threatLevel`. Use it to trigger custom actions — send Telegram alerts, update a blocklist, feed a SIEM, etc.

---

Slack Notifications
-------------------

[](#slack-notifications)

Slack alerts are disabled by default. To enable:

```
THREAT_DETECTION_NOTIFICATIONS=true
THREAT_DETECTION_SLACK_WEBHOOK=https://hooks.slack.com/services/YOUR/WEBHOOK/URL
THREAT_DETECTION_SLACK_CHANNEL=#threat-alerts
```

Only high-severity threats trigger notifications by default (configurable via `notify_levels` in the config).

**Laravel 10:** Uses the built-in `SlackMessage` notification class. No extra package needed.

**Laravel 11+:** The built-in Slack channel was removed. The package **automatically detects this and sends raw HTTP POST webhooks** to your Slack URL. No extra package needed. If you prefer the full notification channel, install:

```
composer require laravel/slack-notification-channel
```

---

Dashboard
---------

[](#dashboard)

The package ships with a built-in dark-mode dashboard (Alpine.js + Tailwind CDN — no build step required).

```
+-------------------------------------------------------------------------+
|  Threat Detection Dashboard                                              |
+-------------------------------------------------------------------------+
|  Total: 847  |  High: 23  |  Med: 156  |  Low: 668  |  IPs: 94         |
+-------------------------------------------------------------------------+
|  [Timeline Chart - 7 Day Stacked Bar]                                   |
+-------------------------------------------------------------------------+
|  Search: [___________]  Level: [All]                                    |
|  Time         IP             Type            Level  Confidence  Actions  |
|  Mar 2 14:02  185.220.101.4  SQL Injection   HIGH   80%         [FP]    |
|  Mar 2 13:58  45.33.32.156   XSS Script Tag  HIGH   65%         [FP]    |
|  Mar 2 13:45  192.168.1.10   Scanner: Nikto  MED    35%         [FP]    |
+-------------------------------------------------------------------------+
|  Top IPs              |  Threats by Country                              |
|  185.220.101.4  [23]  |  US  234                                        |
|  45.33.32.156   [18]  |  CN  156                                        |
|  103.152.220.1  [12]  |  RU  98                                         |
+-------------------------------------------------------------------------+

```

### Enable the dashboard

[](#enable-the-dashboard)

Add to `.env`:

```
THREAT_DETECTION_DASHBOARD=true
```

Visit: `http://your-app.test/threat-detection`

### Dashboard authentication

[](#dashboard-authentication)

The dashboard uses `['web', 'auth']` middleware by default — users must be logged in.

**If your app does not have authentication set up yet** (e.g., during local development), temporarily change the middleware in `config/threat-detection.php`:

```
'dashboard' => [
    'enabled' => true,
    'path' => 'threat-detection',
    'middleware' => ['web'],  // temporarily remove 'auth'
],
```

> Restore `['web', 'auth']` before deploying to production.

**If the dashboard shows empty data**, make sure the API endpoints are accessible. The dashboard fetches data from the API. See [API Authentication](#api-authentication) for details.

---

API Endpoints
-------------

[](#api-endpoints)

The package provides 15 REST endpoints for building custom dashboards or integrations.

### API Authentication

[](#api-authentication)

API routes use `auth:sanctum` middleware by default. The package handles this gracefully:

- **Sanctum installed:** API requires authentication via Sanctum tokens or SPA session auth.
- **Sanctum NOT installed:** The package **automatically detects** that Sanctum is missing and falls back to `['api']` only. The API works without authentication.

**If you don't use Sanctum but want to protect your API**, add your own auth guard in `config/threat-detection.php`:

```
'api' => [
    'enabled' => true,
    'prefix' => 'api/threat-detection',
    'middleware' => ['api', 'auth'],  // or 'auth:your-guard'
],
```

**For local testing** (if Sanctum blocks access), temporarily change:

```
'middleware' => ['api'],  // remove 'auth:sanctum'
```

> Restore authentication before deploying to production.

### Endpoint Reference

[](#endpoint-reference)

MethodEndpointDescriptionGET`/api/threat-detection/threats`List threats (paginated, filterable)GET`/api/threat-detection/threats/{id}`Single threat detailsPOST`/api/threat-detection/threats/{id}/false-positive`Mark threat as false positiveGET`/api/threat-detection/stats`Overall statisticsGET`/api/threat-detection/summary`Detailed breakdown by type, level, IPGET`/api/threat-detection/live-count`Threats in last hourGET`/api/threat-detection/by-country`Grouped by countryGET`/api/threat-detection/by-cloud-provider`Grouped by cloud providerGET`/api/threat-detection/top-ips`Top offending IPsGET`/api/threat-detection/timeline`Threat timeline (for charts)GET`/api/threat-detection/ip-stats?ip=x.x.x.x`Stats for specific IPGET`/api/threat-detection/correlation`Correlation analysisGET`/api/threat-detection/export`Export to CSVGET`/api/threat-detection/exclusion-rules`List exclusion rulesDELETE`/api/threat-detection/exclusion-rules/{id}`Delete an exclusion rule### Query Parameters for `/threats`

[](#query-parameters-for-threats)

ParameterDescription`keyword`Search in IP, URL, type`ip`Filter by IP address`level`Filter by threat level (`high`, `medium`, `low`)`type`Filter by threat type`country`Filter by country code`is_foreign`Filter foreign IPs (`true`/`false`)`cloud_provider`Filter by cloud provider`is_false_positive`Filter by false positive status (`true`/`false`)`date_from` / `date_to`Date range filter`per_page`Items per page (default: 20, max: 100)### Example API Response

[](#example-api-response)

**GET `/api/threat-detection/stats`:**

```
{
  "success": true,
  "data": {
    "total_threats": 847,
    "high_severity": 23,
    "medium_severity": 156,
    "low_severity": 668,
    "unique_ips": 94,
    "foreign_ips": 67,
    "cloud_attacks": 12,
    "today": 34,
    "last_hour": 5
  }
}
```

### Building Custom Frontends

[](#building-custom-frontends)

**Vue.js:**

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

    const threats = await fetch('/api/threat-detection/threats?per_page=20');
    this.threats = await threats.json();
}
```

**React:**

```
useEffect(() => {
    fetch('/api/threat-detection/stats')
        .then(res => res.json())
        .then(data => setStats(data));
}, []);
```

> If your API uses `auth:sanctum`, include authentication headers or configure Sanctum SPA authentication for cookie-based requests.

---

Artisan Commands
----------------

[](#artisan-commands)

```
# View threat stats summary in the terminal
php artisan threat-detection:stats

# Enrich existing logs with geo-data (country, city, ISP, cloud provider)
# Uses the free ip-api.com service (rate-limited to 45 req/min, auto-throttled)
php artisan threat-detection:enrich --days=7

# Purge old logs to keep the database clean
php artisan threat-detection:purge --days=30
```

---

Custom Patterns
---------------

[](#custom-patterns)

Add your own detection regex patterns in `config/threat-detection.php`:

```
'custom_patterns' => [
    '/your-regex-here/i' => 'Your Threat Label',
],
```

**Example — detect requests to a WordPress login page:**

```
'/\/wp-login\.php/i' => 'WordPress Login Probe',
```

The threat level for each pattern is determined automatically by matching keywords in the label against the `threat_levels` config:

```
'threat_levels' => [
    'high' => ['XSS', 'SQL Injection', 'RCE', 'Aadhaar', 'PAN', 'Bank', 'Token', 'Password', 'JWT', 'Deserialization', 'Metadata Access', 'Evasion', 'Encoding'],
    'medium' => ['Directory Traversal', 'LFI', 'SSRF', 'Sensitive', 'Config', 'Session', 'Command Chain', 'Recon Tool', 'Raw PHP'],
    'low' => ['User-Agent', 'JS Redirect', 'SEO Bot', 'Empty', 'Rate', 'Command-line Downloader'],
],
```

If the label doesn't match any keyword, the threat defaults to `low` severity.

Invalid regex patterns are automatically skipped and logged as warnings — they won't crash your application.

---

Using the Facade
----------------

[](#using-the-facade)

For programmatic access to threat data outside of the middleware:

```
use JayAnta\ThreatDetection\Facades\ThreatDetection;

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

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

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

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

---

Reducing False Positives
------------------------

[](#reducing-false-positives)

### Content Path Suppression

[](#content-path-suppression)

If you have CMS editors, blog post forms, or comment sections where users submit rich content, those paths often trigger false positives (e.g., a blog post containing `` code samples). Add those paths to suppress low/medium alerts:

```
// config/threat-detection.php
'content_paths' => [
    'admin/posts/*',
    'admin/pages/*',
    'blog/*/edit',
    'comments',
],
```

On these paths, only **high-severity** threats are logged.

### False Positive Reporting

[](#false-positive-reporting)

Click the **FP** button on any threat in the dashboard to mark it as a false positive. This:

1. Flags the threat as `is_false_positive = true`
2. Auto-creates an exclusion rule so similar threats from the same URL/type are suppressed going forward

Manage exclusion rules via API:

```
GET  /api/threat-detection/exclusion-rules
DELETE /api/threat-detection/exclusion-rules/{id}
```

### Confidence Scoring

[](#confidence-scoring)

Every threat receives a confidence score (0-100) based on:

- Number of pattern matches in the same request
- Severity of the matched pattern
- Where the pattern was found (query string &gt; headers &gt; body)
- Whether the user-agent matches a known attack tool
- Current detection mode

Threats below the confidence threshold for your detection mode are not logged (see [Detection Modes](#detection-modes)).

---

Detected Attack Types
---------------------

[](#detected-attack-types)

CategoryExamples**Injection**SQL injection (UNION, boolean, time-based, CHAR encoding), NoSQL injection, command injection, LDAP injection**XSS**Script tags, event handlers, JavaScript URIs, DOM manipulation, encoded XSS**Code Execution**RCE, PHP deserialization, template injection (Blade, JSP, ASP), eval(), base64 decode**File Access**Directory traversal, LFI/RFI, sensitive file probes (.env, wp-config, composer.json, .git)**SSRF**Localhost access, AWS/GCP metadata endpoints, private IP ranges (10.x, 172.16-31.x, 192.168.x)**Authentication**Brute force detection, token leaks, password exposure, session ID exposure**Scanners**SQLMap, Nikto, Nmap, Burp Suite, Acunetix, WPScan, Nessus, Nuclei, Metasploit**Bots**Python scripts, Go HTTP clients, cURL, wget, empty user agents**DDoS**Rate-based excessive request detection**XXE**XML external entity attacks, DOCTYPE entity declarations**Log4Shell**JNDI injection attempts (LDAP, RMI, DNS)**Evasion**SQL comment insertion (`UNION/**/SELECT`), double URL encoding (`%2527`), CHAR encoding**Web Shells**c99, r57, b374k, WSO, FilesMan, encoded eval execution**Crypto Mining**Coinhive, CryptoNight, Monero script detection---

Running the Test Suite
----------------------

[](#running-the-test-suite)

```
composer test
```

The package includes 86 tests covering detection patterns, middleware behavior, API endpoints, confidence scoring, exclusion rules, DDoS detection, evasion resistance (full-cycle), queue support, event dispatch, and input validation.

---

License
-------

[](#license)

MIT License. See [LICENSE](LICENSE) for details.

Contributing
------------

[](#contributing)

Contributions are welcome! Please submit a Pull Request.

Credits
-------

[](#credits)

- [Jay Anta](https://github.com/jay123anta)

###  Health Score

43

—

FairBetter than 91% of packages

Maintenance88

Actively maintained with recent releases

Popularity23

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity44

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~4 days

Total

3

Last Release

62d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/169d7ffbb5c1225ca08050f854ee9509a30042b2bde07178351882d20f90a8fb?d=identicon)[jay123anta](/maintainers/jay123anta)

---

Top Contributors

[![jay123anta](https://avatars.githubusercontent.com/u/62276865?v=4)](https://github.com/jay123anta "jay123anta (46 commits)")

---

Tags

bot-detectionddos-protectionfail2banhoneypotintrusion-detectionlaravellaravel-packagemiddlewareowaspphpsecuritysecurity-monitoringsql-injectionthreat-detectionwafweb-application-firewallweb-application-securityxssxss-detectionmiddlewarelaravelloggingsecurityxssSQL Injectionthreat-detectionddosintrusion-detection

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/jayanta-laravel-threat-detection/health.svg)

```
[![Health](https://phpackages.com/badges/jayanta-laravel-threat-detection/health.svg)](https://phpackages.com/packages/jayanta-laravel-threat-detection)
```

###  Alternatives

[laravel/cashier

Laravel Cashier provides an expressive, fluent interface to Stripe's subscription billing services.

2.5k25.9M107](/packages/laravel-cashier)[laravel/pulse

Laravel Pulse is a real-time application performance monitoring tool and dashboard for your Laravel application.

1.7k12.1M99](/packages/laravel-pulse)[roots/acorn

Framework for Roots WordPress projects built with Laravel components.

9682.1M97](/packages/roots-acorn)[spatie/laravel-health

Monitor the health of a Laravel application

85810.0M83](/packages/spatie-laravel-health)[yadahan/laravel-authentication-log

Laravel Authentication Log provides authentication logger and notification for Laravel.

416632.8k5](/packages/yadahan-laravel-authentication-log)[dragon-code/laravel-http-logger

Logging incoming HTTP requests

319.8k3](/packages/dragon-code-laravel-http-logger)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
