Patterns build · 2026-10-01
OWASP Core Rule Set coreruleset/coreruleset@v4.29.0 converted into native WAF rules for four web servers. Generated automatically; no manual edits.
Coverage: 749 patterns across 22 categories — SQLi, XSS, RCE, LFI, RFI, plus generic anomaly and protocol-violation rules.
What changed since the previous release
No rule changed since the previous release (CRS v4.29.0).
The whole of it, per rule and per target, is in changes.json, attached to this release.
Backends
| Backend | Format | Bots | Archive | Size |
|---|---|---|---|---|
| Nginx | map + if
| 1879 | nginx_waf.zip
| 48K |
| Apache | ModSecurity | 1879 | apache_waf.zip
| 80K |
| Traefik | Middleware TOML | 1879 | traefik_waf.zip
| 20K |
| HAProxy | ACL | 1879 | haproxy_waf.zip
| 60K |
Quick install
curl -LO https://github.com/fabriziosalmi/patterns/releases/download/2026-10-01-crs-v4.29.0/nginx_waf.zip
unzip nginx_waf.zip -d /etc/nginx/waf_patternsIntegration guides → Nginx · Apache · Traefik · HAProxy
What each target does with each rule
Of the 749 records in the CRS v4.29.0 intermediate representation, what each target does:
| Target | Full | Approximate | Unsound | Dropped |
|---|---|---|---|---|
| Nginx | 12 | 156 | 0 | 581 |
| Apache (ModSecurity) | 0 | 1 | 712 | 36 |
| Traefik | 0 | 1 | 6 | 742 |
| HAProxy | 2 | 97 | 403 | 247 |
Why a record is dropped, by the first reason the backend found:
| Reason | Nginx | Apache (ModSecurity) | Traefik | HAProxy |
|---|---|---|---|---|
| matched on a request component the target does not have | 96 | 685 | 160 | |
| an operator the backend cannot express | 398 | 21 | 3 | 31 |
| not a rule: it changes another rule | 54 | 54 | 54 | |
| the expression does not compile | 15 | 2 | ||
| longer than the target accepts | 16 | |||
| it refuses ordinary traffic once converted | 13 | |||
| it records and does not refuse | 4 |
What a written rule loses, in how many of them:
| Loss | Nginx | Apache (ModSecurity) | Traefik | HAProxy |
|---|---|---|---|---|
| matched on other variables than the rule names | 149 | 633 | 3 | 480 |
| an operator written as something it is not | 373 | 2 | 301 | |
| transformations the rule was written to run after are not applied | 115 | 184 | 2 | 136 |
| the expression was rewritten | 281 | 3 | 100 | |
| a chain written without all of its links | 13 | 121 | 3 | 56 |
| written although it is not a rule | 54 | |||
| case-insensitivity is not honoured | 3 |
The verdict for every rule and target is in coverage.json, attached to this release. How to read it.
Verify
This release is 2026-10-01-crs-v4.29.0, and it stays: releases are never deleted or replaced, so a link to this tag is a link to these files. Every file in it is signed by the workflow that built it, and attested. SHA256SUMS lists their hashes and is signed with the rest.
cosign verify-blob --bundle nginx_waf.zip.sigstore.json \
--certificate-identity https://github.com/fabriziosalmi/patterns/.github/workflows/update_patterns.yml@refs/heads/main \
--certificate-oidc-issuer https://token.actions.githubusercontent.com nginx_waf.zipEvery step, and how to pin to a release.
SHA-256
b59ecf261def71434f6642fa07e885027af948a33910fead14813c1aa066a03a nginx_waf.zip
a6eb4d614f7ec0fae8b42b03e4f72e09009e46277eb3af8f18d7c8101d765569 apache_waf.zip
f52d31cf4b2c35f214d8f8647e3d6a5f61815ceb73adf51d71de0a908d89d5ad traefik_waf.zip
92a3f5d2ebfe899dd9d471da845a7da271bad06057ddd8e1a910fe6c491b7f03 haproxy_waf.zip
echo "b59ecf261def71434f6642fa07e885027af948a33910fead14813c1aa066a03a nginx_waf.zip" | sha256sum -c -