A reverse-proxy web application firewall in Rust. It inspects every request at Layer 7, accumulates an anomaly score, and returns a verdict — in under a millisecond on the common path. Complete and standalone on its own.
# install the `waf` binary from crates.io $ cargo install waf-proxy # run it against your backend (listens :8080) $ waf --config config.toml # benign → forwarded, attack → blocked $ curl -o /dev/null -w "%{http_code}\n" localhost:8080/ 200 $ curl -o /dev/null -w "%{http_code}\n" \ "localhost:8080/?q=1' OR '1'='1" 403
Every module that matches contributes points to a cumulative anomaly score (a CRS-style model). When the score crosses your block threshold, the request is denied — and the full breakdown is emitted in the decision log.
Modules run in phases as the request is read; each contributes to the same score. No single rule blocks on its own unless it's worth it.
GraphQL and gRPC operations are validated on their shape — depth, aliases, fields, batch size — not just their content, to cap abuse of typed APIs.
Double-encoding-aware percent-decoding, NFKC, and pipeline-wide overlong-collapse fold evasions into a canonical form before inspection. OWASP CRS / ModSecurity rules import via a native seclang parser.
Detection is one part. The core is a real edge proxy with the operational pieces you need to put it in front of traffic.
rustls with HTTP/1.1 and HTTP/2 over ALPN, certificates from file, optional mutual-TLS — all fail-closed.
A per-client token bucket at connection time; block with 429 or add to the anomaly score.
Trusted-proxy / X-Forwarded-For handling, resolved once and fail-safe: unconfigured means un-spoofable.
Structural caps on body, headers, params, cookies and JSON depth — oversized or malformed requests are rejected.
Explicit fail-open / fail-closed policy per scenario: upstream error, module panic, bad reload, parser limit.
SIGHUP re-reads the config with validate-then-swap — a bad reload keeps the last-good config running.
A WAF sits in the request path, so its overhead is a feature. The core is built to stay out of the way of clean traffic.
A RegexSet content prefilter lets clean requests skip the heavy per-rule matching — only suspicious input pays for full inspection.
Built on Tokio with no garbage collector — no pause spikes on the request path, and a small, predictable memory footprint.
Inspection runs in phases as the request is read and stops as soon as a verdict is reached — work you don't need never runs.
Fast, and proven correct. A versioned 260-case malicious/benign corpus gates accuracy and guards against regressions, so tuning for speed never quietly drops coverage. The benchmark and corpus live in the open repository.
The core emits a stable telemetry contract and exposes typed extension seams, so you add capability by injection, not by patching.
Prometheus /metrics and a structured JSON decision log — including the per-rule score contributions behind every verdict. This is the exact contract the enterprise control plane consumes.
A builder wires in typed seams — the distributed StateStore, the TlsCertSource — and a WASM plugin runtime (Proxy-Wasm on wasmi) loads your own modules. The enterprise tier plugs in here, without touching the core.
The core is published to crates.io — build against the pieces you need, or run the proxy binary directly.
The reverse-proxy binary — cargo install it and run as waf.
waf-core↗Base types, config, and client-IP resolution.
waf-normalizer↗Decoding, NFKC, and request parsing (anti-evasion).
waf-pipeline↗Phased orchestration and anomaly scoring.
waf-detection↗Detection modules, rules, and the fast-path prefilter.
waf-wasm↗The Proxy-Wasm plugin runtime (wasmi).
Install the waf binary from crates.io, or build from source — it needs only Rust and cargo, and listens on :8080.
# install the `waf` binary from crates.io $ cargo install waf-proxy $ waf --config config.toml # …or build from source $ git clone https://github.com/0x00spor3/Light-WAF $ cd Light-WAF && cargo run -p waf-proxy -- --config config.toml
# config.toml
[proxy]
listen = "0.0.0.0:8080"
backend = "http://127.0.0.1:3000"
[waf]
mode = "blocking"
block_threshold = 5The whole engine is open source under Apache-2.0. Star it, file issues, or build a plugin.