A request for /%2fadmin reaches your gateway. Your ACL blocks /admin. The gateway sees an encoded string that does not match the literal /admin rule and passes it through. The backend decodes first, routes second, and delivers the admin panel to the caller.

Six CVEs across six different tools document the same structural flaw. The security ACL evaluates the path at a different normalization state than the path the backend ultimately serves. This is not misconfiguration. RFC 3986 leaves decode-order implementation-defined.

RFC 3986 Does Not Say When to Decode

RFC 3986 §6.2.2 describes normalization as optional preprocessing with no required ordering constraint. Section 2.3 states that percent-encodings of unreserved characters SHOULD be decoded by normalizers. The spec specifies no point in the middleware stack where this must happen. Each gateway decides independently.

nginx demonstrates the ambiguity in a single configuration line. With proxy_pass http://backend/, nginx decodes and normalizes before forwarding. Without a path in the directive, it forwards the raw client string unchanged. Same binary, two behaviors, one configuration difference.