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
Checkout — coezzion-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(); }
}
Cart — coezzion-service-cart/src/Cart.API/Startup.cs:57-64:
app.UseApiConfiguration(env, Configuration); // L59
app.UseSwaggerConfiguration(env); // L61
app.UseAuthenticationConfiguration(); // L63
Product — coezzion-service-product/src/Product.API/Startup.cs:63-72:
app.UseApiConfiguration(env, Configuration); // L65
app.UseSwaggerConfiguration(env, Configuration); // L69
app.UseAuthenticationConfiguration(); // L71
Store — coezzion-service-store/src/Store.API/Startup.cs:57-62:
app.UseApiConfiguration(env, Configuration); // L59
app.UseAuthenticationConfiguration(); // L61
2.2 UseApiConfiguration() — contém UseEndpoints() (terminal)
Checkout — coezzion-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;
}
Cart — coezzion-service-cart/src/Cart.API/Configuration/ApiConfig.cs:61-90:
app.UseAuthorization(); // L79
app.UseEndpoints(...) // L83
Product — coezzion-service-product/src/Product.API/Configuration/ApiConfig.cs:62-93:
app.UseAuthorization(); // L84
app.UseEndpoints(...) // L86
Store — coezzion-service-store/src/Store.API/Configuration/ApiConfig.cs:75-115:
app.UseAuthorization(); // L93
app.UseEndpoints(...) // L97
2.3 UseAuthenticationConfiguration() — registrado DEPOIS do terminal
Nuget — coezzion-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ário | Consequência |
|---|---|
Endpoint SEM [Authorize] | Lazy auth não dispara → HttpContext.User vazio → claim schema null |
| SignalR hub negotiate | UseAuthN() precisa rodar durante o handshake → não roda → #29 |
| Health checks com auth | MapHealthChecks sem [Authorize] não dispara lazy auth |
Middleware custom que lê HttpContext.User | User vazio antes do [Authorize] ser avaliado |
7. Serviços Afetados (padrão idêntico)
| Serviço | Startup.cs | ApiConfig.cs |
|---|---|---|
| checkout ✅ escopo | Startup.cs:70-74 | ApiConfig.cs:79,83 |
| cart ✅ escopo | Startup.cs:59-63 | ApiConfig.cs:79,83 |
| product ✅ escopo | Startup.cs:65-71 | ApiConfig.cs:84,86 |
| store ✅ escopo | Startup.cs:59-61 | ApiConfig.cs:93,97 |
| auth | Startup.cs:57-63 | Mesmo padrão |
| admin | Startup.cs | Mesmo padrão |
| push-notification | Startup.cs | Mesmo padrão |
| realtime | Startup.cs | Mesmo padrão |
| backoffice | Startup.cs | Mesmo padrão |
| reward | Startup.cs | Mesmo padrão |
| message | Startup.cs | Mesmo padrão |
| integration | Startup.cs | Mesmo padrão |
| crm | Startup.cs | Mesmo padrão |
| payments-reports | Startup.cs | Mesmo padrão |
| showcase | Startup.cs | Mesmo padrão |
| jobs | Startup.cs | Mesmo padrão |
| activation | Startup.cs | Mesmo padrão |