Skip to content

Light WAF v0.4.0

Latest

Choose a tag to compare

@0x00spor3 0x00spor3 released this 05 Jul 19:08

Light WAF v0.4.0 — Decision-log score breakdown (drill-down data)

A fast, modular Layer-7 Web Application Firewall written in Rust, operating as a
reverse proxy: it inspects every HTTP request, accumulates a CRS-style anomaly score,
and decides Allow / Block (403) / Reject (400 | 429) before forwarding to the backend.

This is a small, additive release focused on observability. There are no changes to
detection
— the corpus verdicts are identical to v0.3.0. The whole workspace is bumped to
0.4.0 together (uniform versioning).

What's new

Per-rule score_contributions in the decision-log (the headline)

When a request is blocked or rejected, the structured decision-log line now carries a
score_contributions field: a JSON array of the per-rule breakdown that produced the
verdict — [{ "module", "rule_id", "severity", "points" }, …]. Previously the log recorded
only the final rule_id + cumulative score; the full breakdown existed in memory but was
never emitted.

This is the data source for verdict drill-down (reconstructing why a request was
blocked, module by module). The field:

  • is emitted only on the already-logged denied path (never per benign request, never on the
    hot path);
  • is a JSON-string field, so a log consumer parses the line, then parses the field;
  • reconstructs losslessly into the typed model — waf_core::ScoreContribution and
    waf_core::Severity now derive Serialize/Deserialize (severity is lowercased:
    "critical" | "error" | "warning" | "notice"), so a downstream consumer can reuse the exact
    types.

The field names and format are a stable ingestion contract (locked by a shape test),
alongside the Prometheus metrics ABI.

Compatibility

  • Additive. New log field + new Serialize/Deserialize derives on two existing types.
    No API removed or changed; existing code compiles and behaves identically.
  • Detection unchanged — validation corpus 10/10, 0% false positives at PL3, same
    recall as v0.3.0 (this is a logging enrichment, not a detection change).
  • clippy -D warnings clean; full workspace test suite green, including a bite-test that drives
    a real blocked request through the proxy and asserts the enriched field is emitted and
    reconstructs into the typed breakdown.

Install / upgrade

# the binary (command: `waf`)
cargo install waf-proxy        # picks up 0.4.0

# or use the core as a library (open-core, no fork — embed via Proxy::builder + seams)
cargo add waf-core@0.4

Published crates

Crate Role
waf-core Base types, WafModule/Decision, StateStore seam
waf-normalizer Decode + NFKC + parsing + limits
waf-pipeline Phased orchestrator + anomaly scoring
waf-detection Detection modules + fast-path prefilter
waf-wasm Proxy-Wasm runtime (wasmi)
waf-proxy The binary (waf) + embeddable lib (ProxyBuilder)

License

Open source under Apache-2.0. The open-source vs. enterprise boundary is documented
normatively in BOUNDARY.md.