dotnet / dotnet/aspnetcore

Authorization is not re-evaluated after a mid-pipeline reroute in implicit-routing minimal hosting

Open
#68,581 0 comments 0 reactions 0 assignees View on GitHub
area-auth
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.