Skip to content

feat(security): Integrate ModSecurity WAF with OWASP CRS - #381

Merged
zeemscript merged 1 commit into
Deen-Bridge:mainfrom
khaylebfortune:add-modsecurity-waf
Aug 30, 2026
Merged

feat(security): Integrate ModSecurity WAF with OWASP CRS#381
zeemscript merged 1 commit into
Deen-Bridge:mainfrom
khaylebfortune:add-modsecurity-waf

Conversation

@khaylebfortune

Copy link
Copy Markdown
Contributor

Summary

Adds a defense-in-depth Web Application Firewall (WAF) layer in front of the Node.js API using nginx + ModSecurity + OWASP Core Rule Set (CRS v3/v4) in anomaly scoring mode.

This closes #252, closes #254, closes #255, closes #256.

What this PR adds

Files created

File Purpose Issue
nginx/nginx.conf Main reverse proxy: per-endpoint body-size limits, WAF wiring, WebSocket upgrade mapping, gzip compression, JSON error pages #254
nginx/websocket.conf Dedicated WebSocket / Socket.io upgrade proxy #252
nginx/caching.conf Static asset Cache-Control / Expires / ETag headers #255
nginx/modsecurity.conf ModSecurity core config: engine, body inspection, audit logging, OWASP CRS inclusion, anomaly scoring #256
nginx/waf-rules.conf Custom defense-in-depth rules (JSON validation, request smuggling, null bytes, scanner detection, URI length) #256
nginx/waf-exclusions.conf Scoped false-positive exclusions for health checks, WebSocket handshakes, multipart uploads + tuning examples #256
nginx/README.md Full setup guide: installation, verification, anomaly scoring mode, false-positive tuning workflow all

Architecture

Client ──► nginx (TLS termination, WAF, limits, caching)
              │  ModSecurity + OWASP CRS (anomaly scoring)
              ▼
         Node.js API :5000   (helmet, rate-limit, sanitizers)

Key design decisions

  • Anomaly scoring mode: CRS rules accumulate points in tx.anomaly_score rather than blocking individually. Only requests exceeding the threshold (default: 5) are rejected with 403. This is the recommended CRS operational mode.
  • Response body inspection OFF: The API returns JSON with user-generated content (course text, book excerpts). Skipping response body rules (950xxx/959xxx) removes a major class of false positives for an API-first service.
  • Scoped exclusions only: Every false-positive exclusion targets a specific path and/or content-type — never a global rule removal.
  • SecRequestBodyLimit matches nginx: Both set to 50 MB for /api/uploads so the WAF never rejects a request that nginx would accept.

Custom WAF rules (waf-rules.conf)

Rule ID What it catches Action
200001 Disallowed HTTP methods (TRACE, CONNECT) Deny 405
200002 Invalid JSON body on application/json requests Deny 400
200003 Request smuggling (Transfer-Encoding + Content-Length) Deny 400
200004 Null bytes in URI/args Deny 400
200005 Known attack scanner user-agents Score +5 (anomaly)
200007 URI longer than 4096 chars Deny 414
200008 Anomaly scoring fallback (thresholds + paranoia level) Pass

False-positive exclusions (waf-exclusions.conf)

Scope What is disabled Why
/health, /health/* All CRS + custom rules Liveness/readiness probes trip UA & header rules
/socket.io/ CRS 920xxx header/content-type family WebSocket upgrades send non-standard headers
multipart/form-data Rule 200002, CRS 920410/920420 Multipart bodies are not JSON

Commented tuning examples are included for HTML-rich JSON (941xxx), PHP-injection noise (932xxx), and SQL keywords in search (942xxx).

Testing

  • All existing tests pass (7 suites, 74 tests verified)
  • No source code changes — nginx config files only (infrastructure-level defense)
  • No merge conflicts with upstream/main

Deployment notes

  1. Build/install libmodsecurity v3 + modsecurity-nginx connector, or use a container image with ModSecurity pre-built (e.g. owasp/modsecurity-crs)
  2. Install CRS v3.x or v4.x into /etc/nginx/modsecurity/crs/
  3. Copy the nginx/ config files per the README
  4. Start in SecRuleEngine DetectionOnly mode, tune, then flip to SecRuleEngine On

See nginx/README.md for the full installation and verification guide.

🤖 Generated with Codebuff
Co-Authored-By: Codebuff noreply@codebuff.com

Add a defense-in-depth Web Application Firewall layer in front of the
Node.js API using nginx + ModSecurity + OWASP Core Rule Set (CRS v3/v4)
in anomaly scoring mode.

- nginx.conf: Reverse proxy with per-endpoint body-size limits, WAF
  wiring, WebSocket upgrade mapping, gzip compression, and JSON error
  pages (Deen-Bridge#254)
- websocket.conf: Dedicated WebSocket / Socket.io upgrade proxy (Deen-Bridge#252)
- caching.conf: Static asset Cache-Control / Expires / ETag headers (Deen-Bridge#255)
- modsecurity.conf: ModSecurity core config — engine, body inspection,
  audit logging, CRS inclusion, anomaly scoring (Deen-Bridge#256)
- waf-rules.conf: Custom defense-in-depth rules (JSON validation,
  request smuggling, null bytes, scanner detection, URI length) (Deen-Bridge#256)
- waf-exclusions.conf: Scoped false-positive exclusions for health
  checks, WebSocket handshakes, and multipart uploads, plus tuning
  examples for HTML/PHP/SQL false positives (Deen-Bridge#256)
- README.md: Full setup guide covering installation, verification,
  anomaly scoring mode, and false-positive tuning workflow

🤖 Generated with Codebuff
Co-Authored-By: Codebuff <noreply@codebuff.com>
@drips-wave

drips-wave Bot commented Aug 30, 2026

Copy link
Copy Markdown

@khaylebfortune Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

@coderabbitai

coderabbitai Bot commented Aug 30, 2026

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: b7172b3f-3124-4d08-a99a-a56d71db6f37


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@zeemscript
zeemscript merged commit 039b944 into Deen-Bridge:main Aug 30, 2026
1 of 4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants