PHPackages                             rilo-arbabillah/laravel-crowdsec - 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. rilo-arbabillah/laravel-crowdsec

ActiveLibrary[Security](/categories/security)

rilo-arbabillah/laravel-crowdsec
================================

A lightweight CrowdSec-like WAF protection package for Laravel

1.0.0(2mo ago)229MITPHPPHP ^8.1CI passing

Since Mar 11Pushed 1mo agoCompare

[ Source](https://github.com/RiloArbabillah/crowdsec)[ Packagist](https://packagist.org/packages/rilo-arbabillah/laravel-crowdsec)[ RSS](/packages/rilo-arbabillah-laravel-crowdsec/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (2)Dependencies (9)Versions (8)Used By (0)

Laravel CrowdSec
================

[](#laravel-crowdsec)

[![Tests](https://github.com/RiloArbabillah/crowdsec/actions/workflows/tests.yml/badge.svg)](https://github.com/RiloArbabillah/crowdsec/actions/workflows/tests.yml)[![PHP Version](https://camo.githubusercontent.com/d590161c406022a0e2c27dc443b956246a069bdce9f0c6b44fcf810371b91f72/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f7068702d762f72696c6f2d6172626162696c6c61682f6c61726176656c2d63726f77647365632e737667)](https://packagist.org/packages/rilo-arbabillah/laravel-crowdsec)[![License](https://camo.githubusercontent.com/bb43ff9ff963178df394cceb43e91fe9aa03aa4bcc2cb4ff5d8877a1e1d87923/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c6963656e73652f72696c6f2d6172626162696c6c61682f6c61726176656c2d63726f77647365632e737667)](LICENSE)

A lightweight, CrowdSec-like Web Application Firewall (WAF) protection package for Laravel applications. This package provides real-time threat detection and IP blocking based on WAF patterns and behavior analysis.

Release Status
--------------

[](#release-status)

- Latest stable Packagist release: `v1.0.2`
- Stable compatibility: Laravel `^10.0|^11.0|^12.0` with the current hardening and CI updates

Features
--------

[](#features)

- **WAF Pattern Detection**: Detects SQL injection, XSS, path traversal, command injection, and 11 more attack types
- **IP Blocking**: Temporary IP blocks with automatic expiration and progressive escalation
- **Behavior-based Protection**: Rate limiting, brute-force detection, and threat score tracking with auto-decay
- **Caching Layer**: Cached blocked IP lookups for high-traffic applications
- **Event System**: 4 Laravel events (ThreatDetected, IpBlocked, IpUnblocked, BehaviorThresholdExceeded)
- **Notifications**: Email and Slack alerts with severity filtering and rate limiting
- **Honeypot Routes**: Trap routes to catch automated scanners
- **Per-Route Rate Limiting**: Configurable rate limits via middleware (`crowdsec.rate:60,1`)
- **Custom Patterns**: Register custom detection scenarios at runtime
- **GeoIP Lookup**: IP geolocation via ip-api.com with caching
- **REST API**: 6 API endpoints for programmatic management (block, unblock, check, stats, events, blocked)
- **Admin Dashboard**: Standalone dark theme Blade dashboard (enable via config)
- **SIEM Export**: Export events in JSON, CSV, or Syslog (RFC 5424) format
- **CLI Commands**: Statistics, cleanup, and export utilities
- **Facade API**: Easy programmatic access to all features
- **Auto-migrations**: Database tables created automatically
- **CI Pipeline**: GitHub Actions with PHP 8.1/8.2/8.3 × Laravel 10.x/11.x/12.x plus a PHPStan quality gate

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

[](#requirements)

- PHP ^8.1
- Laravel ^10.0 or ^11.0 or ^12.0
- MySQL/PostgreSQL/SQLite (any Laravel-supported database)

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

[](#installation)

Install the package via Composer:

```
composer require rilo-arbabillah/laravel-crowdsec
```

The package will automatically register its service provider and facade.

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

[](#configuration)

Publish the configuration file to customize detection scenarios and thresholds:

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

This will create `config/crowdsec-scenarios.php` where you can:

- Enable or disable the package
- Configure detection patterns for each attack type
- Adjust behavior thresholds (request limits, 404 limits, login attempts)
- Set block durations per severity
- Whitelist IPs that should never be blocked

### Notification Channels

[](#notification-channels)

CrowdSec can send on-demand security alerts through email and Slack. Mail delivery uses the `notifications.recipients` list, while Slack delivery requires an incoming webhook URL.

```
'notifications' => [
    'enabled' => env('CROWDSEC_NOTIFY_ENABLED', false),
    'channels' => ['mail', 'slack'],
    'severity_threshold' => 'high',
    'rate_limit_minutes' => 5,
    'recipients' => ['security@example.com'],
    'slack_webhook_url' => env('CROWDSEC_NOTIFY_SLACK_WEBHOOK_URL', ''),
],
```

```
CROWDSEC_NOTIFY_ENABLED=true
CROWDSEC_NOTIFY_CHANNELS=mail,slack
CROWDSEC_NOTIFY_RECIPIENTS=security@example.com,ops@example.com
CROWDSEC_NOTIFY_SLACK_WEBHOOK_URL=https://hooks.slack.com/services/T000/B000/XXXX
```

If you enable the `slack` channel without a webhook URL, `php artisan crowdsec:doctor`will report the configuration as invalid.

### Enabling/Disabling the Package

[](#enablingdisabling-the-package)

You can toggle the package on or off via configuration:

```
// config/crowdsec-scenarios.php

return [
    // Enable or disable the entire package
    'enabled' => true,  // Set to false to disable all protection

    // ... rest of configuration
];
```

When disabled, the middleware will pass all requests through without any filtering or blocking. This is useful for:

- Development environments where you need to test without WAF interference
- Debugging specific issues without protection blocking legitimate traffic
- Temporary maintenance windows

### Default Configuration

[](#default-configuration)

```
// config/crowdsec-scenarios.php

return [
    // Enable/disable the package
    'enabled' => true,

    // Whitelist IPs (won't be blocked)
    'whitelist_ips' => [
        '127.0.0.1',
        '::1',
    ],

    // Behavior thresholds
    'behavior' => [
        'request_threshold' => 500,      // requests per minute
        '404_threshold' => 15,           // 404s per minute
        'login_threshold' => 5,          // login attempts per minute
        'threat_score_threshold' => 50,
        'block_duration' => 240,         // 4 hours
        'severity' => 'high',
    ],

    // Block duration defaults (in minutes)
    'defaults' => [
        'low' => 60,
        'medium' => 240,
        'high' => 720,
        'critical' => 1440,
    ],

    // ... detection patterns
];
```

Basic Usage
-----------

[](#basic-usage)

### Applying Middleware to Routes

[](#applying-middleware-to-routes)

Apply the middleware to individual routes:

```
use Illuminate\Support\Facades\Route;

Route::middleware(['crowdsec'])->group(function () {
    Route::get('/admin', function () {
        // Protected route
    });

    Route::post('/login', [AuthController::class, 'login']);
});
```

### Applying Middleware Globally

[](#applying-middleware-globally)

Add the middleware to your HTTP kernel for global protection:

```
// app/Http/Kernel.php

protected $middlewareAliases = [
    // ...
    'crowdsec' => \RiloArbabillah\LaravelCrowdSec\Http\Middleware\CrowdSecProtection::class,
];
```

Then apply to routes or route groups:

```
// Protect all web routes
Route::middleware(['crowdsec'])->group(base_path('routes/web.php'));

// Protect API routes
Route::middleware(['api', 'crowdsec'])->group(base_path('routes/api.php'));
```

### Skipping Middleware for Certain Routes

[](#skipping-middleware-for-certain-routes)

```
// Disable for health check endpoints
Route::middleware(['crowdsec'])->group(function () {
    Route::get('/admin', function () {
        // Protected
    });
});

Route::get('/health', function () {
    // Not protected
})->withoutMiddleware(['crowdsec']);
```

Programmatic Usage
------------------

[](#programmatic-usage)

Use the `CrowdSec` facade for programmatic control:

### Check if IP is Blocked

[](#check-if-ip-is-blocked)

```
use RiloArbabillah\LaravelCrowdSec\Facades\CrowdSec;

$ip = request()->ip();

if (CrowdSec::isBlocked($ip)) {
    abort(403, 'Your IP has been blocked');
}
```

### Manually Block an IP

[](#manually-block-an-ip)

```
use RiloArbabillah\LaravelCrowdSec\Facades\CrowdSec;

// Block for 60 minutes
CrowdSec::blockIp($request->ip(), 'Manual ban - spam', 60);

// Block for 24 hours (default for critical threats)
CrowdSec::blockIp($request->ip(), 'Suspicious activity', 1440);
```

### Unblock an IP

[](#unblock-an-ip)

```
use RiloArbabillah\LaravelCrowdSec\Facades\CrowdSec;

CrowdSec::unblockIp($ip);
```

### Track Login Attempts

[](#track-login-attempts)

Call this after failed login attempts for brute-force protection:

```
use RiloArbabillah\LaravelCrowdSec\Facades\CrowdSec;

public function login(Request $request)
{
    if (! Auth::attempt($credentials)) {
        // Track failed attempt
        CrowdSec::trackLoginAttempt($request->ip());

        return back()->withErrors(['email' => 'Invalid credentials']);
    }

    // Reset login attempts on successful login
    // (optional - you could implement this)

    return redirect('/dashboard');
}
```

### Analyze Request for Threats

[](#analyze-request-for-threats)

```
use RiloArbabillah\LaravelCrowdSec\Facades\CrowdSec;

$threats = CrowdSec::analyzeRequest($request);

if (! empty($threats)) {
    foreach ($threats as $threat) {
        \Log::warning('Security threat detected', [
            'type' => $threat['type'],
            'severity' => $threat['severity'],
            'matched' => $threat['matched'],
        ]);
    }
}
```

CLI Commands
------------

[](#cli-commands)

### View Protection Statistics

[](#view-protection-statistics)

```
php artisan crowdsec:stats
```

Output includes:

- Active blocked IPs
- Expired blocked IPs
- Events today
- Events this week
- Top attackers (IP addresses)

For JSON output (useful for monitoring):

```
php artisan crowdsec:stats --json
```

### Clean Up Expired Bans

[](#clean-up-expired-bans)

Remove expired IP blocks and old security events:

```
php artisan crowdsec:cleanup
```

If audit logging is enabled, the cleanup command also prunes audit records older than `audit.retention_days`.

#### Cleanup Options

[](#cleanup-options)

```
# Preview what would be deleted (no changes)
php artisan crowdsec:cleanup --dry-run

# Clean only expired bans
php artisan crowdsec:cleanup --expired

# Clean only old events (older than 30 days)
php artisan crowdsec:cleanup --old-events

# Clean only old behaviors (older than 7 days)
php artisan crowdsec:cleanup --old-behaviors
```

Audit log retention is configured in `config/crowdsec-scenarios.php`:

```
'audit' => [
    'enabled' => env('CROWDSEC_AUDIT_ENABLED', false),
    'retention_days' => env('CROWDSEC_AUDIT_RETENTION_DAYS', 365),
],
```

#### Automated Cleanup in Production

[](#automated-cleanup-in-production)

Add to your `routes/console.php` or set up a scheduled command:

```
// In routes/console.php
Artisan::command('crowdsec:daily-cleanup', function () {
    $this->call('crowdsec:cleanup', ['--expired' => true]);
})->purpose('Clean up expired bans daily');
```

Or use Laravel's scheduler:

```
// In app/Console/Kernel.php
protected function schedule(Schedule $schedule)
{
    $schedule->command('crowdsec:cleanup --expired')->daily();
}
```

Database
--------

[](#database)

The package creates three tables automatically via migrations:

TableDescription`blocked_ips`Tracks blocked IPs with expiration and reason`ip_behaviors`Tracks per-IP metrics (request count, 404s, login attempts, threat score)`security_events`Logs all detected security threatsTables are created when you run:

```
php artisan migrate
```

Detected Threats
----------------

[](#detected-threats)

The package detects the following attack types:

Threat TypeSeverityExamplesSQL InjectionCritical`UNION SELECT`, `OR 1=1`, `xp_cmdshell`XSSHigh``, `javascript:`, `onclick=`Path TraversalCritical`../`, `%2e%2e%2f`Command InjectionCritical`;cat`, `|whoami`, ``id``File InclusionHigh`php://input`, `data:text/html`PHP SerializationCritical`O:16:"MaliciousClass"`Directory BruteforceMedium`.git/config`, `.env`, `wp-admin`Header InjectionHighCRLF injection, `Location:`Suspicious User AgentMedium`sqlmap`, `nmap`, `python-requests`Behavior ThresholdHighRate limiting, brute-forceProduction Guidelines
---------------------

[](#production-guidelines)

### 1. Monitor Regularly

[](#1-monitor-regularly)

Run stats command periodically or set up monitoring:

```
# Check for active threats
php artisan crowdsec:stats

# Export to monitoring system
php artisan crowdsec:stats --json | jq '.events_today'
```

### 2. Tune Thresholds for Production

[](#2-tune-thresholds-for-production)

Adjust `config/crowdsec-scenarios.php` based on your traffic:

```
'behavior' => [
    'request_threshold' => 1000,    // Increase for high-traffic sites
    '404_threshold' => 20,          // Adjust based on your 404 rate
    'login_threshold' => 3,         // Stricter for login pages
    'threat_score_threshold' => 50,
    'block_duration' => 240,
],
```

### 3. Protect Optional Endpoints Before Enabling Them

[](#3-protect-optional-endpoints-before-enabling-them)

The REST API, metrics endpoint, and dashboard are disabled by default. When you enable them, CrowdSec now defaults to authenticated middleware so they are not exposed publicly by accident.

```
'api' => [
    'enabled' => env('CROWDSEC_API_ENABLED', false),
    'middleware' => ['api', 'auth:sanctum'],
],

'metrics' => [
    'enabled' => env('CROWDSEC_METRICS_ENABLED', false),
    'path' => 'crowdsec/metrics',
    'middleware' => ['web', 'auth'],
],

'dashboard' => [
    'enabled' => env('CROWDSEC_DASHBOARD_ENABLED', false),
    'path' => 'crowdsec',
    'middleware' => ['web', 'auth'],
],
```

Recommended production overrides:

```
'api' => [
    'enabled' => true,
    'middleware' => ['api', 'auth:sanctum'],
],

'metrics' => [
    'enabled' => true,
    'middleware' => ['signed'],
],

'dashboard' => [
    'enabled' => true,
    'middleware' => ['web', 'auth', 'verified'],
],
```

Run `php artisan crowdsec:doctor` after enabling any of these surfaces. The doctor command now fails if the API or dashboard lacks authentication, or if metrics are exposed without `auth` or `signed` middleware.

### 4. Whitelist Internal Services

[](#4-whitelist-internal-services)

```
'whitelist_ips' => [
    '127.0.0.1',
    '::1',
    '10.0.0.0/8',      // Internal network
    '192.168.0.0/16',  // Internal network
    'your-load-balancer-ip',
],
```

### 5. Set Up Log Monitoring

[](#5-set-up-log-monitoring)

Monitor Laravel logs for CrowdSec warnings:

```
// Log channel configuration
'log' => [
    'driver' => 'daily',
    'path' => storage_path('logs/laravel.log'),
    'level' => 'warning',
],
```

### 6. Schedule Regular Cleanup

[](#6-schedule-regular-cleanup)

```
// In app/Console/Kernel.php
protected function schedule(Schedule $schedule)
{
    // Clean expired bans daily at 3 AM
    $schedule->command('crowdsec:cleanup --expired --old-events --old-behaviors')
             ->daily()
             ->at('03:00');
}
```

### 7. Performance Considerations

[](#7-performance-considerations)

- The middleware runs on every request - keep patterns optimized
- IP whitelist is checked first for performance
- Behavior tracking uses efficient increment operations
- Consider caching blocked IPs for very high-traffic sites

### Performance Benchmarks

[](#performance-benchmarks)

The package includes a benchmark suite (`tests/Benchmark`) to verify overhead stays minimal.

Run benchmarks:

```
vendor/bin/phpunit tests/Benchmark --testdox
```

Typical results (100 iterations average):

OperationAvg TimeTargetWhitelist bypass~0.006ms&lt; 0.5ms ✅Clean request analysis~0.038ms&lt; 2ms ✅Blocked IP check~0.045ms&lt; 2ms ✅Threat detection (SQLi)~0.047ms&lt; 5ms ✅Multi-threat detection~0.051ms&lt; 5ms ✅POST body analysis~0.159ms&lt; 3ms ✅Behavior tracking~0.163ms&lt; 3ms ✅> **Note:** Results may vary depending on hardware. Benchmarks use SQLite in-memory.

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

[](#contributing)

Contributions are welcome! Please follow these steps:

1. Fork the repository
2. Create a feature branch: `git checkout -b feature/my-new-feature`
3. Make your changes
4. Run checks: `composer test && composer analyse`
5. Commit your changes: `git commit -am 'Add some feature'`
6. Push to the branch: `git push origin feature/my-new-feature`
7. Submit a Pull Request

### Running Tests

[](#running-tests)

```
composer test
```

### Running Static Analysis

[](#running-static-analysis)

```
composer analyse
```

GitHub Actions now runs both PHPUnit and PHPStan as part of the default CI pipeline. The static analysis gate currently focuses on route files, notification delivery, and the `crowdsec:doctor` command to keep the check lightweight across the supported Laravel version matrix.

Security
--------

[](#security)

If you discover any security-related issues, please email the maintainer instead of opening an issue.

License
-------

[](#license)

This package is open-sourced software licensed under the [MIT license](LICENSE).

###  Health Score

41

—

FairBetter than 89% of packages

Maintenance90

Actively maintained with recent releases

Popularity11

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity47

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

Unknown

Total

1

Last Release

63d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/ce29bd3226e14d8e46d2bea171e71ff1ffa78616320570d81e21a9da440d2c94?d=identicon)[RiloArbabillah](/maintainers/RiloArbabillah)

---

Top Contributors

[![RiloArbabillah](https://avatars.githubusercontent.com/u/45306630?v=4)](https://github.com/RiloArbabillah "RiloArbabillah (53 commits)")

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/rilo-arbabillah-laravel-crowdsec/health.svg)

```
[![Health](https://phpackages.com/badges/rilo-arbabillah-laravel-crowdsec/health.svg)](https://phpackages.com/packages/rilo-arbabillah-laravel-crowdsec)
```

###  Alternatives

[larastan/larastan

Larastan - Discover bugs in your code without running it. A phpstan/phpstan extension for Laravel

6.4k43.5M5.2k](/packages/larastan-larastan)[laravel/passport

Laravel Passport provides OAuth2 server support to Laravel.

3.4k85.0M532](/packages/laravel-passport)[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-enum

Laravel Enum support

3655.4M31](/packages/spatie-laravel-enum)

PHPackages © 2026

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