Phirewall
Phirewall is a PHP based application firewall that provides a PSR-15 middleware.
Install / Use
/learn @flowd/PhirewallREADME
Phirewall
<img src="docs/assets/logo.svg" width="200" alt="Phirewall Logo" align="right">Protect your PHP application from brute force, DDoS, SQL injection, XSS, and bot attacks with a single middleware.
Phirewall is a PSR-15 middleware that provides comprehensive application-layer protection. It's lightweight, framework-agnostic, and easy to configure.
Why Phirewall?
- Simple Setup - Add protection in minutes with sensible defaults
- Multiple Attack Vectors - Rate limiting, brute force protection, OWASP rules, bot detection
- Framework Agnostic - Works with any PSR-15 compatible framework (Laravel, Symfony, Slim, Mezzio, etc.)
- Production Ready - Redis support for multi-server deployments
- Observable - PSR-14 events for logging, metrics, and alerting
Quick Start
composer require flowd/phirewall
use Flowd\Phirewall\Config;
use Flowd\Phirewall\Middleware;
use Flowd\Phirewall\KeyExtractors;
use Flowd\Phirewall\Store\InMemoryCache;
// Create the firewall
$config = new Config(new InMemoryCache());
// Allow health checks to bypass all rules
$config->safelists->add('health', fn($req) => $req->getUri()->getPath() === '/health');
// Block common scanner paths
$config->blocklists->add('scanners', fn($req) => str_starts_with($req->getUri()->getPath(), '/wp-admin'));
// Rate limit: 100 requests per minute per IP
$config->throttles->add('api', limit: 100, period: 60 /* seconds */, key: KeyExtractors::ip());
// Ban IP after 5 failed logins in 5 minutes
$config->fail2ban->add('login', threshold: 5, period: 300 /* seconds */, ban: 3600 /* seconds */,
filter: fn($req) => $req->getHeaderLine('X-Login-Failed') === '1',
key: KeyExtractors::ip()
);
// Add to your middleware stack
$middleware = new Middleware($config);
// The PSR-17 ResponseFactory is optional — Phirewall auto-detects installed factories.
// Pass one explicitly if needed: new Middleware($config, new Psr17Factory())
Add the middleware to your PSR-15 pipeline. All requests will be evaluated against your rules before reaching your application.
Try It Now
Run one of the included examples to see Phirewall in action:
# Basic setup demo
php examples/01-basic-setup.php
# See brute force protection
php examples/02-brute-force-protection.php
# Test SQL injection blocking
php examples/04-sql-injection-blocking.php
# Full production setup
php examples/08-comprehensive-protection.php
Examples
The examples/ folder contains runnable examples:
| # | Example | Description | |---|---------|-------------| | 01 | basic-setup | Minimal configuration to get started | | 02 | brute-force-protection | Fail2Ban-style login protection | | 03 | api-rate-limiting | Tiered rate limits for APIs | | 04 | sql-injection-blocking | OWASP-style SQLi detection | | 05 | xss-prevention | Cross-Site Scripting protection | | 06 | bot-detection | Scanner and malicious bot blocking | | 07 | ip-blocklist | File-backed IP/CIDR blocklists | | 08 | comprehensive-protection | Production-ready multi-layer setup | | 09 | observability-monolog | Event logging with Monolog | | 10 | observability-opentelemetry | Distributed tracing with OpenTelemetry | | 11 | redis-storage | Redis backend for multi-server deployments | | 12 | apache-htaccess | Apache .htaccess IP blocking | | 13 | benchmarks | Storage backend performance comparison | | 14 | owasp-crs-files | Loading OWASP CRS rules from files | | 15 | in-memory-pattern-backend | Configuration-based CIDR/IP blocklists | | 16 | allow2ban | Hard volume cap with auto-ban | | 17 | known-scanners | Block known attack tools and vulnerability scanners | | 18 | trusted-bots | Trusted bot verification via reverse DNS | | 19 | header-analysis | Suspicious headers detection | | 20 | rule-benchmarks | Firewall rule performance benchmarks | | 21 | sliding-window | Sliding window rate limiting | | 22 | multi-throttle | Multi-window burst + sustained rate limiting | | 23 | dynamic-limits | Role-based dynamic throttle limits | | 24 | pdo-storage | PdoCache with SQLite, MySQL, PostgreSQL | | 25 | track-threshold | Track with optional threshold and thresholdReached flag | | 26 | psr17-factories | PSR-17 response factory integration | | 27 | request-context | RequestContext API for post-handler fail2ban signaling |
Features
Protection Layers
| Feature | Description | |---------|-------------| | Safelists | Bypass all checks for trusted requests (health checks, internal IPs) | | Blocklists | Immediately deny suspicious requests (403) | | Throttling | Fixed and sliding window rate limiting by IP, user, API key, or custom key (429) with dynamic limits and multiThrottle | | Fail2Ban | Auto-ban after repeated failures | | Allow2Ban | Hard volume cap -- ban after too many total requests | | Track with Threshold | Passive counting with optional alert threshold | | OWASP CRS | SQL injection, XSS, and PHP injection detection | | Pattern Backends | File/Redis-backed blocklists with IP, CIDR, path, and header patterns |
Matchers
| Matcher | Description | |---------|-------------| | Known Scanners | Block sqlmap, nikto, nmap, and other scanner User-Agents | | Trusted Bots | Safelist Googlebot, Bingbot, etc. via reverse DNS verification | | Suspicious Headers | Block requests missing standard browser headers | | IP Matcher | Safelist or block by IP/CIDR range |
Observability
- PSR-14 Events -
SafelistMatched,BlocklistMatched,ThrottleExceeded,Fail2BanBanned,Allow2BanBanned,TrackHit,FirewallError - Fail-Open by Default - Cache outages don't take down the application; errors dispatched via PSR-14
- Diagnostics Counters - Per-rule statistics for monitoring
- Standard Headers -
X-RateLimit-*,Retry-After,X-Phirewall-*
Storage Backends
| Backend | Use Case |
|---------|----------|
| InMemoryCache | Development, testing, single requests |
| ApcuCache | Single-server production |
| RedisCache | Multi-server production |
| PdoCache | SQL-backed persistence (MySQL, PostgreSQL, SQLite) |
Documentation
Full documentation is available at phirewall.de:
- Getting Started - Installation & quick start guide
- Framework Integration - PSR-15, Laravel, Symfony, Slim, Mezzio
- Features - Safelists, blocklists, rate limiting, fail2ban, bot detection, OWASP rules
- Advanced - Dynamic throttles, observability, infrastructure adapters
- Common Attacks - Protection recipes for 10+ attack types
- FAQ - Frequently asked questions
Installation
composer require flowd/phirewall
Optional Dependencies
# For Redis-backed distributed counters (multi-server)
composer require predis/predis
# For Monolog logging integration
composer require monolog/monolog
APCu: Enable the PHP extension and set apc.enable_cli=1 for CLI testing.
Response Headers
Phirewall can add diagnostic headers to the response when a request is blocked or safelisted. These diagnostic headers are opt-in and disabled by default:
$config->enableResponseHeaders(); // Enable X-Phirewall, X-Phirewall-Matched, and X-Phirewall-Safelist headers
| Header | Description | Opt-in required |
|--------|-------------|-----------------|
| X-Phirewall | Block type: blocklist, throttle, fail2ban, allow2ban | Yes |
| X-Phirewall-Matched | Rule name that triggered | Yes |
| X-Phirewall-Safelist | Safelist rule that matched (on allowed requests) | Yes |
| Retry-After | Seconds until the client may retry (throttles and allow2ban bans) | No (always present) |
Note:
Retry-Afteris always included on responses where a retry delay applies (429 throttles and allow2ban bans), regardless ofenableResponseHeaders().
Enable $config->enableRateLimitHeaders() for standard X-RateLimit-* headers.
Client IP Behind Proxies
When behind load balancers or CDNs, use TrustedProxyResolver:
use Flowd\Phirewall\Http\TrustedProxyResolver;
use Flowd\Phirewall\KeyExtractors;
$resolver = new TrustedProxyResolver([
'10.0.0.0/8', // Internal network
'172.16.0.0/12', // Docker
]);
$config->throttles->add('api', limit: 100, period: 60,
key: KeyExtractors::clientIp($resolver)
);
Custom Responses
Customize blocked responses while keeping standard headers:
use Flowd\Phirewall\Config\Response\ClosureBlocklistedResponseFactory;
use Flowd\Phirewall\Config\Response\ClosureThrottledResponseFactory;
$config->blocklistedResponseFactory = new ClosureBlocklistedResponseFactory(
function (string $rule, string $type, $req) {
return new Response(403, ['Content-Type' => 'applicati
Related Skills
node-connect
354.3kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
112.3kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
354.3kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
qqbot-media
354.3kQQBot 富媒体收发能力。使用 <qqmedia> 标签,系统根据文件扩展名自动识别类型(图片/语音/视频/文件)。
