Authorization is not re-evaluated after a mid-pipeline reroute in implicit-routing minimal hosting
- Dominant language
- C#
- Stars
- 38.4k
- Forks
- 10.9k
- Avg merge
- 2d 5h
- Merged PRs (30d)
- 276
Description
## Summary
In minimal-hosting apps that rely on the framework's implicit routing (no explicit `UseRouting()` call), a mid-pipeline reroute does not re-run the framework's automatically-added authentication and authorization middleware against the endpoint that is ultimately selected, so an authorization requirement on that endpoint can go unevaluated.
## What is wrong
* The invariant "authorization runs against the endpoint that actually executes" does not hold for implicit-routing minimal-hosting apps when a mid-pipeline reroute changes which endpoint is matched (for example, a reroute triggered by URL-rewrite middleware).
* `WebApplicationBuilder.ConfigureApplication`'s implicit-routing branch composes authentication and authorization once, eagerly, on the outer pipeline, instead of deferring them into the framework's `PostRoutingPipeline` mechanism that already replays on every reroute. Only CSRF protection is deferred that way on this branch today.
* The explicit-`UseRouting()` branch already defers authentication, authorization, and CSRF together into `PostRoutingPipeline`, so it does not have this gap. The two documented ways of composing the same framework currently produce different security guarantees for otherwise-equivalent application code.
## Why it matters (defense in depth)
* An endpoint decorated with an authorization requirement should never execute without that requirement being evaluated against it, regardless of whether routing reached it by a direct match or by a reroute.
* Closing the asymmetry between the implicit- and explicit-routing composition paths removes a correctness gap that depends on which (undocumented) composition style an application happens to use.
## Affected code
* src/DefaultBuilder/src/WebApplicationBuilder.cs:485-535 - `ConfigureApplication`'s implicit- vs. explicit-routing branches compose different middleware sets for `PostRoutingPipeline`
* src/Http/Routing/src/EndpointRoutingMiddleware.cs:33-72 - constructor replays whatever is stored under `PostRoutingPipeline` on every reroute (already correct; the gap is only in what the implicit-routing branch stores there)
* src/Shared/Reroute.cs - shared reroute helper used by URL-rewrite middleware and other reroute-triggering middleware
## Recommended fix
Defer the same middleware set (authentication, authorization, CSRF) into `PostRoutingPipeline` for the implicit-routing branch, exactly as already happens for the explicit-`UseRouting()` branch, removing the separate authentication/authorization-only composition path used only by implicit routing. This makes both routing compositions structurally equivalent with respect to which security middleware replays on a reroute.
Alternatives considered:
* Documentation-only guidance describing safe middleware ordering — rejected as the sole fix because it leaves the framework's own default composition producing the weaker guarantee with no code-level safeguard.
* Detecting and erroring when implicit routing is combined with reroute-capable middleware — rejected; this would be a breaking behavior change with no reliable signal to detect the combination safely ahead of time.
Compatibility: internal-only change; no public API surface is affected. Behavior for applications that already call `UseRouting()` explicitly is unchanged.
## Acceptance criteria
* [ ] Authorization requirements on an endpoint are evaluated whenever that endpoint executes, whether reached directly or via a mid-pipeline reroute, for both implicit- and explicit-routing composition.
* [ ] A regression test exercises a reroute that changes which endpoint is matched, for both routing compositions.
* [ ] No new public API surface is introduced.
## Related
* #68582 - endpoint-specific authorization marker hardening (independent, complementary defense-in-depth change)
Contributor guide
Research direction
Start in src/DefaultBuilder/src/WebApplicationBuilder.cs around ConfigureApplication and compare the implicit- and explicit-routing branches. Read src/Http/Routing/src/EndpointRoutingMiddleware.cs and src/Shared/Reroute.cs to understand the existing replay path. Add regression coverage for a reroute that changes the matched endpoint under both routing compositions, and verify authorization is evaluated whenever the endpoint executes.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- csharp
- Domain
- authorization, backend, security, testing
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 55/100