HIGH rate limiting bypassaspnetbearer tokens

Rate Limiting Bypass in Aspnet with Bearer Tokens

Rate Limiting Bypass in Aspnet with Bearer Tokens

Rate limiting in ASP.NET is commonly implemented to protect endpoints from abuse by capping the number of requests a client can make within a time window. When authentication relies on Bearer tokens, misconfigurations can allow a single token (or token class) to bypass intended rate limits, enabling denial-of-service or resource exhaustion attacks. This specific combination—rate limiting plus Bearer token authentication—can expose vulnerabilities when token identity is not consistently enforced by the rate limiter.

In ASP.NET, developers often use policies like AddPolicy and AddAuthentication with JWT Bearer schemes. If the rate limiter is applied before the authentication middleware resolves the token, or if it applies limits based on IP alone rather than on the authenticated principal, an attacker can make many requests with a valid token while the identity is not considered for limiting. For example, if the rate limiter uses IpRateLimitMiddleware configured to track by IP address only, a shared or compromised Bearer token used from multiple sources may not be throttled per token, allowing abuse across client IPs.

Another bypass pattern occurs when the rate limiter is scoped to controller actions or route templates that do not require authentication, while the Bearer token is only required for a subset of endpoints. An attacker can probe unauthenticated endpoints to exhaust quotas, then use the Bearer token to access protected resources without being constrained by the same limits. This violates the principle that rate limits should apply to authenticated requests on a per-identity basis to prevent credential-based abuse.

ASP.NET Core’s default in-memory rate limiting via AddRateLimiter can also be misconfigured if policies are not explicitly bound to authentication requirements. Consider the following typical setup:

// Program.cs
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(options =>
    {
        options.Authority = "https://example.auth0.com/";
        options.Audience = "api://example-api";
    });

builder.Services.AddRateLimiter(options =>
{
    options.GlobalLimiter = PartitionedRateLimiter.Create<HttpContext, string>(
        context => RateLimitPartition.GetSlidingWindowLimiter(
            partitionKey: context.User.Identity?.Name ?? context.Connection.RemoteIpAddress?.ToString(),
            factory: _ => new SlidingWindowRateLimiterOptions
            {
                PermitLimit = 100,
                Window = TimeSpan.FromMinutes(1)
            }));
});

In this example, if context.User.Identity is null before authentication completes, the partition key may fall back to IP, allowing token misuse across IPs. Attackers can also probe endpoints that do not enforce the [Authorize] attribute, effectively bypassing token-based rate controls. The risk is elevated when token validation is delayed or when policies are not consistently enforced across all routes.

To detect this class of issue, scanners test whether rate limits are enforced per authenticated identity rather than only per IP or per endpoint. They check whether multiple requests with the same Bearer token from different IPs are throttled, and whether unauthenticated paths can be abused to circumvent limits intended for authenticated traffic.

Bearer Tokens-Specific Remediation in Aspnet

Remediation focuses on ensuring that rate limiting is applied consistently to authenticated identities and that Bearer tokens are validated before limits are applied. In ASP.NET, you should bind rate limiter partitions to the authenticated principal so that each token is subject to its own quota. Avoid relying on IP-based limits when token-based authentication is in use.

First, enforce authentication before rate limiting by ordering middleware correctly and using the [Authorize] attribute on controllers or actions. Second, define rate limiter policies that use the user identity or token identifier as the partition key. The following example demonstrates a secure configuration:

// Program.cs
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(options =>
    {
        options.Authority = "https://example.auth0.com/";
        options.Audience = "api://example-api";
        options.TokenValidationParameters = new TokenValidationParameters
        {
            ValidateIssuer = true,
            ValidateAudience = true,
            ValidateLifetime = true,
            ValidateIssuerSigningKey = true
        };
    });

builder.Services.AddAuthorization();

builder.Services.AddRateLimiter(options =>
{
    options.GlobalLimiter = PartitionedRateLimiter.Create<HttpContext, string>(
        context =>
        {
            var userId = context.User.Identity?.IsAuthenticated == true
                ? context.User.Identity.Name
                : context.Request.Headers["Authorization"].ToString().Replace("Bearer ", string.Empty);
            return RateLimitPartition.GetSlidingWindowLimiter(
                partitionKey: userId ?? context.Connection.RemoteIpAddress?.ToString() ?? "anonymous",
                factory: _ => new SlidingWindowRateLimiterOptions
                {
                    PermitLimit = 100,
                    Window = TimeSpan.FromMinutes(1)
                });
        });
});

This configuration ensures that once the Bearer token is validated, the user identity is available for partitioning. If the identity cannot be resolved, the code falls back to extracting the token from the Authorization header as a last resort, which is less precise but still better than IP-only partitioning. Always require authentication for endpoints that enforce rate limits to prevent unauthenticated bypass.

Additionally, apply the [Authorize] attribute explicitly to controllers or actions that require both authentication and rate control:

[ApiController]
[Route("api/[controller]")]
[Authorize] // Ensures a valid Bearer token is required
public class SecureController : ControllerBase
{
    [HttpGet("data")]
    public IActionResult GetData()
    {
        return Ok(new { message = "Rate-limited and authenticated" });
    }
}

For scenarios where different clients share a token, consider augmenting the partition key with tenant or client identifiers extracted from the token claims to further reduce collision risks. middleBrick scans can verify whether rate limiting is applied per authenticated identity and flag configurations that rely solely on IP or unauthenticated paths, providing prioritized findings with severity and remediation guidance.

Related CWEs: resourceConsumption

CWE IDNameSeverity
CWE-400Uncontrolled Resource Consumption HIGH
CWE-770Allocation of Resources Without Limits MEDIUM
CWE-799Improper Control of Interaction Frequency MEDIUM
CWE-835Infinite Loop HIGH
CWE-1050Excessive Platform Resource Consumption MEDIUM

Frequently Asked Questions

Can an attacker bypass rate limits by rotating IPs while using a single Bearer token?
Yes, if the rate limiter does not include the authenticated identity or token identifier in its partition key and relies only on IP addresses, an attacker can rotate source IPs to bypass limits while using the same Bearer token. Ensure the partition key uses the user identity or extracted token value.
Does middleBrick test for Bearer token-specific rate limiting bypasses?
middleBrick runs 12 security checks in parallel, including Rate Limiting and Authentication, and cross-references OpenAPI specs with runtime findings to identify whether rate limits are enforced per authenticated identity for Bearer token scenarios.