request-scanner
v0.1.5@backendkit-labs/request-scanner
Embedded WAF — blocks SQLi, XSS, NoSQL injection and more.
Overview#
A WAF (Web Application Firewall) typically runs at the reverse proxy layer (Cloudflare, AWS WAF, Nginx). But many environments — serverless, on-premise, platforms without WAF access — cannot rely on that layer. Even when available, fine-grained business rules often require decisions the proxy cannot make.
@backendkit-labs/request-scanner is an embedded WAF that runs inside your Node.js process, inspecting every request before it touches business logic. Two capabilities set it apart from simpler middleware:
- →Recursive deep scanning: inspects nested objects and arrays — not just top-level values.
- →Object key scanning: detects NoSQL injection via operator keys like { "$where": ... } or { "$ne": null } — not just values.
- →DoS protection: maxDepth (default 10) and maxStringLength (default 10000) caps prevent resource exhaustion from deeply-nested or oversized payloads.
- →SSRF rules are disabled by default to prevent false positives in apps that legitimately process URLs.
Detection Rules#
23 built-in rules across 6 categories. Each rule has a configurable severity (block, log-only, or disabled) per detection level.
| Prop | Type | Description |
|---|---|---|
| sql-001–004 | SQLi | UNION SELECT, DDL (DROP/TRUNCATE/ALTER), catalog enumeration, time-based blind (SLEEP/WAITFOR). |
| xss-001–002 | XSS | Script tag injection, dangerous URI schemes (javascript:, vbscript:). |
| pt-001–002 | Path Traversal | Directory traversal sequences (../ and ..\ variants), sensitive file path access. |
| nosql-001–003 | NoSQL | MongoDB operator injection ($where, $ne, $regex, $gt) — in both keys and values. |
| ssrf-001–003 | SSRF | Internal IP ranges, loopback addresses, cloud metadata endpoints. Disabled by default. |
| cmd-001–002 | Command Injection | Shell operator chaining (;, |, &&), system command patterns. |
Configuration#
npm install @backendkit-labs/request-scanner| Prop | Type | Description |
|---|---|---|
| level | 'permissive'|'standard'|'strict' | Detection sensitivity. 'strict' activates all 23 rules with zero tolerance. |
| allowList | string[] | Paths that bypass all scanning (e.g. trusted admin or webhook endpoints). |
| maxDepth | number | Maximum object nesting depth to scan. Deeper structures are truncated to prevent DoS. |
| maxStringLength | number | Maximum string length to scan. Longer strings are truncated. |
| customRules | Rule[] | Additional rules to run alongside the built-in set. |
| onThreat | (threat, req) => void | Callback invoked on every detected threat. Use for logging, metrics, or alerting. |
Environment variable overrides
WAF_ENABLED=true # globally enable/disable (default: true) WAF_SSRF_ENABLED=false # enable SSRF rules when you don't process URLs WAF_EXCLUDE_PATHS=/health,/metrics # comma-separated bypass paths
Express Middleware#
Call scanner.scan() with the request body, query, headers, and path. Returns an array of detected threats — an empty array means the request is clean.
NestJS Guard#
Extend ScannerGuard and implement getConfig(). Apply per-controller with @UseGuards(), globally in main.ts, or per-method with @UseWafPipe() for endpoint-level policies.
// Global — protects all routes const scanner = new RequestScanner({ level: 'standard' }); app.useGlobalGuards(new ScannerGuard(scanner)); // Per-route — stricter policy on sensitive endpoints @Post('search') @UseWafPipe({ level: 'strict', onThreat: (t) => metrics.increment('security.threat') }) async search(@Body() dto: SearchDto) { ... }
Examples#
From basic to production-grade — copy and adapt.
import { RequestScanner } from '@backendkit-labs/request-scanner'; const scanner = new RequestScanner({ level: 'strict', allowList: ['/admin/raw-query'], }); app.use((req, res, next) => { const threats = scanner.scan({ body: req.body, query: req.query, headers: req.headers, path: req.path, }); if (threats.length > 0) { return res.status(403).json({ error: 'Blocked', rule: threats[0].ruleId }); } next(); });
⚖️ vs. Alternatives#
Comparing against helmet (HTTP security headers) and express-validator — the most common security middleware in Express apps.
| Feature | @backendkit-labs/request-scanner | helmet | express-validator |
|---|---|---|---|
| SQL injection detection | ✅ Pattern-based | ❌ Headers only | ❌ Schema only |
| XSS detection | ✅ Body/query/headers | ✅ CSP headers | ❌ |
| SSRF detection | ✅ | ❌ | ❌ |
| NoSQL injection | ✅ | ❌ | ❌ |
| Command injection | ✅ | ❌ | ❌ |
| Path traversal | ✅ | ❌ | ❌ |
| Request body scanning | ✅ | ❌ | ✅ Schema validation |
| NestJS guard | ✅ | ❌ | ❌ |
| Configurable severity | ✅ permissive/standard/strict | ❌ | ❌ |
| Custom rules | ✅ | ❌ | ⚠️ Custom validators |
| Allow list | ✅ Per-path | ❌ | ❌ |
| Zero runtime deps | ✅ | ✅ | ✅ |
✅ Supported · ❌ Not supported · ⚠️ Partial / workaround needed. Download counts are approximate weekly npm averages.