CME-1314

Input Canonicalization Before Security Decision

Description

Normalize and canonicalize all user-supplied structured input (URLs, IP addresses, domain names, file paths, type identifiers, protocol schemes) to a standard form before applying any security decision such as allowlist matching, denylist checking, or policy evaluation. Decoding, case folding, Unicode normalization, IP address format unification (dotted-decimal, hex, octal, IPv4-mapped IPv6), and scheme normalization must occur before the security check — not after. This prevents attackers from using encoding variants, aliasing, or alternate representations to bypass list-based security controls. The canonicalization order must be: decode all layers → normalize → validate against security policy → sanitize.

CVSS Vector Impacts

Metric Transition Rationale
Attack Complexity (AC) L → H The attacker must find an input representation that survives full canonicalization while still bypassing the security check — encoding tricks (URL-encoding, Unicode homoglyphs, octal IP notation, mixed-case evasion) are neutralized before the security decision is made, requiring the attacker to discover a novel bypass that operates at the semantic level rather than the syntactic level

CWE Relationships

Verification

Review application source code for canonicalization/normalization calls that execute before security-relevant comparisons (allowlist checks, denylist checks, policy evaluations). Verify that the canonicalized form — not the raw input — is used in all subsequent security decisions.

$ grep -rn 'urllib.parse\|urlparse\|URL.parse\|new URL\|InetAddress.getByName\|canonicalize\|NFC\|NFKC\|unicodedata.normalize\|Normalizer.normalize\|os.path.realpath\|Path.*resolve' <app_source>/ | grep -i 'input\|request\|param\|user\|url\|path\|host\|addr'
# Expected: Canonicalization/normalization calls present in input-handling code paths that feed into security decisions
Platform: any
$ grep -rn 'allowlist\|blocklist\|denylist\|whitelist\|blacklist' <app_source>/ | grep -i 'request\|req\.\|params\|raw\|input\|getParameter' | head -10
# Expected: Zero matches — security list checks should operate on canonicalized values, not raw request parameters
Platform: any
$ curl -s -o /dev/null -w '%{http_code}' '<app_endpoint>/%2e%2e/%2e%2e/etc/passwd' && echo ' ' && curl -s -o /dev/null -w '%{http_code}' '<app_endpoint>/../../etc/passwd'
# Expected: Both requests return identical response codes (both blocked or both canonicalized and rejected)
Platform: any

Remediation

linux nginx URL canonicalization and encoded-path normalization

printf 'merge_slashes on;\nlocation ~* "%%2[ef]" {\n    return 400;\n}\n' > /etc/nginx/conf.d/cme-1314-canonicalization.conf
nginx -t
nginx -s reload
linux Apache httpd URL decoding enforcement and path traversal blocking

printf '<IfModule mod_rewrite.c>\n  RewriteEngine On\n  # Block percent-encoded path traversal sequences\n  RewriteCond %%{THE_REQUEST} %%2[eE]%%2[eE] [OR]\n  RewriteCond %%{THE_REQUEST} %%2[fF]\n  RewriteRule .* - [F,L]\n</IfModule>\nAllowEncodedSlashes NoDecode\n' > /etc/httpd/conf.d/cme-1314-canonicalization.conf
apachectl configtest 2>&1 || httpd -t 2>&1
systemctl reload httpd 2>/dev/null || systemctl reload apache2 2>/dev/null
← CME-1313: CRLF / Line Injection Prevention (Newline Sanitization for Structured Formats) CME-1315: Allowlist-Preferred Input Validation (Deny-by-Default Filtering) →