Transformations create a changed copy of variable data before the operator evaluates it. They do not rewrite the HTTP request. A transformation pipeline runs from left to right, and order is security-significant.
SecRule ARGS "@contains select" \
"id:100030,phase:2,deny,t:none,t:urlDecodeUni,t:htmlEntityDecode,t:lowercase"
Decoding and encoding
| Transformation | Purpose |
|---|---|
urlDecode | Decodes standard URL encoding. |
urlDecodeUni | Decodes URL and supported Unicode-style encoding. |
htmlEntityDecode | Decodes HTML entities. |
jsDecode | Decodes JavaScript escape sequences. |
cssDecode | Decodes CSS escapes. |
escapeSeqDecode | Decodes common escape sequences. |
base64Decode / base64DecodeExt | Decodes Base64 input. |
hexDecode | Decodes hexadecimal representation. |
urlEncode, base64Encode, hexEncode | Encode a transformed copy. |
Repeated decoding can create ambiguity. Apply only the pipeline required by the rule and test nested encoding deliberately.
Case, whitespace, and comments
lowercase and uppercase normalize case. compressWhitespace, removeWhitespace, trim, trimLeft, and trimRight normalize spacing. Comment transformations remove or replace comment syntax to make split attack tokens visible.
Paths and command lines
normalizePath resolves path navigation and separators; normalizePathWin applies Windows path behavior. cmdLine normalizes common command-line evasions. Use the platform-appropriate transformation and keep raw-path validation separate where ambiguity matters.
Nulls and byte representation
removeNulls removes null bytes; replaceNulls substitutes spaces. Hash and length transformations produce derived representations. Know whether a downstream operator expects text, bytes, a digest, or a length.
Clear inherited transformations
t:none clears transformations inherited from SecDefaultAction or context. Put it before the explicit pipeline:
"t:none,t:urlDecodeUni,t:lowercase"
Common mistakes
- Applying transformations in an order that hides rather than exposes a pattern.
- Decoding data twice without testing the result.
- Using aggressive normalization for exact protocol validation.
- Assuming transformations modify the application request.
- Forgetting inherited transformations when debugging a match.