Skip to content

v2.4.0 — Measured WAF accuracy, no published secrets, AI redaction, tamper-evident audit log

Choose a tag to compare

@MUKE-coder MUKE-coder released this 11 Sep 08:42
· 12 commits to main since this release
f47b940

Evidence and hardening. The WAF's accuracy is measured and pinned in CI. There is no published dashboard secret. AI prompts are private by default. The audit log can prove it wasn't edited.

Security fixes

  • Double-encoding WAF bypass. The classifier decoded query values once, so %2527 reached an app that decodes again as an apostrophe. Leftover percent-encoding in the path, parameter names and values, and bodies is now decoded up to two more times, and every layer is scanned. Form-encoded bodies are decoded too.
  • Published JWT secret. An unset Dashboard.SecretKey defaulted to a value from the source, so anyone could forge an admin token outside release mode. It is now random, generated at each start.
  • Default password. admin/sentinel is accepted only from a direct loopback connection with no forwarding headers, unless AllowInsecureDefaults is set.
  • WebSocket origin. Browser handshakes must now come from the dashboard's own origin.
  • IP blocks with the WAF disabled. They did nothing. They are now enforced.
  • Memory store data races. Shared actor and threat pointers are now copied.

Measured WAF accuracy

The corpus holds 89 legitimate-but-suspicious requests and 56 attacks. With the default rule set:

  • false positives: 9/89 (10.1%), down from 32/84 (38%)
  • attacks detected: 56/56, up from 47/51

Patterns that fired on ordinary English and code now need SQL, shell, or URL shape. See Measured Accuracy.

An attack regression suite runs end to end: encoded payloads, spoofed forwarding headers against rate limits and IP blocks, and credential stuffing against AuthShield. security/scan runs ZAP and sqlmap against a deliberately injectable app.

Added

  • AI redaction, on by default (AI.Redaction). Query values, bodies, full IPs, cities, emails, tokens, card numbers, and secrets never reach the provider. Matched attack fragments are kept.
  • Tamper-evident audit log. Entries are hash-chained, with HMAC when Storage.AuditKey is set. GET /api/audit-logs/verify and the dashboard's Verify integrity button report modified, missing, and relinked entries.
  • Live IP reputation. Attacking IPs are checked against AbuseIPDB as they arrive, within MaxChecksPerDay, and AutoBlock acts on the results.
  • Blocklist feeds (IPReputation.Feeds). Spamhaus DROP, FireHOL, and NDJSON CIDR lists are refreshed daily and blocked.
  • Dashboard.
    • The WAF mode and per-category sensitivity controls, and a lifetime for each IP block.
    • The audit chain verification described above.

Upgrading

  1. Set Dashboard.SecretKey (32+ random bytes). Otherwise sessions end on every restart and don't work across replicas.
  2. If you reach the dashboard through Docker, a tunnel, or a proxy, set Dashboard.Password. The default password is refused there.
  3. Set Storage.AuditKey for a keyed audit chain.
  4. If you need raw payloads in AI analyses, set AI.Redaction.SendPayloads.
  5. Patterns changed, so run the WAF in log mode briefly and review the Threats page. OpenRedirect now fires only on redirect-named parameters.

Full details are in CHANGELOG.md. Upgrade notes are in What's New in v2.4.