Coraza Caddy Docker test evidence showing pinned component versions, image digest, six clean HTTP 200 results, four HTTP 403 results, and CRS rule IDs.
The fixed Coraza stack matched all ten expected outcomes in this localhost run: six clean requests returned 200 and four controlled SQLi/XSS requests returned 403.

    Lab status

    Product
    Coraza 3.7.0 / coraza-caddy 2.5.0 / Caddy 2.11.2 / OWASP CRS 4.25.0
    Status
    Completed hands-on test
    Updated
    2026-07-26

    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

    Reproducibility notes

    Host runtime

    Docker Desktop 29.2.0 on macOS, aarch64, 10 CPUs, 7.65 GiB assigned

    Caddy build

    Caddy 2.11.2 built with xcaddy and coraza-caddy 2.5.0

    WAF engine

    Coraza 3.7.0 with embedded coraza-coreruleset 4.25.0

    Image digest

    sha256:decfd7324ee3f377d80e3e41b7f7db4be500c615a6ee2f80e8de8a565e909d23

    Upstream

    mccutchen/go-httpbin:2.21.0 on the same isolated Docker network

    Local ports

    Upstream 127.0.0.1:18180, Coraza 127.0.0.1:18182

    Commands

    How this lab can be reproduced

    Build the pinned Caddy module image

    docker build --provenance=false \
      -t wafwiki/coraza-caddy:2.5.0 \
      docs/lab-fixtures/coraza-caddy

    The build reports Caddy 2.11.2, coraza-caddy 2.5.0, Coraza 3.7.0, and coraza-coreruleset 4.25.0.

    Run the complete evidence lab

    scripts/run-waf-evidence-lab.sh

    The script creates only wafwiki-evidence-* resources, runs the matrix, writes evidence, and cleans up its own containers.

    Inspect Coraza outcomes

    awk -F, 'NR == 1 || $1 == "coraza" { print }' \
      docs/lab-evidence/waf-engine-comparison-2026-07-26-requests.csv

    Ten Coraza rows are shown with six status 200 decisions and four status 403 decisions.

    Observed result

    What the hands-on test showed

    Expected outcomes

    10 / 10 matched

    Every Coraza status matched the declared expectation for this small request set.

    Clean requests

    6 returned 200

    Clean query, JSON, email, version path, filter, and C++ term requests reached the upstream.

    Controlled attack-like requests

    4 returned 403

    SQLi-like and XSS-like strings were blocked in both query parameters and JSON fields.

    Build compatibility

    Caddy 2.11.2 required

    An earlier Caddy 2.10.2 build failed because coraza-caddy 2.5.0 requires Caddy 2.11.2.

    Observed resource snapshot

    57.2 MiB

    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:decfd7324ee3f377d80e3e41b7f7db4be500c615a6ee2f80e8de8a565e909d23

    Evidence context

    The Coraza result came from a shared, versioned test topology.

    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.

    Reproducible Docker topology showing controlled curl requests split across ModSecurity NGINX and Coraza Caddy stacks before one go-httpbin upstream.

    Open evidence

    Download the sanitized result files.

    The files expose the status matrix and versioned summary without publishing raw container logs or unrelated local data.

    Download evidence summary JSON

    Pinned image IDs, component versions, host details, request results, latency samples, resource snapshots, and limitations.

    Limitations

    What this result does not prove

    Related research

    Continue researching Coraza 3.7.0 / coraza-caddy 2.5.0 / Caddy 2.11.2 / OWASP CRS 4.25.0