@chiranthmoger/fortifyjs
v1.1.3
Published
Zero-dependency Web Application Firewall and AI Security Suite for Node.js. One-line protection against injection, XSS, CSRF, SSRF, prompt injection, and 15 attack classes. Replaces helmet, cors, csurf, and express-rate-limit.
Maintainers
Readme
FortifyJS
Zero-Dependency Web Application Firewall and AI Security Suite for Node.js
One-line protection against injection, XSS, CSRF, SSRF, prompt injection, and 15 attack classes. Replaces helmet, cors, csurf, express-rate-limit, and legacy sanitizers with zero external dependencies.
Table of Contents
- Overview
- Why FortifyJS
- Empirical Benchmarks (2,142 Samples)
- Quick Start
- 15-Vector Attack Arsenal Matrix
- AI and LLM Prompt Protection
- Runtime Sink Guardrails
- Protection Tiers
- Framework Compatibility Matrix
- Mass-Assignment and Parameter Sanitization
- Offline CLI Testing
- Contributing and License
Overview
FortifyJS is an in-process security engine for modern Node.js and TypeScript web applications. It inspects incoming HTTP requests, parameters, query strings, headers, and request bodies across 15 distinct vulnerability classes in sub-millisecond execution time.
Unlike traditional cloud WAFs that sit outside your infrastructure, FortifyJS executes directly inside your application runtime. This enables deep structural inspection of parsed JSON trees, exact execution sink protection, and native AI/LLM prompt validation without adding network hops or third-party dependencies.
Why FortifyJS
Securing a Node.js backend typically requires maintaining multiple separate packages, managing conflicting configurations, and writing custom defenses for modern vectors such as Server-Side Request Forgery (SSRF) and GenAI prompt injections.
FortifyJS replaces fragmented security dependencies with a single unified framework.
Solution Comparison Matrix
| Feature / Dimension | FortifyJS | Legacy Node Packages | Cloud WAF (Cloudflare/AWS) | AI-Only Guardrails |
| :--- | :--- | :--- | :--- | :--- |
| External Dependencies | 0 (Zero) | 6 to 10 packages | N/A (Cloud proxy) | Heavy (Python/Model weights) |
| Inspection Latency | < 0.07 ms (Fast-path < 0.005 ms) | 2 to 8 ms (Combined) | 15 to 50 ms (Network hop) | 100 to 500 ms (LLM inference) |
| AI Prompt Injection Guard | Built-in (llmGuard) | None | Limited / Cost add-on | Yes |
| Traditional WAF (15 Vectors)| Built-in | Fragmented | Yes | None |
| Runtime Sink Guardrails | Built-in (assertSafe*) | None | None (Edge proxy blind to sinks) | None |
| SSRF Bitwise CIDR Validation | Built-in (RFC subnets & metadata)| None (Requires custom DNS code) | Partial | None |
| Deep JSON Tree Inspection | Built-in (Non-recursive stack) | None | Partial | None |
| Framework Portability | Express, Fastify, Next.js, Hono, Koa, NestJS | Express only | Protocol level | API level |
| Cloud & Vendor Lock-In | None (Runs in-process) | None | Vendor locked | Model locked |
Legacy Package Replacement
| Legacy Package | FortifyJS Built-In Equivalent | Performance Advantage |
| :--- | :--- | :--- |
| helmet | Security Headers Shield | Zero dependencies, uniform policy configuration |
| cors | CORS Shield | Dynamic origin resolution, regex matching, credential isolation |
| csurf | CSRF Shield | Double-submit cookie pattern with constant-time comparison |
| express-rate-limit | Distributed / Memory Rate Limiter | In-process bounded MemoryStore with pluggable Redis/KV stores |
| express-mongo-sanitize | NoSQLi Detector & Sanitizer | Recursive object tree inspection covering Mongo, Couch, and Elasticsearch |
| xss-clean | Multi-Vector XSS Detector | Context-aware HTML attribute, SVG, and DOM protocol sink inspection |
| Custom LLM regexes | AI Prompt Guard (llmGuard) | Multilingual instruction override, role isolation, and delimiter defense |
Empirical Benchmarks (2,142 Samples)
FortifyJS has been tested against real-world adversarial payloads and benign application traffic across industry-standard corpora:
- OWASP ModSecurity Core Rule Set (CRS) v4.0.0: 12 regression test suites covering SQLi, XSS, Path Traversal, and RCE.
- PayloadsAllTheThings: 10 attack suites covering SQLi Auth Bypass, XSS (JHaddix), Command Execution, Path Traversal, NoSQL Injection, SSRF, XXE, CRLF, SSTI, and Open Redirect.
- HarmBench Red-Team Dataset: Multilingual jailbreaks and instruction override attempts.
- ChatGPT DAN Corpus: Roleplay and prompt escape vectors (DAN 12.0, STAN, DUDE).
- Big List of Naughty Strings (BLNS): Boundary testing and format string fuzzing.
- Real-World Synthetic Traffic: 500 clean production payloads evaluating false-positive rates.
Measured Evidence Summary
| Benchmark Metric | Measured Result | Significance | | :--- | :--- | :--- | | Total Samples Evaluated | 2,142 | Comprehensive multi-suite test harness | | Adversarial Attacks Evaluated | 1,333 | Zero-day, polyglot, and evasive payloads | | Benign Samples Evaluated | 809 | Production JSON payloads, queries, and stress inputs | | Recall (Detection Rate) | 98.95% (1,319 / 1,333) | Stoppage of known and novel attack vectors | | Specificity (Benign Clearance) | 98.27% (795 / 809) | Reliable throughput for legitimate traffic | | False Positive Rate (FPR) | 1.73% | Minimal benign alarms on complex input strings | | Precision | 98.95% | High operational accuracy | | F1-Score | 0.9895 | Balanced harmonic precision and recall | | p50 Latency | 0.0636 ms (63.6 μs) | Sub-millisecond pipeline latency | | p90 Latency | 0.1715 ms (171.5 μs) | Predictable tail performance under load | | p99 Latency | 0.8665 ms (866.5 μs) | Sub-millisecond worst-case latency | | Core Throughput | 15,723 req/sec/core | Single CPU core capacity without GPU acceleration |
Dataset Breakdown
| Dataset | Type | Samples | Detection Accuracy | | :--- | :--- | :--- | :--- | | OWASP CRS SQLi Regression (Rule 942100) | Adversarial | 17 | 100.0% | | OWASP CRS SQLi Regression (Rule 942120) | Adversarial | 42 | 100.0% | | OWASP CRS SQLi Regression (Rule 942120) [Negative Test] | Benign | 3 | 66.7% | | OWASP CRS SQLi Regression (Rule 942130) | Adversarial | 6 | 100.0% | | OWASP CRS SQLi Regression (Rule 942130) [Negative Test] | Benign | 5 | 100.0% | | OWASP CRS XSS Regression (Rule 941100) | Adversarial | 6 | 100.0% | | OWASP CRS XSS Regression (Rule 941110) | Adversarial | 5 | 100.0% | | OWASP CRS XSS Regression (Rule 941110) [Negative Test] | Benign | 1 | 100.0% | | OWASP CRS XSS Regression (Rule 941120) | Adversarial | 6 | 100.0% | | OWASP CRS XSS Regression (Rule 941120) [Negative Test] | Benign | 17 | 100.0% | | OWASP CRS XSS Regression (Rule 941130) | Adversarial | 19 | 100.0% | | OWASP CRS XSS Regression (Rule 941130) [Negative Test] | Benign | 2 | 100.0% | | OWASP CRS LFI / Path Traversal (Rule 930100) | Adversarial | 3 | 100.0% | | OWASP CRS LFI / Path Traversal (Rule 930110) | Adversarial | 8 | 100.0% | | OWASP CRS LFI / Path Traversal (Rule 930110) [Negative Test] | Benign | 4 | 75.0% | | OWASP CRS LFI / Path Traversal (Rule 930120) | Adversarial | 14 | 100.0% | | OWASP CRS LFI / Path Traversal (Rule 930120) [Negative Test] | Benign | 4 | 100.0% | | OWASP CRS LFI / Path Traversal (Rule 930130) | Adversarial | 11 | 100.0% | | OWASP CRS LFI / Path Traversal (Rule 930130) [Negative Test] | Benign | 4 | 100.0% | | OWASP CRS RCE / Command Injection (Rule 934100) | Adversarial | 28 | 100.0% | | OWASP CRS RCE / Command Injection (Rule 934100) [Negative Test] | Benign | 2 | 100.0% | | PayloadsAllTheThings SQLi Auth Bypass Suite | Adversarial | 78 | 100.0% | | PayloadsAllTheThings XSS Vector Suite (JHaddix) | Adversarial | 110 | 100.0% | | PayloadsAllTheThings Unix Command Execution | Adversarial | 83 | 100.0% | | PayloadsAllTheThings Path Traversal | Adversarial | 140 | 100.0% | | PayloadsAllTheThings NoSQL Injection Suite | Adversarial | 26 | 100.0% | | PayloadsAllTheThings SSRF Vectors | Adversarial | 48 | 100.0% | | PayloadsAllTheThings XML External Entity (XXE) | Adversarial | 15 | 100.0% | | PayloadsAllTheThings CRLF Injection Suite | Adversarial | 15 | 100.0% | | PayloadsAllTheThings Server-Side Template Injection (SSTI) | Adversarial | 18 | 100.0% | | PayloadsAllTheThings Open Redirect Vectors | Adversarial | 23 | 100.0% | | HarmBench Red-Team Jailbreak Dataset | Adversarial | 350 | 100.0% | | ChatGPT DAN & Roleplay Jailbreak Prompts | Adversarial | 15 | 93.3% | | Real-World Benign Application Traffic | Benign | 500 | 100.0% | | Big List of Naughty Strings (Exploits) | Adversarial | 247 | 94.7% | | Big List of Naughty Strings (Benign Stress) | Benign | 267 | 95.5% |
Quick Start
Installation
npm install @chiranthmoger/fortifyjsExpress (One-Line Setup)
const express = require('express');
const { shield } = require('fortifyjs');
const app = express();
app.use(express.json());
// Activates WAF, Rate Limiting, CORS, CSRF, and Security Headers
app.use(shield('medium'));
app.get('/api/users', (req, res) => {
res.json({ message: 'Request passed security checks' });
});
app.listen(3000);Fastify
const fastify = require('fastify')();
const { fastifyPlugin } = require('fortifyjs/adapters/fastify');
fastify.register(fastifyPlugin, { tier: 'medium' });
fastify.get('/api/data', async (request, reply) => {
return { status: 'secure' };
});
fastify.listen({ port: 3000 });Next.js (App Router and Edge Middleware)
import nextjsAdapter from 'fortifyjs/adapters/nextjs';
export async function middleware(request) {
const verdict = await nextjsAdapter(request, { tier: 'medium' });
if (!verdict.safe) {
return new Response(JSON.stringify({ error: verdict.error }), {
status: 403,
headers: { 'Content-Type': 'application/json' }
});
}
}Hono
import { Hono } from 'hono';
import { honoMiddleware } from 'fortifyjs/adapters/hono';
const app = new Hono();
app.use('*', honoMiddleware({ tier: 'medium' }));
app.get('/', (c) => c.text('Protected'));
export default app;15-Vector Attack Arsenal Matrix
FortifyJS actively monitors and blocks threats across 15 attack classes:
| Vector | Attack Class | Target Description | Detection Strategy | Protection Layer |
| :--- | :--- | :--- | :--- | :--- |
| SQLi | SQL Injection | Tautologies (OR 1=1), UNION queries, comment breakouts, stacked statements | Structural token parser and boolean expression tree analysis | WAF & assertSafeSqlQuery |
| XSS | Cross-Site Scripting | Stored, reflected, DOM sinks, SVG events, JavaScript schemes | Context-aware HTML attribute scanner and URI protocol guards | WAF & Normalizer |
| NoSQLi | NoSQL Injection | MongoDB operator injections ($where, $regex, $ne, $gt) | Operator denylist and non-recursive JSON key/value inspection | WAF & assertSafeNoSql |
| CmdI | Command Injection | Shell metacharacters (;, \|, &, backticks), subshell expansions, PowerShell | Binary denylist and command chaining heuristics | WAF & assertSafeCommand |
| Path | Path Traversal | Directory escapes (../), overlong UTF-8, null byte terminations | Lexical root boundary check and canonical path resolution | WAF & assertSafePath |
| SSRF | Server-Side Forgery | Cloud metadata (169.254.169.254, metadata.goog), loopbacks, decimal/octal IPs | Bitwise CIDR calculator, DNS rebinding guards, OAST detection | WAF & assertSafeUrl |
| AI/LLM | Prompt Injection | DAN jailbreaks, system prompt exfiltration, delimiter escapes | Multilingual instruction override classifier and role isolation | llmGuard & assertSafePrompt |
| XXE | XML Entity Injection | External entity definitions, parameter entities, billion laughs bomb | DTD entity scanner and XML expansion depth check | WAF Parser |
| Proto | Prototype Pollution | __proto__, constructor.prototype object pollution | Non-recursive object key validation and prototype freeze guards | WAF & sanitizeObject |
| HPP | Parameter Pollution | Split query parameters intended to bypass validation rules | Array normalization and duplicate query key rejection | Adapter Engine |
| Redir | Open Redirect | Protocol-relative destinations (//evil.com), credential confusion (user@host) | Hostname whitelist enforcement and URL structure verification | assertSafeRedirect |
| CRLF | Response Splitting | \r\n carriage return sequences injected into headers | Header delimiter sanitization and boundary check | Security Headers Shield |
| SSTI | Template Injection | FreeMarker, Jinja2, Twig expressions ({{7*7}}, ${...}) | Template reflection execution and arithmetic multiplier detection | WAF Engine |
| LDAP | LDAP Injection | Logical filter escapes ()(|), wildcard harvesting (objectClass=*) | RFC 4515 LDAP filter parser | WAF Engine |
| GQL | GraphQL Abuse | Introspection dumps, recursive circular queries, alias batching | Query depth analyzer and complexity limits | WAF Engine |
AI and LLM Prompt Protection
FortifyJS includes dedicated guardrails designed for applications integrating LLMs (OpenAI, Anthropic, Gemini, local Ollama):
1. LLM Route Middleware (llmGuard)
Mount llmGuard() directly onto generation or chat endpoints to inspect prompts before model execution:
const express = require('express');
const { llmGuard } = require('fortifyjs');
const app = express();
app.use(express.json());
// Protect chat route
app.post('/api/chat', llmGuard(), (req, res) => {
const userPrompt = req.body.prompt;
res.json({ reply: 'Processed safely' });
});2. Programmatic Prompt Verification
const { assertSafePrompt, scanPrompt } = require('fortifyjs');
// 1. Detailed inspection verdict
const verdict = scanPrompt(userInput);
console.log(verdict.safe); // true or false
console.log(verdict.confidence); // 0.0 to 1.0
console.log(verdict.matches); // Array of matched heuristics
// 2. Guardrail assertion (throws FortifyPromptError if malicious)
assertSafePrompt(userInput);3. Comprehensive GenAI Defense Capabilities
- System Prompt Role Isolation: Inspects user input independently of system instructions to prevent accidental self-flagging.
- RAG Context Scanning:
scanRagContext()evaluates external vector store chunks before inserting them into prompts. - Agent Tool Call Validation:
guardToolCall()inspects parameters passed into tool functions (such as SQL queries or file paths). - Model Output Inspection:
scanModelOutput()scans generated text for leaked API tokens, PII, or raw shellcode.
Runtime Sink Guardrails
Defense-in-depth requires validating values at the exact execution sink to prevent second-order attacks:
| Guardrail Function | Target Operation | Defense Strategy | Default Action |
| :--- | :--- | :--- | :--- |
| assertSafeCommand | OS Execution (child_process.exec) | Denies shell operators, subshells, and dangerous binaries | Rejects command |
| assertSafePath | Filesystem IO (fs.readFile) | Enforces directory boundary containment via path.resolve | Confines to root |
| assertSafeUrl | Network Calls (fetch, axios) | Bitwise CIDR check against private, loopback, and metadata IPs | Rejects private IPs |
| assertSafeSqlQuery | Database Queries (db.query) | AST structural parser preventing tautologies and stacked queries | Rejects query |
| assertSafeNoSql | Document Queries (collection.find) | Deep object walk stripping unauthorized $ operators | Strips operators |
| assertSafeRedirect | HTTP Redirects (res.redirect) | Validates target host against whitelist | Blocks foreign hosts |
| assertSafePrompt | LLM Generations | Detects instruction overrides and jailbreaks | Rejects prompt |
Code Example
const {
assertSafeCommand,
assertSafePath,
assertSafeUrl,
assertSafeSqlQuery,
assertSafeRedirect
} = require('fortifyjs');
// 1. Validate shell command
assertSafeCommand(req.body.cmd);
// 2. Confine file downloads to a safe directory
const safeFilePath = assertSafePath(req.query.file, { rootDir: '/var/www/uploads' });
// 3. Block SSRF to internal services or cloud metadata
assertSafeUrl(req.body.webhookUrl, { allowPrivate: false });
// 4. Validate raw dynamic SQL
assertSafeSqlQuery(req.body.query);
// 5. Prevent open redirect
assertSafeRedirect(req.query.next, { allowedHosts: ['myapp.com'] });Protection Tiers
FortifyJS provides four pre-configured security tiers:
| Feature / Shield | basic | medium | hard | advanced |
| :--- | :--- | :--- | :--- | :--- |
| Detection Threshold | Balanced (0.50) | Balanced (0.50) | Strict (0.25) | Strict (0.25) |
| Security Headers | Standard | Standard | Strict CSP + HSTS | Strict CSP + HSTS |
| Rate Limiting | 100 req / 15 min | 200 req / 15 min | 100 req / 15 min | 100 req / 15 min |
| CORS Policy | Same-Origin | Same-Origin | Strict Whitelist | Strict Whitelist |
| CSRF Protection | Disabled | Disabled | Enabled (Double-Submit) | Enabled (Double-Submit) |
| Bot Protection | Monitor | Block Bad Bots | Block Bad Bots | Adaptive Fingerprint |
| Behavioral Profiler | Entropy Check | Anomaly Scoring | Anomaly Scoring | Anomaly Scoring |
| File Upload Shield | Disabled | Extension Whitelist | Extension + MIME | Deep Scan + MIME |
| Threat Dashboard | Disabled | Disabled | Disabled | Enabled (/admin/security) |
Framework Compatibility Matrix
| Framework | Import Path | Setup Style | Runtime Target |
| :--- | :--- | :--- | :--- |
| Express | require('fortifyjs') | app.use(shield('medium')) | Node.js |
| Fastify | require('fortifyjs/adapters/fastify') | fastify.register(fastifyPlugin) | Node.js |
| Next.js | import nextjsAdapter from 'fortifyjs/adapters/nextjs' | Edge / Route Middleware | Node.js, Vercel Edge |
| Hono | import { honoMiddleware } from 'fortifyjs/adapters/hono' | app.use('*', honoMiddleware()) | Node.js, Bun, Cloudflare |
| Koa | const { koaMiddleware } = require('fortifyjs/adapters/koa') | app.use(koaMiddleware()) | Node.js |
| NestJS | import { FortifyGuard } from 'fortifyjs/adapters/nestjs' | @UseGuards(FortifyGuard) | Node.js |
Mass-Assignment and Parameter Sanitization
Protect application state by stripping or rejecting unauthorized object properties:
const { shield, sanitizeObject } = require('fortifyjs');
// 1. Automatic middleware sanitization
app.use(shield('medium', {
sanitize: {
stripFields: ['isAdmin', 'role', 'permissions', 'balance'],
rejectOnForbidden: false // Set true to return 400 Bad Request
}
}));
// 2. Programmatic utility
const { sanitized, strippedKeys } = sanitizeObject(req.body, {
stripFields: ['isAdmin', 'role']
});Offline CLI Testing
FortifyJS includes a standalone command-line tool for offline evaluations, CI/CD security quality gates, and local verification:
# Scan a single payload string
fortifyjs scan "1' UNION SELECT username, password FROM users--"
# Scan a file of test payloads with CSV reporting
fortifyjs scan-file ./test-payloads.txt --format csvContributing and License
- Contributions are welcome. Review CONTRIBUTING.md for testing guidelines.
- To report security vulnerabilities, review SECURITY.md.
- Distributed under the MIT License.
