Tutorial

Logging with OWASP CRS, Part 1: What Your WAF Is Telling You

A web application firewall produces exactly one thing you can hold in your hands: logs. Blocking is a side effect of a rule matching; the log line is the record that it happened, why, and what the request looked like. If nobody reads those logs, the WAF is a very expensive way to return 403s. This is the first of a three part series on logging with OWASP CRS: Part 1 (this post): what ModSecurity and CRS write to disk, how to read it, what to look for, and the two small additions we recommend before you ship a single line to a log platform. Part 2: ModSecurity, with the logs shipped to the Elastic Stack (Logstash, Elasticsearch, Kibana) and a ready made dashboard. Part 3: Coraza, with the logs shipped to Grafana and Loki through Alloy, and the same dashboard. Parts 2 and 3 come with Docker Compose stacks you can run locally in a few minutes. Each post has its files attached, and a zip with all of them at the end. Both use the CRS project’s own container images and the same CRS release. Part 2 runs owasp/modsecurity-crs, NGINX with ModSecurity v3 (libmodsecurity). Part 3 runs coraza-crs, Caddy with Coraza. The examples in this post come from ModSecurity v3; most of it applies to ModSecurity v2 on Apache and to Coraza as well, and where the engines differ, we say so.