Real-time security middleware for Node.js.
Detects and blocks SQL Injection, XSS, and NoSQL Injection before they reach the database, with intelligent Rate Limiting and automatic suspicious IP banning.
63/63 real HTTP tests passed · 66/66 unit tests passed · zero production dependencies
- Why Parry_DDoS?
- Features
- Installation
- Quick Start
- Full Configuration
- How It Works
- Project Structure
- Tests
- Response Headers
- SIEM and Alert Integration
- TypeScript
- Roadmap
- Contributing
- License
Most Node.js applications rely on validation at the route or ORM layer — which means malicious payloads reach application logic before hitting any barrier. Parry_DDoS acts before any route, like a gatekeeper at the request entry point.
- No malicious payload ever reaches the database.
- No extra production dependencies — pure Node.js native.
- Every threat is logged with IP, method, route, and affected field.
- IPs that repeatedly attempt attacks are automatically banned.
| Feature | Detail |
|---|---|
| SQL Injection | 13 patterns — UNION, OR/AND bypass, comments, SLEEP/BENCHMARK, DROP/ALTER, xp_cmdshell, information_schema, hex encoding, LOAD FILE |
| XSS | 15 patterns — <script>, inline event handlers, javascript:, vbscript:, data: URI, SVG injection, template injection (Angular/Vue/Handlebars), null-byte, autofocus+onfocus |
| NoSQL Injection | Dangerous MongoDB operators ($where, $expr, $function) and suspicious ones ($gt, $ne, $or, $regex etc.) in objects and JSON strings |
| Rate Limiting | Sliding window per IP with X-RateLimit-* headers |
| Intelligent Ban | Suspicious activity counter separate from volume — attacking IPs are banned before hitting the request limit |
| Multi-layer Decoding | URL decode (up to 3 passes), HTML entities, Unicode zero-width strip, before any scan |
onThreat Callback |
Hook for integration with SIEM, Slack, PagerDuty, DataDog, etc. |
| TypeScript | Full typings included in types/index.d.ts |
npm install express # only peer dependencyParry_DDoS has zero production dependencies.
expressis apeerDependency— if it's already in your project, nothing else to install.
const express = require('express');
const { Parry_DDoS } = require('./src/middleware');
const app = express();
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
// Apply before any route
app.use(Parry_DDoS());
app.post('/login', (req, res) => {
res.json({ ok: true });
});
app.listen(3000);With default settings, the middleware is fully operational. All detectors and rate limiting are enabled out of the box.
app.use(
Parry_DDoS({
// ── Detectors ───────────────────────────────────────────────
sql: true, // Enable SQL Injection detection
xss: true, // Enable XSS detection
nosql: true, // Enable NoSQL Injection detection
// ── Rate Limiting ───────────────────────────────────────────
rateLimit: true,
maxRequests: 100, // Max requests per window per IP
windowMs: 60_000, // Window duration in ms (default: 1 min)
// ── Intelligent Ban ─────────────────────────────────────────
suspiciousThreshold: 5, // Detected attacks before ban
banDurationMs: 300_000, // Ban duration in ms (default: 5 min)
// ── Logging ─────────────────────────────────────────────────
logThreats: true, // Display colored logs in the console
// ── Integration Hook ────────────────────────────────────────
onThreat(entry, req, res) {
// entry.type → 'THREAT' | 'BAN' | 'RATE_LIMIT'
// entry.ip → client IP
// entry.threats[] → [{ detector, field, pattern }]
// entry.method → 'POST', 'GET', etc.
// entry.url → affected route
},
})
);| Option | Default |
|---|---|
sql |
true |
xss |
true |
nosql |
true |
rateLimit |
true |
maxRequests |
100 |
windowMs |
60000 (1 min) |
suspiciousThreshold |
5 |
banDurationMs |
300000 (5 min) |
logThreats |
true |
maxObjectDepth |
5 |
Every request goes through the following pipeline before reaching any route:
Request
│
├─► [1] Rate Limit check ──────── 429 if exceeded or banned
│
├─► [2] Target collection
│ ├── query params
│ ├── body (recursive flatten up to maxObjectDepth)
│ ├── route params
│ └── sensitive headers (user-agent, referer, cookie, x-forwarded-for)
│
├─► [3] Multi-layer decoding per value
│ ├── URL decode (up to 3 passes — anti double-encoding)
│ ├── HTML entities (< & ' etc.)
│ └── Unicode zero-width strip
│
├─► [4] Parallel scan per detector
│ ├── SQLInjectionDetector.scan(value)
│ ├── XSSDetector.scan(value)
│ └── NoSQLDetector.scan(rawValue) ← receives object or string
│
├─► [5] Threat detected?
│ ├── YES → recordSuspicious(ip) · log · onThreat() · 400
│ └── NO → next()
│
└─► Application route
Parry_DDoS maintains two independent counters per IP:
IP: 203.0.113.42
├── timestamps[] → sliding window of normal requests
│ (blocked when > maxRequests)
└── suspicious → incremented on every detected attack
(banned when >= suspiciousThreshold)
This means a high-volume legitimate IP is not banned, while an IP making only 3 requests — all malicious — is banned immediately upon reaching the threshold.
The RateLimiter runs automatic cleanup every 10 minutes to prevent unbounded memory growth.
POST /api/users?search=<payload>
│
├── query.search ← query string
├── body ← root object (NoSQL top-level operators)
├── body.username ← direct fields
├── body.address.street ← nested fields (up to maxObjectDepth)
├── params.id ← route params
├── header.user-agent ← sensitive headers
├── header.referer
├── header.cookie
└── header.x-forwarded-for
Parry_DDoS/
│
├── src/
│ ├── middleware/
│ │ ├── parry_ddos.js ← Main orchestrator
│ │ └── index.js ← Barrel export
│ │
│ ├── detectors/
│ │ ├── sql.js ← SQL Injection detector
│ │ ├── xss.js ← XSS detector
│ │ ├── nosql.js ← NoSQL Injection detector
│ │ └── index.js ← Barrel export
│ │
│ └── core/
│ ├── rateLimiter.js ← Sliding-window rate limiter + ban
│ ├── logger.js ← Colored logger with timestamps
│ └── index.js ← Barrel export
│
├── config/
│ └── defaults.js ← Centralized default values
│
├── constants/
│ └── patterns.js ← All regex patterns in one place
│
├── types/
│ └── index.d.ts ← Public TypeScript typings
│
├── tests/
│ ├── unit/
│ │ ├── detectors.test.js ← Isolated tests per detector
│ │ └── rateLimiter.test.js ← RateLimiter tests
│ ├── integration/
│ │ └── middleware.test.js ← Middleware end-to-end with req/res mock
│ ├── fixtures/
│ │ └── payloads.js ← Reusable attack payloads across suites
│ └── index.js ← Aggregated test runner
│
├── scripts/
│ ├── test-server.js ← Express server for real HTTP tests
│ └── run-tests.js ← 63 HTTP test suite against the server
│
├── examples/
│ └── express-basic.js ← Full integration example
│
├── docs/
│ └── architecture.md ← Documented design decisions
│
└── package.json
Parry_DDoS has two independent test suites totalling 129 tests.
npm testCovers isolated detectors (SQL, XSS, NoSQL), the RateLimiter, and the middleware with req/res mocks. Runs in any environment, including CI.
▶ Unit — Detectors 32 tests
▶ Unit — RateLimiter 9 tests
▶ Integration — Middleware 25 tests
─────────────────────────────────────
Total 66 tests | 0 failures
# Terminal 1 — start the test server
npm run start:test
# Terminal 2 — run the HTTP tests
npm run test:httpCovers clean requests, all attack vectors in body/query/params/headers, X-RateLimit-* headers, window exhaustion, intelligent ban, and simultaneous multiple threats.
Sanity checks 2 tests
Clean requests 6 tests
SQL Injection 16 tests
XSS 12 tests
NoSQL Injection 12 tests
X-RateLimit Headers 5 tests
Volume Rate Limiting 3 tests
Intelligent Ban 3 tests
Multiple Threats 4 tests
─────────────────────────────────────────
Total 63 tests | 0 failures
Parry_DDoS injects the following headers into every response:
| Header | Description |
|---|---|
X-RateLimit-Limit |
Configured maximum requests |
X-RateLimit-Remaining |
Requests remaining in the current window |
X-RateLimit-Reset |
Window reset timestamp (ms) |
When a request is blocked, the response follows this format:
// 400 — threat detected
{
"error": true,
"message": "Request blocked: malicious pattern detected.",
"threats": [
{ "detector": "SQL_INJECTION", "field": "body.username" },
{ "detector": "XSS", "field": "body.comment" }
]
}
// 429 — rate limit or ban
{
"error": true,
"message": "Too many suspicious requests. IP temporarily banned.",
"banExpiresAt": 1712700000000
}Use the onThreat callback to forward events to any external system:
// Slack
Parry_DDoS({
onThreat(entry) {
fetch('https://hooks.slack.com/services/...', {
method: 'POST',
body: JSON.stringify({
text: `🚨 *${entry.threats[0].detector}* detected\nIP: ${entry.ip}\nRoute: ${entry.method} ${entry.url}`,
}),
});
},
});
// DataDog
Parry_DDoS({
onThreat(entry) {
dogstatsd.increment('parry_ddos.threat', 1, [`detector:${entry.threats[0].detector}`]);
},
});
// Structured log file (NDJSON)
const fs = require('fs');
Parry_DDoS({
logThreats: false, // disable console output, use callback only
onThreat(entry) {
fs.appendFileSync('threats.ndjson', JSON.stringify(entry) + '\n');
},
});Parry_DDoS includes full typings with no @types/* required:
import { Parry_DDoS, Parry_DDoSOptions, ThreatLogEntry } from './src/middleware';
const options: Parry_DDoSOptions = {
suspiciousThreshold: 3,
onThreat: (entry: ThreatLogEntry) => {
console.log(entry.threats);
},
};
app.use(Parry_DDoS(options));Exported types: Parry_DDoSOptions, ThreatLogEntry, ThreatMatch, RateLimitResult, IPSnapshot, DetectorType, LogEntryType, RateLimiter, SQLInjectionDetector, XSSDetector, NoSQLDetector.
Parry_DDoS is under active development. Upcoming versions will bring robust additions that expand protection beyond the middleware layer:
- CIDR verification for trusted proxies before accepting
X-Forwarded-For - Protection against Header Injection and HTTP Response Splitting
- Path Traversal detection (
../,%2e%2e%2f) in params and query - IP and route allowlist support for excluding specific paths from inspection
- Redis adapter for
RateLimiter— multi-instance and Kubernetes cluster support without state loss -
StorageAdapterinterface to plug in any backend (Memcached, DynamoDB, etc.) - Real-time ban synchronization across instances via Pub/Sub
- Token Bucket with per-route burst control
- Simultaneous connection flood detection per IP
- Request fingerprinting to identify bots even with rotating IPs
- Slowloris detection — blocking connections that deliberately delay data transmission
- Challenge-response (headless CAPTCHA) for IPs in the grey zone
- Official Docker image with built-in configuration server
- Helm chart for Kubernetes deployment as a sidecar or centralized gateway
- Standalone mode: Parry_DDoS as an independent reverse proxy, requiring no code-level integration in the application
- Web monitoring dashboard with real-time threat map, ban history, and per-detector metrics
- Metrics export in Prometheus/OpenTelemetry format
- Session-level behavioral analysis — detects attack patterns distributed over time (slow attacks)
- IP reputation model with automatic decay
- Integration with external threat intelligence feeds (AbuseIPDB, Spamhaus)
- Learning mode: collects legitimate traffic to automatically calibrate thresholds
Contributions are welcome. To get started:
git clone <repo>
cd Parry_DDoS
npm install express
# Run the tests before any changes
npm test
# For new detectors: add patterns to constants/patterns.js
# For new tests: add fixtures to tests/fixtures/payloads.jsWhen opening a PR, please include:
- Unit tests for the altered detector or module
- Updates to
types/index.d.tsif the public API changes - A
CHANGELOG.mdentry (if present)
MIT — see LICENSE for details.
