ADR-0008: Collection keys match case-insensitively
ADR-0008: Collection keys match case-insensitively
- Status: proposed
- Date: 2026-10-06
- Deciders: @fzipi
- Category: Divergence
Context
- ModSecurity v2 compares a selector against member names with
strcasecmp(apache2/re_variables.c, everyvar_*_generateforARGS,REQUEST_HEADERS,REQUEST_COOKIES,TX, …). - libmodsecurity v3 stores members in an unordered multimap with a lower-casing hash and
equality (
headers/modsecurity/anchored_set_variable.h,MyHash,MyEqual). - Coraza 3.8.1 lower-cases keys on storage and lookup (
internal/collections/map.go) unless built withcoraza.rule.case_sensitive_args_keys(Coraza ADR-0016), in which caseARGSkeys are compared exactly; Coraza ADR-0015 added a case-sensitive map type for internal use and deferred switching the default to v4.
OWASP CRS writes %{tx.anomaly_score} and TX:ANOMALY_SCORE interchangeably (hundreds of
occurrences of each spelling) and selects headers as REQUEST_HEADERS:Content-Type.
Decision
Member names in every collection are matched against key selectors, macro keys and
setvar names case-insensitively. A regex selector is applied to the member name as the
engine parsed it and is case-sensitive unless the expression says otherwise. Normative
text: spec/05-variables.md#collection-keys. The Coraza case-sensitive build is
non-conforming.
Options considered
- Case-sensitive keys: HTTP header names are case-insensitive by RFC 9110 and CRS mixes
TXkey spellings; rejected. - Per-collection sensitivity (Coraza’s own stated ideal): no engine implements it and no ruleset needs it; rejected for now.
- Case-insensitive everywhere (chosen).
Consequences
- For ModSecurity: no change.
- For Coraza: keep the default; the build tag stays opt-in and documented as non-conforming.
- For rule authors: argument names that differ only in case cannot be distinguished by a key selector; use a regex selector if that ever matters.
Tests
References
spec/05-variables.md#collection-keys- Coraza ADR-0015 and Coraza ADR-0016 in
corazawaf/coraza/docs/adr