HIGH crlf injectionaspnetmutual tls

Crlf Injection in Aspnet with Mutual Tls

Crlf Injection in Aspnet with Mutual Tls

Crlf Injection occurs when an attacker can inject a carriage return (CR, \r) and line feed (\n) sequence into a header or status line, causing the server to prematurely terminate a line and potentially inject additional headers or split responses. In ASP.NET applications, this often manifests through user-controlled inputs such as query strings, headers, or cookies that are reflected into response headers without proper sanitization. When Mutual Transport Layer Security (Mutual TLS) is enforced, the client presents a certificate during the TLS handshake and the server validates it before the application layer processes requests. While Mutual TLS strengthens authentication and ensures that only trusted clients can initiate connections, it does not alter how HTTP messages are parsed. Consequently, if an ASP.NET application constructs response headers using unchecked input, the presence of \r\n sequences can still lead to response splitting, HTTP response smuggling, or header injection, even when Mutual TLS is in place.

For example, consider an endpoint that echoes a client-supplied value into a custom response header. If the input contains %0D%0A (URL-encoded CR LF) and the developer does not sanitize it, the following can occur:

// Unsafe reflection of user input into a header in ASP.NET Core
var userValue = Request.Headers["X-Custom"].ToString();
Response.Headers.Add("X-Additional", userValue);

An attacker could provide a value like injected\r\nX-Content-Type-Options: nosniff, resulting in duplicated or injected headers. Because Mutual TLS ensures a trusted client identity, developers may assume the request is safe and skip validation, inadvertently creating a blind spot. The risk is compounded when the application uses HTTP/2, where header compression and multiplexing may obscure injection effects. Moreover, logs and monitoring systems may record the request as authenticated due to the successful Mutual TLS handshake, delaying detection of the injection path. The combination of strong client authentication and insufficient output encoding creates a scenario where trust boundaries are misinterpreted, allowing an attacker to manipulate protocol-level behavior despite encrypted transport.

Mutual Tls-Specific Remediation in Aspnet

Remediation focuses on strict input validation and canonicalization of any data that influences HTTP headers, independent of the authentication mechanism. Never reflect untrusted input into headers, and if unavoidable, enforce a strict allowlist of characters and percent-encode potentially dangerous symbols. In ASP.NET, configure Kestrel to require and validate client certificates, and ensure the certificate validation logic is explicit and does not implicitly trust the presence of a certificate.

Example of configuring Mutual TLS in ASP.NET Core with explicit certificate validation:

// Program.cs - Enabling and validating client certificates
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel(serverOptions =>
{
    serverOptions.ListenAnyIP(5001, listenOptions =>
    {
        listenOptions.UseHttps(httpsOptions =>
        {
            httpsOptions.ServerCertificate = new X509Certificate2("server.pfx", "password");
            httpsOptions.ClientCertificateMode = ClientCertificateMode.RequireCertificate;
            httpsOptions.AllowedCertificateTypes = CertificateTypes.All;
            httpsOptions.RemoteCertificateValidationCallback = (sender, cert, chain, errors) =>
            {
                // Perform strict validation: check thumbprint, issuer, policy, etc.
                if (cert is null) return false;
                if (cert.GetCertDateString() < DateTime.UtcNow.ToString()) return false;
                // Example: allow only specific thumbprint for testing
                const string allowedThumbprint = "A1B2C3D4E5F6...";
                return cert.GetCertHashString().Replace(":", "").Equals(allowedThumbprint, StringComparison.OrdinalIgnoreCase);
            };
        });
    });
});

On the application side, sanitize headers using a defensive helper that removes or encodes CR and LF characters:

// Header sanitizer utility
public static class HeaderSanitizer
{
    private static readonly Regex CrlfRegex = new(@"[\r\n]", RegexOptions.Compiled);
    public static string Sanitize(string input) => CrlfRegex.Replace(input, string.Empty);
}

Apply it before adding values to response headers:

var userValue = Request.Headers["X-Custom"].ToString();
var safeValue = HeaderSanitizer.Sanitize(userValue);
Response.Headers.Add("X-Additional", safeValue);

Additionally, adopt a defense-in-depth approach by enabling security headers such as Content-Security-Policy and X-Content-Type-Options, and validate the integrity of any client certificates against revocation lists. Regularly test header handling using tools that can inject CR LF sequences and verify that responses do not split or leak sensitive information.

Frequently Asked Questions

Does Mutual TLS prevent Crlf Injection in ASP.NET?
No. Mutual TLS authenticates the client and ensures encrypted transport, but it does not sanitize user input that flows into HTTP headers. If user-controlled data containing CR or LF characters is reflected into headers without validation, Crlf Injection remains possible.
How can I test for Crlf Injection in an API protected by Mutual TLS?
Use a proxy that can present a valid client certificate while injecting CR LF sequences into headers or query parameters. Observe whether the response contains duplicated headers or altered status lines to confirm whether the injection vector is present.