Type Confusion in Aspnet with Bearer Tokens
Type Confusion in Aspnet with Bearer Tokens — how this specific combination creates or exposes the vulnerability
Type confusion in an ASP.NET API context occurs when an application deserializes or casts data into an incorrect type, allowing an attacker to manipulate object behavior. When bearer tokens are involved, the risk amplifies if token handling logic is coupled with polymorphic deserialization or dynamic type resolution. For example, an endpoint that accepts a JSON payload and deserializes it into a base class without strict type validation may inadvertently map attacker-controlled fields into token-related properties, such as scopes or roles.
Consider an ASP.NET Core Web API that uses bearer token authentication via the AddAuthentication(JwtBearerDefaults.AuthenticationScheme) scheme. If the application also includes endpoints that accept user-supplied input to determine how token metadata is processed (e.g., mapping claims or roles), and that input is not strictly typed, an attacker may supply a crafted JSON structure that causes the runtime to treat a string claim as a more privileged object type. This type confusion can lead to privilege escalation, bypass of authorization checks, or token misuse.
In practice, this can manifest when custom token validation logic uses reflection or dynamic object graphs. Suppose an endpoint receives a token and a user-controlled TypeHint field that influences how the token payload is interpreted. If the server uses JsonConvert.DeserializeObject(json, Type.GetType(typeHint)) without validating or restricting the type, an attacker could supply a malicious type such as System.Security.Claims.ClaimsPrincipal or a custom class that alters authorization decisions. Because bearer tokens often carry sensitive identity and scope information, confusion between expected token metadata types and attacker-supplied types can expose internal structures or enable unauthorized access.
Real-world patterns include misconfigured polymorphic deserialization in controllers that bind token-related DTOs alongside user-controlled type discriminators. This aligns with common weaknesses in input validation and improper handling of structured data, as noted in the OWASP API Security Top 10. Attackers may probe such endpoints with manipulated tokens and type hints to trigger unexpected behavior, such as accessing admin-only claims or evading scope checks.
middleBrick detects these risks through its 12 parallel security checks, including Input Validation and Property Authorization analyses. By correlating OpenAPI/Swagger specifications with runtime behavior, the scanner identifies endpoints where type handling intersects with bearer token usage, providing prioritized findings and remediation guidance without requiring authentication or internal architecture insight.
Bearer Tokens-Specific Remediation in Aspnet — concrete code fixes
Remediation focuses on strict type handling, avoiding dynamic deserialization of user-controlled data, and isolating token processing from input-driven type resolution. Below are concrete code examples for secure ASP.NET Core API practices.
1. Avoid dynamic type resolution for token payloads
Do not use Type.GetType or similar mechanisms with user-supplied values. Instead, deserialize into concrete, expected types.
// Insecure: dynamic type resolution based on user input
// string typeHint = userInput["typeHint"];
// var obj = JsonConvert.DeserializeObject(userPayload, Type.GetType(typeHint));
// Secure: deserialize into a known DTO
public class TokenPayloadDto {
public string Sub { get; set; }
public string[] Scopes { get; set; }
public string Role { get; set; }
}
var payload = JsonConvert.DeserializeObject<TokenPayloadDto>(userPayload);
2. Use strongly typed models for claims and authorization
Define explicit models for claims and roles extracted from bearer tokens, and avoid mapping dynamic or untrusted input into these models.
public class ClaimsPrincipalDto {
public string Name { get; set; }
public string Email { get; set; }
public List<string> Roles { get; set; }
}
// Bind only known properties with [Bind] or manual mapping
[HttpPost("claims")]
public IActionResult ProcessClaims([Bind("Name,Email,Roles")] ClaimsPrincipalDto claimsDto) {
// Safe: uses only explicitly bound properties
return Ok(new { claimsDto.Name, claimsDto.Roles });
}
3. Enforce strict input validation and schema checks
Validate incoming JSON against a defined schema and reject unexpected fields, especially those that could influence type selection or token interpretation.
services.AddControllers()
.AddJsonOptions(options => {
options.JsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
// Enforce strict mode if using System.Text.Json
options.JsonSerializerOptions.IncludeFields = false;
});
// Optionally use a library like FluentValidation for payload validation
public class TokenPayloadValidator : AbstractValidator<TokenPayloadDto> {
public TokenPayloadValidator() {
RuleFor(x => x.Scopes).NotNull().NotEmpty();
RuleFor(x => x.Role).Must(r => new[] { "user", "admin" }.Contains(r));
}
}
4. Isolate authentication logic from user-controlled routing
Keep bearer token validation within the authentication pipeline and avoid exposing token processing to endpoints that accept arbitrary type hints or polymorphic data.
app.UseAuthentication();
app.UseAuthorization();
// Do not create endpoints that reinterpret token metadata based on user input
app.UseEndpoints(endpoints => {
endpoints.MapControllers();
// Avoid: endpoints.MapPost("/token/{type}", ...);
});
5. Leverage built-in JWT validation and avoid custom parsing
Rely on ASP.NET Core’s JWT Bearer handler to validate tokens, and do not manually parse or reinterpret token contents based on external input.
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options => {
options.TokenValidationParameters = new TokenValidationParameters {
ValidateIssuer = true,
ValidIssuer = "https://auth.example.com",
ValidateAudience = true,
ValidAudience = "api.example.com",
ValidateLifetime = true,
ClockSkew = TimeSpan.Zero
};
});Related CWEs: inputValidation
| CWE ID | Name | Severity |
|---|---|---|
| CWE-20 | Improper Input Validation | HIGH |
| CWE-22 | Path Traversal | HIGH |
| CWE-74 | Injection | CRITICAL |
| CWE-77 | Command Injection | CRITICAL |
| CWE-78 | OS Command Injection | CRITICAL |
| CWE-79 | Cross-site Scripting (XSS) | HIGH |
| CWE-89 | SQL Injection | CRITICAL |
| CWE-90 | LDAP Injection | HIGH |
| CWE-91 | XML Injection | HIGH |
| CWE-94 | Code Injection | CRITICAL |