URL Request Path Canonicalization Before Authorization
Description
Ensure the web server, reverse proxy, or application framework canonicalizes request URIs — resolving path equivalences (., ..), stripping matrix parameters (;param=value), normalizing percent-encoding, collapsing duplicate slashes, and standardizing trailing slashes — before the authorization module evaluates access control rules. The root cause of CWE-551 is a behavior ordering defect where authorization sees a raw URI form that does not match configured security constraints, but the routing/dispatch layer later normalizes the URI and matches a protected resource. Canonicalization-first ensures the authorization decision and the routing decision operate on the same resolved path. Implementation varies by stack: Spring Security's StrictHttpFirewall rejects non-normalized requests; Tomcat's encodedSolidusHandling and allowBackslash settings control normalization; Nginx's merge_slashes and location matching normalize by default; Apache's AllowEncodedSlashes and mod_rewrite handle encoding normalization. Reverse proxies should be configured to normalize before forwarding to backends, and frameworks should reject requests containing path-equivalent sequences rather than silently normalizing them.
CVSS Vector Impacts
| Metric | Transition | Rationale |
|---|---|---|
| Attack Complexity (AC) | L → H | Attacker can no longer bypass authorization using non-canonical URL forms (matrix parameters, double encoding, path segment equivalences, trailing characters); exploitation requires finding a bypass that survives full URI canonicalization before the authorization decision evaluates the request |
CWE Relationships
Verification
Test that non-canonical URL forms (matrix parameters, dot-segments, encoded path separators) do not bypass authorization on protected endpoints; inspect web server and framework configuration for canonicalization-before-auth settings
# Expected: 401 or 403 — matrix parameter does not bypass auth
# Expected: 401 or 403 — dot-segment does not bypass auth
# Expected: 401 or 403 — encoded dot does not bypass auth
# Expected: StrictHttpFirewall configured with restrictive defaults
# Expected: merge_slashes on (default); proxy_pass uses normalized $uri
# Expected: AllowEncodedSlashes NoDecode or absent (default deny)
Remediation
printf '# CME-921: URL path canonicalization before authorization\nmerge_slashes on;\n\nmap $request_uri $cme921_block {\n default 0;\n "~*\\.\\." 1;\n "~*%%2[eE]" 1;\n "~*%%2[fF]" 1;\n "~*%%5[cC]" 1;\n "~*;[^/]*=" 1;\n}\n' > /etc/nginx/conf.d/cme-921-canonicalization.conf
printf '# Include inside server {} blocks:\n# if ($cme921_block) { return 400; }\n' >> /etc/nginx/conf.d/cme-921-canonicalization.conf
nginx -t
systemctl reload nginx
printf '# CME-921: URL path canonicalization before authorization\nAllowEncodedSlashes NoDecode\n\nRewriteEngine On\n# Reject dot-segment traversal sequences\nRewriteCond %%{REQUEST_URI} (\\.\\.) [OR]\nRewriteCond %%{REQUEST_URI} (%%2[eE]\\.) [OR]\nRewriteCond %%{REQUEST_URI} (\\.%%2[eE]) [OR]\n# Reject matrix parameters that could bypass path matching\nRewriteCond %%{REQUEST_URI} (;[^/]*=)\nRewriteRule .* - [F]\n' > /etc/httpd/conf.d/cme-921-canonicalization.conf
httpd -t 2>&1 || apachectl configtest 2>&1
systemctl reload httpd