HIGH header injectionaspnetbearer tokens

Header Injection in Aspnet with Bearer Tokens

Header Injection in Aspnet with Bearer Tokens — how this specific combination creates or exposes the vulnerability

Header Injection in ASP.NET when Bearer Tokens are used centers on improper handling of user-supplied input that reaches HTTP headers, particularly the Authorization header or custom headers that influence authentication flow. When an application builds or forwards headers using unvalidated data, an attacker can inject additional header lines or manipulate token boundaries, leading to token leakage, request smuggling, or authorization bypass.

In ASP.NET, the framework typically parses the Authorization header as Bearer <token>. If developer code concatenates strings to form this header using input from query strings, form fields, or other sources without strict validation, newline characters (e.g., \r\n) can be injected. For example, an attacker may supply a token value containing \r\nX-Forwarded-For: bad.example.com, causing the server to treat injected lines as additional headers. This can change routing, enable host header poisoning, or expose the token to downstream services that process the forwarded request.

Another scenario involves logging or diagnostic code that echoes the Authorization header. If the header value is reflected in responses or logs without sanitization, an injected newline can be used to break out of log formats and inject fake entries or even script content in log viewers that render output in a browser. Because Bearer Tokens often carry high privileges, leakage via header injection can lead to account compromise or lateral movement within a microservice architecture where tokens are passed between components.

ASP.NET Core’s use of the AuthenticationHandler<TOptions> pipeline means developers may inadvertently trust headers set by reverse proxies or API gateways. If the application does not explicitly validate the format of the Authorization header and relies on the presence of the Bearer prefix, malformed tokens or injected control characters may bypass intended validation logic. The framework’s default behavior does not automatically reject newline characters in header values when they come from untrusted sources, so it is up to the developer to enforce strict input rules.

OpenAPI/Swagger specifications that define security schemes as type: http with scheme: bearer can give a false sense of safety if runtime validation is weak. The spec may declare that a Bearer token is required, but if the application does not sanitize incoming headers before constructing outgoing requests to downstream services, injection remains possible. Cross-referencing spec definitions with runtime findings is important to detect mismatches between declared authentication flows and actual behavior, a capability offered by scanners that map such findings to frameworks like OWASP API Top 10.

Real-world impact includes token exfiltration via injected headers that forward credentials to an attacker-controlled endpoint, or session fixation when an injected header alters the routing path of authorized requests. Because Bearer Tokens are often reused across multiple services, a single injection point can have wide-reaching consequences. Effective mitigation requires canonicalizing headers, rejecting unexpected control characters, and validating the entire Authorization header format rather than only the token portion.

Bearer Tokens-Specific Remediation in Aspnet — concrete code fixes

Remediation focuses on strict validation and canonicalization of the Authorization header in ASP.NET. Never construct Authorization headers by concatenating user input. Instead, use the framework’s built-in authentication mechanisms and validate token format before use.

1. Validate Bearer Token format explicitly

Ensure the Authorization header strictly follows Bearer <token> and reject any header containing newline or carriage return characters. Use regular expressions to enforce a safe token character set and length.

using System.Text.RegularExpressions;
using Microsoft.AspNetCore.Http;

public static class HeaderValidation
{
    private static readonly Regex BearerTokenRegex = new Regex(@"^Bearer [A-Za-z0-9\-._~+/=]+$", RegexOptions.Compiled);

    public static bool IsValidBearerHeader(string authorization)
    {
        if (string.IsNullOrWhiteSpace(authorization))
            return false;
        // Reject newlines or carriage returns which enable header injection
        if (authorization.Contains("\r") || authorization.Contains("\n"))
            return false;
        return BearerTokenRegex.IsMatch(authorization);
    }
}

Use this validator in middleware or within a custom authentication handler before processing the token.

2. Reject unexpected headers and canonicalize forwarded headers

If your ASP.NET application forwards requests to downstream services, do not forward headers derived from untrusted input. Explicitly build the outgoing Authorization header using a validated token only.

using System.Net.Http;
using System.Threading.Tasks;

public async Task<HttpResponseMessage> ForwardRequestAsync(string userSuppliedToken, HttpClient client)
{
    if (!HeaderValidation.IsValidBearerHeader($"Bearer {userSuppliedToken}"))
    {
        throw new HttpRequestException("Invalid Authorization header");
    }

    var request = new HttpRequestMessage(HttpMethod.Get, "https://api.example.com/resource");
    // Use the validated token directly; do not concatenate or forward other headers from the original request
    request.Headers.Add("Authorization", $"Bearer {userSuppliedToken}");
    return await client.SendAsync(request);
}

3. Avoid echoing Authorization headers in responses or logs

Ensure logging frameworks do not accidentally include the full Authorization header. Redact or omit the header when recording diagnostics.

logger.LogInformation("Request received for userId {UserId}", userId);
// Do NOT log authorizationHeader variable

4. Use ASP.NET Core built-in authentication when possible

Rely on AddAuthentication and AddJwtBearer so the framework handles Bearer token validation and rejects malformed headers automatically.

services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(options =>
    {
        options.TokenValidationParameters = new TokenValidationParameters
        {
            ValidateIssuer = true,
            ValidIssuer = "https://auth.example.com",
            ValidateAudience = true,
            ValidAudience = "api-resource",
            ValidateLifetime = true
        };
    });

5. Reject control characters at the edge

Configure Kestrel or your reverse proxy to reject requests containing newline characters in header names or values. This complements application-level validation and reduces reliance on developer discipline alone.

Frequently Asked Questions

How can I test if my ASP.NET endpoint is vulnerable to Bearer token header injection?
Send a request with an Authorization header containing newline characters (e.g., 'Bearer abc\r\nX-Forwarded-For: malicious.com') and observe whether the server processes injected headers or reflects them in responses. Use a proxy or scanner to verify that the injected lines do not alter routing or appear in logs.
Does using OpenAPI specs guarantee protection against header injection in ASP.NET?
No. OpenAPI/Swagger definitions declare authentication intent but do not enforce runtime validation. If ASP.NET code constructs headers from untrusted input, injection is possible regardless of the spec. Validate and canonicalize headers in code and use the framework’s authentication handlers to mitigate risk.