Host runtime
Docker Desktop 29.2.0 on macOS, aarch64, 10 CPUs, 7.65 GiB assigned
Original WAFWiki lab
Hands-on Coraza and Caddy Docker test with pinned versions, OWASP CRS 4.25.0, ten clean and attack-like requests, HTTP results, logs, and build constraints.

Evidence policy
WAFWiki separates verified smoke-test results from architecture diagrams and methodology notes. A smoke test proves one narrow local path; it does not claim full production readiness.
Environment
Docker Desktop 29.2.0 on macOS, aarch64, 10 CPUs, 7.65 GiB assigned
Caddy 2.11.2 built with xcaddy and coraza-caddy 2.5.0
Coraza 3.7.0 with embedded coraza-coreruleset 4.25.0
sha256:decfd7324ee3f377d80e3e41b7f7db4be500c615a6ee2f80e8de8a565e909d23
mccutchen/go-httpbin:2.21.0 on the same isolated Docker network
Upstream 127.0.0.1:18180, Coraza 127.0.0.1:18182
Commands
docker build --provenance=false \
-t wafwiki/coraza-caddy:2.5.0 \
docs/lab-fixtures/coraza-caddyThe build reports Caddy 2.11.2, coraza-caddy 2.5.0, Coraza 3.7.0, and coraza-coreruleset 4.25.0.
scripts/run-waf-evidence-lab.shThe script creates only wafwiki-evidence-* resources, runs the matrix, writes evidence, and cleans up its own containers.
awk -F, 'NR == 1 || $1 == "coraza" { print }' \
docs/lab-evidence/waf-engine-comparison-2026-07-26-requests.csvTen Coraza rows are shown with six status 200 decisions and four status 403 decisions.
Observed result
Expected outcomes
Every Coraza status matched the declared expectation for this small request set.
Clean requests
Clean query, JSON, email, version path, filter, and C++ term requests reached the upstream.
Controlled attack-like requests
SQLi-like and XSS-like strings were blocked in both query parameters and JSON fields.
Build compatibility
An earlier Caddy 2.10.2 build failed because coraza-caddy 2.5.0 requires Caddy 2.11.2.
Observed resource snapshot
Docker reported 57.2 MiB after the request and latency samples; this is not a sizing recommendation.
Coraza 3.7.0 / coraza-caddy 2.5.0 / Caddy 2.11.2
OWASP CRS 4.25.0, rule engine on, blocking paranoia level 1
clean decisions: 6 x HTTP 200
SQLi/XSS decisions: 4 x HTTP 403
observed rules: 942100, 941100, 941110, 941160, 949110
image digest: sha256:decfd7324ee3f377d80e3e41b7f7db4be500c615a6ee2f80e8de8a565e909d23Evidence context
Both WAF paths used the same upstream, request definitions, OWASP CRS 4.25.0, localhost routing, and evidence format. The reverse proxies and engines remained different by design.

Open evidence
The files expose the status matrix and versioned summary without publishing raw container logs or unrelated local data.
Twenty request outcomes with engine, case, method, path, expected status, observed status, and curl time.
Pinned image IDs, component versions, host details, request results, latency samples, resource snapshots, and limitations.
Limitations
Related research