Research
One path, two interpretations: a route-level authorization bypass
A local case study of an authorization bypass caused by route matching and resource lookup using different URL path representations.
In a local reproduction, an unauthenticated request for a protected file returned 401 Unauthorized through its intended route. An equivalent URL using an alternate encoding entered a public fallback and returned 200 OK with the file’s contents. Both requests resolved to the same resource; the outcome changed because the application used different representations of the URL to decide whether authentication applied and to locate the file.
The application boundary
Link to this section: The application boundaryThe test application enforced authentication on a protected path prefix. A public catchall route used the same file handler and could reach the same directory. Any request resolving to a protected file was intended to pass authentication before the file was served.
The ordinary request followed that rule: it matched the protected route, ran the authentication middleware, and was rejected. The encoded equivalent did not match the protected prefix at the routing layer. Instead, it took the catchall route, where the file handler received a decoded path to the protected file. The protected route’s authentication middleware was never selected for that request.
This layout is an essential condition of the finding. A routing difference alone does not expose data; the less restricted fallback must also be able to reach a resource covered by a more restrictive route.
What the local test showed
Link to this section: What the local test showedWe created a file containing a synthetic marker and sent both request forms without credentials:
| Request form | Route selected | Observed response |
|---|---|---|
| Ordinary protected path | Protected route | 401 Unauthorized |
| Equivalent encoded path | Public fallback | 200 OK with the test marker |
We then kept an equivalent protected-prefix and public-fallback arrangement with the same file handler but changed the router. In that control, both request forms returned 401 Unauthorized. This helped isolate the result to route selection rather than file serving or URL encoding alone.
Source review showed that the affected router preferred the encoded form of the path when matching routes, while the downstream file handler resolved the decoded path. A separate local forwarding test showed the same route-selection gap when the fallback passed requests to another handler. It did not establish exposure of a production backend.
Testing was limited to local servers and synthetic data. No production system or customer data was accessed.
Root cause: inconsistent path representations
Link to this section: Root cause: inconsistent path representationsAn HTTP server can retain an encoded request target and a decoded path derived from it. Either representation can be useful. The security boundary fails when one component uses the encoded form to decide which access rule applies while another uses the decoded form to locate the resource.
In this case, the two decisions diverged:
Route selection: encoded path -> public fallback
Resource lookup: decoded path -> protected fileAuthentication was attached to the protected route. Once the alternate spelling selected the fallback, that check was no longer in the request’s execution path. The file handler still reached the protected file because it used the decoded path. This is a path canonicalization failure across an authorization boundary.
Scope and impact
Link to this section: Scope and impactThe demonstrated bypass required three conditions:
- Access control applied to a specific route or path prefix.
- A less restricted fallback accepted an equivalent encoded form of that path.
- The fallback could resolve the decoded path to the protected resource.
Under those conditions, a requester who controls the URL can obtain content without an authenticated session. The local test demonstrated this with a synthetic file. It does not show that every application using the affected router has the necessary fallback or that any production deployment exposed private content.
A fronting proxy that rejects or consistently normalizes the alternate path may block the request before it reaches the application. We did not test a production proxy configuration, so the full deployed request chain remains an important part of any impact assessment.
Remediation and regression testing
Link to this section: Remediation and regression testingAuthorization and resource lookup should use a consistent path representation. An application can reject ambiguous encodings before route selection or apply access control at a shared resource boundary that every route must cross. The right implementation depends on how the application handles legitimate encoded path parameters and downstream routing.
Regression tests should send ordinary and equivalent encoded paths through the complete request chain, including any front proxy and resource handler. If both forms resolve to the same protected resource, both should receive the same authorization decision.
Every route capable of resolving a protected resource must enforce its access rule.