PHPackages                             metalinked/laravel-defender - 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. [Security](/categories/security)
4. /
5. metalinked/laravel-defender

ActiveLibrary[Security](/categories/security)

metalinked/laravel-defender
===========================

Modular Laravel security package: brute force protection, dynamic IP blocklist, auto-block, country access control, honeypot, events, Pulse card, multi-channel alerts, and security audit.

v1.19.0(1w ago)458↓64.7%MITPHPPHP ^8.2CI failing

Since Jun 13Pushed 10mo ago1 watchersCompare

[ Source](https://github.com/metalinked/laravel-defender)[ Packagist](https://packagist.org/packages/metalinked/laravel-defender)[ RSS](/packages/metalinked-laravel-defender/feed)WikiDiscussions main Synced today

READMEChangelog (10)Dependencies (20)Versions (18)Used By (0)

Laravel Defender
================

[](#laravel-defender)

[![Tests](https://camo.githubusercontent.com/47ffe524d1126eb7f8c2a6c9615063bd28fef72eab7f2fa13d8dd5cbade29932/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f6d6574616c696e6b65642f6c61726176656c2d646566656e6465722f74657374732e796d6c3f6272616e63683d6d61696e266c6162656c3d7465737473267374796c653d666c61742d737175617265)](https://github.com/metalinked/laravel-defender/actions/workflows/tests.yml)[![PHPStan](https://camo.githubusercontent.com/e91d761e62b6ce7d323c09f3bf73730047ebba9d69a98b822164aef3495071e9/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f6d6574616c696e6b65642f6c61726176656c2d646566656e6465722f7068707374616e2e796d6c3f6272616e63683d6d61696e266c6162656c3d7068707374616e267374796c653d666c61742d737175617265)](https://github.com/metalinked/laravel-defender/actions/workflows/phpstan.yml)[![GitHub Release](https://camo.githubusercontent.com/02cf3c45e8e4ff76986c863602a845258b31cdb6227739fc0d1be300cb0f3003/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f762f72656c656173652f6d6574616c696e6b65642f6c61726176656c2d646566656e6465723f7374796c653d666c61742d737175617265)](https://github.com/metalinked/laravel-defender/releases)[![Total Downloads](https://camo.githubusercontent.com/1388ec4211187270219a5184fdc13671fe2004b9548f9c3edc0864fca1d7bea7/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f6d6574616c696e6b65642f6c61726176656c2d646566656e6465723f7374796c653d666c61742d737175617265)](https://packagist.org/packages/metalinked/laravel-defender)[![License](https://camo.githubusercontent.com/254988f8f16f43bcaeda47adbf228efe359ca3f0f7557c7d7977e216ff253bb0/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f6d6574616c696e6b65642f6c61726176656c2d646566656e6465723f7374796c653d666c61742d737175617265)](https://github.com/metalinked/laravel-defender/blob/main/LICENSE.md)

A modular security package for Laravel with advanced threat detection, brute force protection, dynamic IP blocklisting with auto-block, country access control, honeypot spam protection, multi-channel alerts, and a Laravel Pulse dashboard card. Fully configurable and privacy-friendly.

---

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

[](#requirements)

LaravelPHP11.x^8.212.x^8.213.x^8.3---

Features
--------

[](#features)

- 🛡️ **Honeypot spam protection** for forms
- 👁️ **Request logging** and alert system for suspicious activity
- 🚨 **Advanced risk detection**: malicious user-agents, common attack routes, login attempts with common usernames, path traversal, and fuzzing patterns
- 🔒 **Brute force protection**: blocks IPs after too many suspicious requests
- 🌍 **Country access control**: allow or deny by country code, with IP whitelist bypass
- 🚫 **Dynamic IP blocklist**: block/unblock IPs at runtime via Artisan, no config changes needed
- 🤖 **Auto-block**: automatically block IPs that trigger repeated events within a configurable time window
- 🎯 **Laravel Events**: `SuspiciousRequestDetected` and `IpBlocked` for full extensibility
- 🔔 **Multi-channel alerts**: log, database, mail, Slack, webhook
- 📊 **Laravel Pulse card**: real-time security dashboard (optional, requires `laravel/pulse`)
- 🔍 **Security audit command**: detects common Laravel misconfigurations and missing security headers
- 📝 **Artisan commands**: view, export, and prune logs directly from the console

---

Installation
------------

[](#installation)

**1. Install via Composer:**

```
composer require metalinked/laravel-defender
```

**2. Publish the config file:**

```
php artisan vendor:publish --tag=defender-config
```

**3. Publish and run the migrations:**

```
php artisan vendor:publish --tag=defender-migrations
php artisan migrate
```

This creates two tables:

- `defender_ip_logs`: stores access logs and security alerts
- `defender_blocked_ips`: stores dynamically blocked IPs

> The `database` alert channel and the IP blocklist both require the migrations to be run. If you only use `log`-based alerts and no blocklist, you can skip the migrations.

---

Global Protection (Recommended)
-------------------------------

[](#global-protection-recommended)

Register Defender's middlewares globally to protect all requests, including those to non-existent routes like `/wp-admin`, `/phpmyadmin`, and `/xmlrpc.php`.

In `bootstrap/app.php`:

```
->withMiddleware(function (Middleware $middleware) {
    $middleware->append(\Metalinked\LaravelDefender\Http\Middleware\BlockedIpMiddleware::class);
    $middleware->append(\Metalinked\LaravelDefender\Http\Middleware\AdvancedDetectionMiddleware::class);
    $middleware->append(\Metalinked\LaravelDefender\Http\Middleware\BruteForceMiddleware::class);
    $middleware->append(\Metalinked\LaravelDefender\Http\Middleware\CountryAccessMiddleware::class);
})
```

MiddlewareDescription`BlockedIpMiddleware`Instantly blocks IPs in the dynamic blocklist (returns 403). Run this first.`AdvancedDetectionMiddleware`Detects malicious user-agents, attack routes, and common usernames.`BruteForceMiddleware`Blocks IPs after too many suspicious requests in the configured window.`CountryAccessMiddleware`Allows or denies access based on country code.---

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

[](#configuration)

All options are in `config/defender.php` after publishing.

### IP Logging &amp; Brute Force

[](#ip-logging--brute-force)

```
'ip_logging' => [
    'enabled' => true,
    'log_all'  => false, // Log every request, not just suspicious ones. Only for debugging.
],

'brute_force' => [
    'max_attempts'  => 5,
    'decay_minutes' => 10,
],
```

### Advanced Detection &amp; Country Access

[](#advanced-detection--country-access)

```
'advanced_detection' => [
    'enabled'                => true,
    'geo_provider'           => 'ip-api',       // 'ip-api', 'ipinfo', 'ipgeolocation'
    'geo_cache_minutes'      => 10,
    'ipinfo_token'           => env('IPINFO_TOKEN'),
    'ipgeolocation_key'      => env('IPGEOLOCATION_KEY'),
    'suspicious_user_agents' => ['curl', 'python', 'sqlmap', 'nmap', 'nikto', 'fuzzer', 'scanner'],
    'suspicious_routes'      => ['/wp-admin', '/wp-login', '/phpmyadmin', '/admin.php', '/xmlrpc.php'],
    'common_usernames'       => ['admin', 'administrator', 'root', 'test', 'user'],
    'country_access' => [
        'mode'          => 'allow',       // 'allow' = only listed countries; 'deny' = block listed countries
        'countries'     => ['ES'],
        'whitelist_ips' => ['1.2.3.4'],  // Always allowed, regardless of country
    ],
],
```

**Geo providers:**

- [ip-api.com](https://ip-api.com/): free tier, no registration required (default)
- [ipinfo.io](https://ipinfo.io/): requires `IPINFO_TOKEN`
- [ipgeolocation.io](https://ipgeolocation.io/): requires `IPGEOLOCATION_KEY`

### Dynamic IP Blocklist &amp; Auto-block

[](#dynamic-ip-blocklist--auto-block)

```
'blocklist' => [
    'enabled'                 => true,
    'cache_ttl'               => 300,   // Seconds to cache each IP's blocked status
    'auto_block_after'        => null,  // IpBlocked events before auto-blocking (null = disabled)
    'auto_block_hours'        => null,  // Duration of auto-block in hours (null = permanent)
    'auto_block_window_hours' => 24,    // Sliding window in hours for counting events
],
```

### Alerts

[](#alerts)

```
'alerts' => [
    'channels' => ['log', 'database'], // Also: 'mail', 'slack', 'webhook'
    'mail'     => ['to' => env('DEFENDER_ALERT_MAIL_TO')],
    'slack'    => ['webhook_url' => env('DEFENDER_SLACK_WEBHOOK')],
    'webhook'  => ['url' => env('DEFENDER_ALERT_WEBHOOK')],
],
```

### Environment Variables

[](#environment-variables)

VariableDescription`DEFENDER_GEO_PROVIDER`Geo provider: `ip-api`, `ipinfo`, or `ipgeolocation``IPINFO_TOKEN`API token for ipinfo.io`IPGEOLOCATION_KEY`API key for ipgeolocation.io`DEFENDER_ALERT_MAIL_TO`Email address for alert notifications`DEFENDER_SLACK_WEBHOOK`Slack incoming webhook URL`DEFENDER_ALERT_WEBHOOK`Custom webhook URL for alert notifications---

Dynamic IP Blocklist
--------------------

[](#dynamic-ip-blocklist)

Block and unblock IPs at runtime without touching config files or deploying:

```
# Block permanently
php artisan defender:block-ip 1.2.3.4 --reason="Persistent attacker"

# Block for 24 hours
php artisan defender:block-ip 1.2.3.4 --reason="Brute force" --hours=24

# Unblock
php artisan defender:unblock-ip 1.2.3.4

# List all currently blocked IPs
php artisan defender:block-list
```

Blocked IPs are stored in `defender_blocked_ips` and cached (default 5 minutes per IP) for fast lookup on every request.

---

Auto-block
----------

[](#auto-block)

Defender can automatically block IPs that trigger repeated `IpBlocked` events within a time window, useful for catching persistent attackers without manual intervention.

Enable it in `config/defender.php`:

```
'blocklist' => [
    'auto_block_after'        => 5,   // Block after 5 triggered events
    'auto_block_hours'        => 24,  // Block for 24 hours (null = permanent)
    'auto_block_window_hours' => 24,  // Count events within a 24-hour sliding window
],
```

With this configuration, any IP that causes 5 blocked requests within 24 hours is automatically added to the blocklist for 24 hours. The counter resets after blocking.

Auto-block is **disabled by default** (`auto_block_after: null`).

---

Events &amp; Extensibility
--------------------------

[](#events--extensibility)

Defender fires standard Laravel events you can listen to from your application:

```
use Metalinked\LaravelDefender\Events\SuspiciousRequestDetected;
use Metalinked\LaravelDefender\Events\IpBlocked;

// In your EventServiceProvider or AppServiceProvider boot():
Event::listen(SuspiciousRequestDetected::class, function ($event) {
    // $event->ip, $event->reason, $event->request
    // Fired when a threat is detected, even if the request is not blocked
});

Event::listen(IpBlocked::class, function ($event) {
    // $event->ip, $event->reason, $event->request
    // Fired when a middleware actually blocks a request (returns 429 or 403)
});
```

Use these events to integrate with your own notification system, SIEM, audit trail, or any custom logic, without modifying the package.

---

Honeypot Spam Protection
------------------------

[](#honeypot-spam-protection)

Protects forms from bots using a hidden field and a time-based check.

**1. Add the honeypot field to your Blade form:**

```
@defenderHoneypot
```

**2. Enable automatic protection or use the middleware per route:**

```
// config/defender.php
'honeypot' => [
    'auto_protect_forms' => true,
],
```

Or apply it manually:

```
Route::post('/contact', ...)->middleware('defender.honeypot');
```

**Publish the view (optional):**

```
php artisan vendor:publish --tag=defender-views
```

---

Alert System
------------

[](#alert-system)

Defender supports multiple alert channels for real-time notifications.

ChannelDescriptionDefault`log`Writes to Laravel's application logEnabled`database`Saves alerts to `defender_ip_logs`Enabled`mail`Sends an email to `DEFENDER_ALERT_MAIL_TO`Disabled`slack`Posts to a Slack webhookDisabled`webhook`POSTs to any URLDisabled---

Laravel Pulse Card
------------------

[](#laravel-pulse-card)

If [Laravel Pulse](https://pulse.laravel.com/) is installed, Defender automatically registers a dashboard card with live security activity.

Add the card to your Pulse dashboard view:

```

```

The card shows:

- Threats detected in the last hour
- Total threats recorded
- Top 5 attacking IPs
- Latest 8 detection events (auto-refreshes every 10 seconds)

No additional configuration needed. The card is registered automatically when Pulse and Livewire are detected.

---

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

[](#artisan-commands)

### View logs

[](#view-logs)

```
php artisan defender:ip-logs                  # Latest 50 logs
php artisan defender:ip-logs --suspicious     # Only suspicious logs
php artisan defender:ip-logs --ip=1.2.3.4     # Filter by IP
php artisan defender:ip-logs --limit=100      # Limit results
```

### Export logs

[](#export-logs)

```
php artisan defender:export-logs --format=csv
php artisan defender:export-logs --suspicious --format=json --output=suspicious.json
php artisan defender:export-logs --ip=1.2.3.4 --from=2024-06-01 --to=2024-06-30 --format=csv
```

> Only logs stored in the database (with the `database` channel enabled) can be viewed or exported.

### Prune old logs

[](#prune-old-logs)

```
php artisan defender:prune-logs --days=90            # Delete logs older than 90 days
php artisan defender:prune-logs --days=30 --laravel  # Also remove old Laravel log files
```

**Scheduled pruning**: add to `bootstrap/routes/console.php`:

```
Schedule::command('defender:prune-logs --days=90')->daily();
```

---

Security Audit
--------------

[](#security-audit)

Run a local audit of your Laravel application's security configuration:

```
php artisan defender:audit
```

Checks for:

- Publicly accessible `.env` file
- `APP_DEBUG` enabled in production
- Permissive CORS configuration (`allowed_origins = "*"`)
- Insecure session cookies (missing `secure` or `http_only` flags)
- Weak or missing `APP_KEY`
- Missing HTTP security headers (`X-Frame-Options`, `X-Content-Type-Options`, `Referrer-Policy`, `Strict-Transport-Security`)

Each issue includes a specific remediation tip.

---

Testing
-------

[](#testing)

```
composer test
```

> Requires the `pdo_sqlite` PHP extension. Tests use an SQLite in-memory database via Orchestra Testbench.

---

Security
--------

[](#security)

To report a security vulnerability, email . All reports are handled responsibly and in confidence.

---

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

[](#contributing)

See [CONTRIBUTING.md](CONTRIBUTING.md) for contribution guidelines.

---

License
-------

[](#license)

MIT © [Metalinked](https://metalinked.net)

---

💬 [Questions, suggestions or feedback? Open a discussion.](https://github.com/metalinked/laravel-defender/discussions)

###  Health Score

41

—

FairBetter than 87% of packages

Maintenance72

Regular maintenance activity

Popularity15

Limited adoption so far

Community9

Small or concentrated contributor base

Maturity58

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 69% 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 ~25 days

Recently: every ~79 days

Total

16

Last Release

13d ago

PHP version history (2 changes)v1.12.0PHP ^8.1

v1.19.0PHP ^8.2

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/213125150?v=4)[metalinked ](/maintainers/metalinked)[@metalinked](https://github.com/metalinked)

---

Top Contributors

[![oskratch](https://avatars.githubusercontent.com/u/16107567?v=4)](https://github.com/oskratch "oskratch (69 commits)")[![github-actions[bot]](https://avatars.githubusercontent.com/in/15368?v=4)](https://github.com/github-actions[bot] "github-actions[bot] (31 commits)")

---

Tags

alertsbrute-forcecountry-blockingdefendergeoiphoneypotip-logginglaravellogin-protectionmiddlewarephpsecuritymiddlewarelaravelgeoipsecurityalertsHoneypotbrute forcelogin protectiondefenderip-loggingcountry-blocking

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Code StylePHP CS Fixer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/metalinked-laravel-defender/health.svg)

```
[![Health](https://phpackages.com/badges/metalinked-laravel-defender/health.svg)](https://phpackages.com/packages/metalinked-laravel-defender)
```

###  Alternatives

[craftcms/cms

Craft CMS

3.6k3.6M3.1k](/packages/craftcms-cms)[jorijn/laravel-security-checker

Added Laravel functionality to the Enlightn Security Checker. Adds a command to check for, and optionally emails you, vulnerabilities when they affect you.

2111.9M1](/packages/jorijn-laravel-security-checker)[dgtlss/warden

A Laravel package that proactively monitors your dependencies for security vulnerabilities by running automated composer audits and sending notifications via webhooks and email

9062.1k](/packages/dgtlss-warden)[simplestats-io/laravel-client

Server-side analytics for Laravel that follows the full funnel from visit to registration to payment, attributed to the channel that drove it. Revenue, MRR, churn and ad-spend profit (ROAS/CAC) per channel. GDPR compliant, ad-blocker proof.

5021.9k](/packages/simplestats-io-laravel-client)

PHPackages © 2026

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