# Synapse WAF PoC
A proof-of-concept integrating the **real Synapse WAF detection engine** (237 production rules) with Cloudflare's [Pingora](https://github.com/cloudflare/pingora) proxy framework. **Pure Rust, no Node.js, no FFI boundary**.
## Performance Headlines
| **Clean GET** | **~10 μs** |
| **Attack detection** | **~25 μs** avg across all vectors |
| **Full pipeline (WAF + DLP, 4 KB)** | **~247 μs** |
| Rules loaded | **237** production rules |
| Benchmark suites | **19** suites, **306** benchmarks |
| vs NAPI (Node.js FFI) | **~2-3x faster** |
| vs ModSecurity | **4-19x faster** |
> **Note**: February 2026 Criterion.rs numbers on macOS arm64. See
> [`docs/performance/BENCHMARK_REPORT_2026_02.md`](docs/performance/BENCHMARK_REPORT_2026_02.md) for the full report.
## Architecture
### Pingora Approach (This PoC)
```mermaid
flowchart LR
Client -->|request| SP["Synapse WAF<br/><b>Single Binary</b>"]
SP -->|proxy| Backend[Backend Server]
Backend -->|response| SP
SP -->|response| Client
subgraph SP_inner [" "]
direction TB
Engine["libsynapse (in-proc)<br/>237 Rules · Entity Tracking · Risk Scoring"]
end
style SP fill:#1e40af,color:#fff
style Engine fill:#2563eb,color:#fff
style Client fill:#f8fafc,stroke:#334155
style Backend fill:#f8fafc,stroke:#334155
```
### Current Approach (nginx + Node.js)
```mermaid
flowchart LR
Client -->|request| Nginx[nginx]
Nginx -->|subrequest| RS["risk-server<br/>(Node.js)"]
RS -->|verdict| Nginx
Nginx -->|proxy| Backend[Backend Server]
RS --- NAPI["NAPI Bridge"]
NAPI --- Lib["libsynapse<br/>(Rust FFI)"]
style Nginx fill:#dc2626,color:#fff
style RS fill:#dc2626,color:#fff
style NAPI fill:#b91c1c,color:#fff
style Lib fill:#991b1b,color:#fff
style Client fill:#f8fafc,stroke:#334155
style Backend fill:#f8fafc,stroke:#334155
```
> **3 components + FFI overhead** vs a single Rust binary.
**Key difference**: Detection happens *inside* the proxy, not across a process boundary.
## Quick Start
```bash
# Build release binary
cargo build --release
# Run (uses default config)
./target/release/synapse-waf
# Run with interactive TUI dashboard
./target/release/synapse-waf --tui
# Or with config file
cp config.example.yaml config.yaml
./target/release/synapse-waf
# Run integration tests
./test.sh
```
## Benchmark Results (February 2026)
Criterion.rs results from 19 benchmark suites (306 benchmarks), release build with LTO:
### Detection Engine
| **Simple GET** | **10.0 μs** | Minimal GET, no params |
| **SQLi detection** | **26.6 μs** | Average across 5 SQLi variants |
| **XSS detection** | **23.3 μs** | Average across 3 XSS variants |
| **Evasive attacks** | **25-33 μs** | Hex, double-encoding, unicode, polyglot |
| **Full rule set (237)** | **71.6 μs** | Linear scaling, ~302 ns/rule |
### Per-Request Hot Path
| Rate limit check | 61 ns |
| ACL evaluation (100 rules) | 156 ns |
| Trap matching (honeypot) | 33 ns |
| Actor is-blocked check | 45 ns |
| Session validation | 304 ns |
### End-to-End Pipeline
| Clean GET, full chain | 72 μs |
| WAF + DLP (4 KB body) | 247 μs |
| WAF + DLP (8 KB body) | 442 μs |
| E-commerce order (heavy) | 1.6 ms |
| Healthcare claim (PII + DLP) | 2.3 ms |
### Comparison
| **Synapse WAF** | **~10-25 μs** | Pure Rust, no FFI boundary |
| libsynapse (NAPI) | ~62-73 μs | Node.js + Rust FFI overhead |
| ModSecurity | 100-500 μs | Depends on ruleset |
| AWS WAF | 50-200 μs | Cloud service |
### Value Proposition
Pingora eliminates the **~47 μs FFI overhead** (73 μs NAPI vs 25 μs pure Rust), providing
a **~2-3x speedup** over the Node.js architecture:
1. **Simpler architecture** - Single Rust binary vs nginx + Node.js + NAPI stack
2. **No serialization boundary** - Detection runs in-process, no IPC
3. **No GC pauses** - No V8 heap, predictable latency
4. **Graceful reload** - Zero-downtime updates via SIGQUIT + socket handoff
5. **Thread-local engines** - Each Pingora worker has its own Synapse instance
| Per-request latency | ~73 μs | ~25 μs | **~3x faster** |
| Components to deploy | 3 (nginx, Node.js, NAPI) | 1 binary | **Simpler** |
| Memory footprint | Node.js + V8 heap | Rust only | **~50% smaller** |
| Cold start | Seconds (V8 init) | Milliseconds | **Much faster** |
| Config reload | Service restart | 240 μs hot reload | **Zero downtime** |
## Configuration
Copy `config.example.yaml` to `config.yaml`:
```yaml
# Server settings (flat fields on GlobalConfig)
http_addr: "0.0.0.0:80"
https_addr: "0.0.0.0:443"
workers: 0 # 0 = auto-detect CPU count
shutdown_timeout_secs: 30
waf_threshold: 70 # Global risk threshold (0-100)
waf_enabled: true
log_level: "info" # trace, debug, info, warn, error
waf_regex_timeout_ms: 100 # ReDoS protection (max 500)
# admin_api_key: "..." # Optional; random key generated if unset
# Upstream backends (round-robin)
upstreams:
- host: "127.0.0.1"
port: 8080
# Rate limiting
rate_limit:
rps: 10000
enabled: true
# Detection toggles
detection:
sqli: true
xss: true
path_traversal: true
command_injection: true
action: "block" # block, log, challenge
block_status: 403
```
See [`docs/reference/configuration.md`](docs/reference/configuration.md) for the full reference.
## Pingora Hooks Used
| `early_request_filter` | Rate limiting (pre-TLS) |
| `request_filter` | Attack detection (main filter) |
| `request_body_filter` | DLP body inspection (PII/sensitive data scanning) |
| `upstream_peer` | Round-robin backend selection |
| `upstream_request_filter` | Add `X-Synapse-*` headers |
| `logging` | Access logs with timing |
## Integration Tests
Run the test script to verify everything works:
```bash
# With proxy already running
./test.sh
# Or start proxy, run tests, stop proxy
./test.sh --start
```
Sample output:
```
============================================
Synapse WAF Integration Tests
============================================
[INFO] Testing clean requests (should PASS)...
[PASS] Simple GET / (502 - allowed)
[PASS] API endpoint (502 - allowed)
...
[INFO] Testing SQL injection (should BLOCK)...
[PASS] SQLi: OR condition (403) - 2ms
[PASS] SQLi: UNION SELECT (403) - 1ms
...
============================================
Results: 23/23 passed
============================================
All tests passed!
```
## Configuration Hot-Reload
Synapse supports zero-downtime configuration updates via the admin API:
```bash
# Reload configuration (~240 μs atomic swap, no dropped requests)
curl -X POST http://localhost:6191/reload -H "X-Admin-Key: $ADMIN_KEY"
```
How it works:
1. New config is parsed and validated
2. Routing table and WAF rules are rebuilt
3. Atomic `RwLock` swap replaces the live config
4. In-flight requests continue unaffected
## Graceful Shutdown
The process handles `SIGQUIT`, `SIGTERM`, and `SIGINT` for graceful shutdown:
1. Signal received — stop accepting new connections
2. In-flight requests are allowed to complete (draining)
3. Process exits when all connections are closed
## Building
```bash
# Development build
cargo build
# Release build (optimized)
cargo build --release
# With full optimizations (LTO + native CPU)
RUSTFLAGS="-C target-cpu=native" cargo build --release
# Run tests
cargo test
# Run benchmarks
cargo bench
```
## Example Usage
### Clean Request (Allowed)
```bash
curl -v http://localhost:6190/api/users/123
# → Proxied to backend
# → X-Synapse-Analyzed: true
# → X-Synapse-Detection-Time-Us: 1
```
### SQL Injection (Blocked)
```bash
curl -v "http://localhost:6190/api/users?id=1'+OR+'1'%3D'1"
# → HTTP 403 Forbidden
# → {"error": "blocked", "reason": "sqli"}
```
### XSS (Blocked)
```bash
curl -v "http://localhost:6190/search?q=%3Cscript%3Ealert(1)%3C/script%3E"
# → HTTP 403 Forbidden
# → {"error": "blocked", "reason": "xss"}
```
### POST with Body
```bash
curl -v -X POST -d '{"user":"test"}' http://localhost:6190/api/users
# Body size logged: "Request body complete: 15 bytes"
```
## Upstream Headers
The proxy adds these headers to upstream requests:
| `X-Synapse-Analyzed` | Always "true" |
| `X-Synapse-Detection-Time-Us` | Detection time in microseconds |
| `X-Synapse-Client-IP` | Client IP (from X-Forwarded-For or connection) |
## Detection Engine
This PoC uses the **real libsynapse engine** from `../risk-server/libsynapse/`, which includes:
- **237 production rules** covering SQLi, XSS, path traversal, command injection, and more
- **Behavioral tracking** - Entity risk accumulates across requests from the same IP
- **Risk scoring** - Graduated risk levels (0-100) with configurable blocking thresholds
- **Rule chaining** - Multiple rules can match and contribute to overall risk
### Verified Detections
Tested and verified to block:
- `UNION SELECT` SQLi attacks (rule 200200)
- Path traversal attempts (rules 200014, 200016)
- Various other attack patterns from the production rule set
### Rules Loading
Rules are loaded at startup from (in order of preference):
1. `../risk-server/libsynapse/rules.json` (production rules)
2. `rules.json` (local override)
3. `/etc/synapse-pingora/rules.json` (system-wide)
4. `src/minimal_rules.json` (fallback with 7 basic patterns)
## Performance Optimizations
1. **Thread-local engines**: Each Pingora worker has its own Synapse instance
2. **Lazy rule loading**: Rules parsed once at startup via `once_cell::Lazy`
3. **Zero-copy headers**: Header references passed directly to engine
4. **LTO**: Link-time optimization in release builds (profile: fat LTO, 1 codegen unit)
5. **Native CPU**: Build with `RUSTFLAGS="-C target-cpu=native"` for best performance
### DLP Body Inspection Optimizations
The DLP scanner has been optimized for high-throughput request body scanning:
| **Content-Type Short Circuit** | Skip binary types (image/*, video/*, multipart/form-data) | Eliminates scan overhead for file uploads |
| **Inspection Depth Cap** | Truncate body to first 8KB by default | O(1) scan time for large payloads |
| **Aho-Corasick Prefilter** | Single-pass multi-pattern detection | 30-50% faster than sequential regex |
#### DLP Performance Benchmarks (February 2026)
| 4 KB | **~34 μs** | ~21 μs | E-commerce order payloads |
| 8 KB | ~65 μs | ~42 μs | At inspection cap limit |
| 18 KB | ~68 μs | ~42 μs | Truncated to 8KB cap |
| 32 KB | ~64 μs | ~41 μs | Plateaus due to truncation |
DLP fast mode saves 30-34%: 4 KB drops from ~34 μs to ~24 μs, 8 KB from ~70 μs to ~46 μs.
#### DLP Configuration Options
```rust
// In code (DlpConfig)
DlpConfig {
enabled: true, // Enable/disable DLP scanning
max_scan_size: 5 * 1024 * 1024, // 5MB hard limit (reject if larger)
max_matches: 100, // Stop after 100 matches
scan_text_only: true, // Only scan text content types
max_body_inspection_bytes: 8 * 1024, // 8KB inspection cap (truncate, don't reject)
}
```
**Tuning Recommendations**:
- **High-security environments**: Set `max_body_inspection_bytes` to 32KB+ for deeper inspection
- **High-throughput APIs**: Keep default 8KB cap for sub-100μs scan times
- **File upload endpoints**: Binary content types are automatically skipped
#### Content Types Automatically Skipped
- `image/*` - All image formats
- `audio/*` - All audio formats
- `video/*` - All video formats
- `application/octet-stream` - Binary data
- `multipart/form-data` - File uploads
- `application/zip`, `application/gzip`, etc. - Archives
- `font/*` - Font files
- `model/*` - 3D models
## Future Work (For Feature Parity with nginx)
### Core Features (Required for Production)
- [x] Full detection rule parity with libsynapse (DONE - using real engine)
- [x] **Multi-site/vhost support** - Hostname-based routing with per-site config
- [x] **TLS termination** - SSL certificates, SNI support
- [x] **Health check endpoint** - `/_sensor/status` equivalent
- [x] **Per-site WAF config** - Override rules, thresholds per hostname
### Management Features (Important)
- [x] **Metrics endpoint** - Prometheus-compatible `/metrics`
- [x] **Config hot-reload API** - Update config without restart
- [x] **Access lists** - Allow/deny CIDRs per site
- [x] **Per-site rate limiting** - Hostname-aware rate limits
- [x] Signal Horizon telemetry integration
### Advanced Features
- [x] DLP scanning in `request_body_filter` (DONE - with performance optimizations)
- [x] Request body inspection (POST/PUT payloads) (DONE - with truncation cap)
- [x] Custom block pages per site
- [x] Dashboard UI integration (Dashboard compatibility routes)
- [x] Production hardening (security audit remediations complete)
## Files
```
synapse-pingora/
├── Cargo.toml # Dependencies
├── config.example.yaml # Example configuration
├── test.sh # Integration test script
├── README.md
├── benches/
│ └── detection.rs # Criterion benchmarks
├── assets/
│ └── admin_console.html # Embedded admin web console
├── docs/ # Project documentation
│ ├── reference/ # Configuration reference
│ ├── tutorials/ # Tuning, DLP, shadow mirroring
│ └── api/ # Admin API reference
└── src/
├── main.rs # Binary entrypoint + Pingora proxy impl
├── lib.rs # Library crate root
├── config.rs # YAML config loading & validation
├── admin_server.rs # Admin HTTP API (90+ endpoints)
├── api.rs # API handler traits
├── metrics.rs # Prometheus metrics registry
├── health.rs # Health check logic
├── rules.rs # Rule loading & management
├── tui.rs # Interactive terminal dashboard
├── waf/ # WAF detection engine
├── entity/ # IP/actor entity store & risk tracking
├── actor/ # Behavioral actor tracking
├── session/ # Session tracking & hijack detection
├── detection/ # Credential stuffing & login detection
├── correlation/ # Campaign correlation engine
├── intelligence/ # Signal intelligence manager
├── dlp/ # Data Loss Prevention scanner
├── profiler/ # Endpoint profiling & schema learning
├── payload/ # Bandwidth & payload analysis
├── trends/ # Trend analysis & anomaly detection
├── fingerprint/ # JA4 fingerprinting & integrity
├── crawler/ # Bot & crawler detection
├── geo/ # GeoIP & impossible travel detection
├── shadow/ # Shadow traffic mirroring
├── signals/ # Signal adapter layer
├── horizon/ # Signal Horizon hub integration
├── tunnel/ # Secure tunnel client
├── telemetry/ # Telemetry & reporting
├── interrogator/ # CAPTCHA, JS challenge, cookie mgmt
├── persistence/ # State persistence layer
├── tarpit/ # Tarpit (not shown: src/tarpit/)
├── utils/ # Circuit breaker & shared utilities
└── (14 more modules) # access, block_log, block_page, body,
# config_manager, headers, ratelimit,
# reload, shutdown, site_waf, sni_validation,
# tls, trap, validation, vhost
```
## License
Licensed under the GNU Affero General Public License v3.0 only.
Copyright Nicholas Crew Ferguson
See [LICENSE](../../LICENSE).
## See Also
- [Pingora GitHub](https://github.com/cloudflare/pingora)
- [Pingora Documentation](https://docs.rs/pingora)