Skip to main content

Achado: Middleware Ordering — UseAuthentication() após UseEndpoints()

Data: 2026-07-08 Severidade: Alto (sistêmico) Serviços afetados: ~17 serviços (4 no escopo do pentest)


1. O Bug

UseAuthentication() é registrado DEPOIS de UseEndpoints() no pipeline de middleware. UseEndpoints(MapControllers) é middleware terminal — não chama o próximo. Resultado: autenticação JWT nunca executa para requisições em controllers.


2. Evidência: Código Fonte

2.1 Startup.Configure() — todos os 4 serviços

Checkoutcoezzion-service-checkout/src/Checkout.API/Startup.cs:68-80:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IInitializeService initializeService)
{
app.UseApiConfiguration(env); // L70 ← contém UseEndpoints
app.UseSwaggerConfiguration(env, Configuration); // L72
app.UseAuthenticationConfiguration(); // L74 ← UseAuthN DEPOIS de UseEndpoints
if (!env.IsDevelopment()) { Initialize(initializeService).Wait(); }
}

Cartcoezzion-service-cart/src/Cart.API/Startup.cs:57-64:

app.UseApiConfiguration(env, Configuration); // L59
app.UseSwaggerConfiguration(env); // L61
app.UseAuthenticationConfiguration(); // L63

Productcoezzion-service-product/src/Product.API/Startup.cs:63-72:

app.UseApiConfiguration(env, Configuration); // L65
app.UseSwaggerConfiguration(env, Configuration); // L69
app.UseAuthenticationConfiguration(); // L71

Storecoezzion-service-store/src/Store.API/Startup.cs:57-62:

app.UseApiConfiguration(env, Configuration); // L59
app.UseAuthenticationConfiguration(); // L61

2.2 UseApiConfiguration() — contém UseEndpoints() (terminal)

Checkoutcoezzion-service-checkout/src/Checkout.API/Configuration/ApiConfig.cs:61-91:

public static IApplicationBuilder UseApiConfiguration(this IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); }
app.UseMiddleware<ErrorHandlingMiddleware>(); // L68
if (!env.IsDevelopment()) { app.UseHttpsRedirection(); } // L70-73
app.UseRouting(); // L75
app.UseCors("Total"); // L77
app.UseAuthorization(); // L79 ← AuthZ ANTES de AuthN
app.UseMiddleware<SerilLogMiddleware>(); // L81
app.UseEndpoints(endpoints => // L83 ← TERMINAL
{
endpoints.MapHealthChecks("/check");
endpoints.MapControllers();
});
return app;
}

Cartcoezzion-service-cart/src/Cart.API/Configuration/ApiConfig.cs:61-90:

app.UseAuthorization(); // L79
app.UseEndpoints(...) // L83

Productcoezzion-service-product/src/Product.API/Configuration/ApiConfig.cs:62-93:

app.UseAuthorization(); // L84
app.UseEndpoints(...) // L86

Storecoezzion-service-store/src/Store.API/Configuration/ApiConfig.cs:75-115:

app.UseAuthorization(); // L93
app.UseEndpoints(...) // L97

2.3 UseAuthenticationConfiguration() — registrado DEPOIS do terminal

Nugetcoezzion-nuget-authentication/src/Coezzion.Authentication/Configuration/AuthenticationConfig.cs:81-88:

public static IApplicationBuilder UseAuthenticationConfiguration(this IApplicationBuilder app)
{
app.UseAuthentication(); // L83 ← NUNCA executa (depois de UseEndpoints)
app.UseAuthorization(); // L85 ← NUNCA executa (depois de UseEndpoints, duplicado de ApiConfig)
return app;
}

3. Pipeline Real vs Esperado

Pipeline que EXECUTA em runtime:

┌─────────────────────────────────┐
│ 1. app.UseDeveloperExceptionPage() (Dev only)
│ 2. app.UseMiddleware<ErrorHandlingMiddleware>()
│ 3. app.UseHttpsRedirection() (non-Dev)
│ 4. app.UseRouting() ✅
│ 5. app.UseCors("Total") ✅
│ 6. app.UseAuthorization() ✅ (mas User NÃO populado)
│ 7. app.UseMiddleware<SerilLogMiddleware>()
│ 8. app.UseEndpoints(MapControllers) ✅ ← TERMINAL
├─────────────────────────────────┤
│ 9. app.UseAuthentication() ❌ NUNCA EXECUTA
│10. app.UseAuthorization() ❌ NUNCA EXECUTA (duplicado)
└─────────────────────────────────┘

Pipeline CORRETO (documentação Microsoft):

┌─────────────────────────────────┐
│ 1. Exception/Error Handling
│ 2. HttpsRedirection
│ 3. UseRouting() ✅
│ 4. UseCors() ✅
│ 5. UseAuthentication() ✅ ← DEVE estar aqui
│ 6. UseAuthorization() ✅ ← DEVE estar aqui
│ 7. UseEndpoints(MapControllers) ✅ ← TERMINAL
└─────────────────────────────────┘

4. Documentação Microsoft

Link: https://learn.microsoft.com/en-us/aspnet/core/fundamentals/middleware/

Seção Middleware order:

"CORS Middleware, Authentication Middleware, and Authorization Middleware must appear in the order shown."

Ordem documentada:

UseRouting → UseCors → UseAuthentication → UseAuthorization → UseEndpoints

Sobre middleware terminal:

"When a middleware short-circuits, it's called a terminal middleware because it prevents further middleware from processing the request."

"Middleware added to the pipeline before the terminal middleware still processes code after their next.Invoke statements."

UseEndpoints(MapControllers) registra EndpointMiddleware no pipeline. Quando uma rota casa com um controller, o middleware executa o controller, envia a resposta, e não chama _next.


5. Evidência do Pentest

GET /api/payment/profile-fraud HTTP/1.1
Authorization: Bearer eyJ...schema:"arezzo"...
api-company-target: schutz

HTTP/1.1 503 Service Unavailable
{"error":"Não foi possível efetuar a conexão com o schema schutz.CustomerProfileFraud"}
  • JWT contém claim schema: "arezzo"
  • Header contém api-company-target: schutz
  • Servidor tentou conectar ao schema schutz (do header), não arezzo (do JWT)
  • 503 confirma: header venceu, claim ignorada

6. Como o Sistema "Funciona" Apesar do Bug

UseAuthorization() (L79 do ApiConfig.cs, que RODA) implementa lazy authentication: quando encontra um endpoint com [Authorize], chama automaticamente AuthenticateAsync("Bearer")JwtBearerHandler.HandleAuthenticateAsync() valida o token e popula HttpContext.User.

Isso mascara o bug para endpoints COM [Authorize]. Mas falha para:

CenárioConsequência
Endpoint SEM [Authorize]Lazy auth não dispara → HttpContext.User vazio → claim schema null
SignalR hub negotiateUseAuthN() precisa rodar durante o handshake → não roda → #29
Health checks com authMapHealthChecks sem [Authorize] não dispara lazy auth
Middleware custom que lê HttpContext.UserUser vazio antes do [Authorize] ser avaliado

7. Serviços Afetados (padrão idêntico)

ServiçoStartup.csApiConfig.cs
checkout ✅ escopoStartup.cs:70-74ApiConfig.cs:79,83
cart ✅ escopoStartup.cs:59-63ApiConfig.cs:79,83
product ✅ escopoStartup.cs:65-71ApiConfig.cs:84,86
store ✅ escopoStartup.cs:59-61ApiConfig.cs:93,97
authStartup.cs:57-63Mesmo padrão
adminStartup.csMesmo padrão
push-notificationStartup.csMesmo padrão
realtimeStartup.csMesmo padrão
backofficeStartup.csMesmo padrão
rewardStartup.csMesmo padrão
messageStartup.csMesmo padrão
integrationStartup.csMesmo padrão
crmStartup.csMesmo padrão
payments-reportsStartup.csMesmo padrão
showcaseStartup.csMesmo padrão
jobsStartup.csMesmo padrão
activationStartup.csMesmo padrão