HIGH token leakagechimutual tls

Token Leakage in Chi with Mutual Tls

Token Leakage in Chi with Mutual Tls — how this specific combination creates or exposes the vulnerability

Token leakage in a Chi application that also uses Mutual TLS (mTLS) occurs when authentication tokens or session identifiers are exposed in ways that bypass or weaken the guarantees provided by mTLS. Even though mTLS authenticates peers by verifying client certificates, tokens such as API keys, JWTs, or OAuth access tokens can still be mishandled in logs, error messages, or insecure transport configurations, effectively undermining the identity assurance that mTLS provides.

In Chi, this often happens when developers focus solely on transport-layer authentication (mTLS) and neglect application-layer token hygiene. For example, if a Chi handler logs incoming headers indiscriminately, an authorization token present in the Authorization or a custom header like x-api-key might be written to logs or error responses. Those artifacts can be accessed by unauthorized parties who compromise logging or monitoring systems. Even when mTLS ensures that only trusted clients can connect, leaked tokens enable attackers to impersonate legitimate users or services across trust boundaries, such as when logs are aggregated across environments.

Another specific scenario involves bidirectional streaming or long-lived connections in Chi where tokens are passed once during initial handshake logic but then cached or reused without additional validation. If the server caches a token in memory and the client certificate context is not strictly bound to that token, an attacker who gains access to the server process (e.g., via other vulnerabilities) might be able to associate that token with an authenticated mTLS session. This cross-correlation of identity layers is precisely why mTLS alone does not prevent token leakage; it secures channel establishment, not how the application stores or propagates tokens after the TLS session is established.

The risk is compounded when error handling in Chi exposes stack traces or request details containing tokens. For instance, if an exception includes a header value in its message and that message is returned in an HTTP 500 response, the token can be exfiltrated even when mTLS is correctly configured. Common frameworks like Chi do not automatically redact sensitive headers; developers must explicitly sanitize inputs and outputs. Without such controls, mTLS protects the pipe but not the content within it, leaving tokens vulnerable through implementation mistakes rather than protocol weaknesses.

Real-world attack patterns mirror these concerns. For example, an unauthenticated attacker might probe an endpoint that requires mTLS but relies on a token for fine-grained authorization. If the token is leaked through verbose error messages or misconfigured logging, the attacker can bypass authorization checks despite the mTLS requirement. This aligns with common classes of vulnerabilities described in the OWASP API Top 10, such as Broken Object Level Authorization (BOLA), where exposure of identifiers or tokens enables privilege escalation even when transport authentication is intact.

Because mTLS ensures client identity at the connection level, it can create a false sense of security. Teams may assume that requiring client certificates eliminates the need for rigorous token management. middleBrick scans specifically test for such gaps by checking whether endpoints leak tokens in responses or logs, even when mTLS is in place. This is important because compliance frameworks such as OWASP API Security Top 10, SOC2, and GDPR expect that confidentiality protections are applied consistently across layers, not just at the network boundary.

Mutual Tls-Specific Remediation in Chi — concrete code fixes

To prevent token leakage in Chi while using Mutual TLS, remediation must focus on strict separation between transport identity and application tokens, careful handling of headers, and robust error management. Below are concrete, idiomatic Chi and middleware examples that address these concerns.

1. Explicitly strip or redact sensitive headers before logging

Ensure that no token-bearing headers are logged. Use Chi middleware to remove or mask sensitive keys before any logging or error propagation occurs.

open System
open Giraffe
open Microsoft.AspNetCore.Http

let sanitizeHeaders (next: HttpFunc) (ctx: HttpContext) =
    let headers = ctx.Request.Headers
    if headers.ContainsKey "Authorization" then
        ctx.Request.Headers.["Authorization"] <- "[Redacted]"
    if headers.ContainsKey "x-api-key" then
        ctx.Request.Headers.["x-api-key"] <- "[Redacted]"
    next ctx

let app = 
    choose [
        GET >=> route "/health" >=> sanitizeHeaders >=> text "OK"
        set_http_header "X-Content-Type-Options" "nosniff"
        // other routes
    ]

2. Bind tokens to mTLS context and validate on each request

Do not assume that a valid client certificate is sufficient. Extract a token (e.g., from a custom header) and verify it against the certificate subject or a mapped identity before proceeding.

open System.Security.Cryptography.X509Certificates

let validateTokenAgainstCert (cert: X509Certificate2) (token: string) : bool =
    // Example: ensure token contains a subject identifier present in the cert
    cert.Subject.Contains(token, StringComparison.OrdinalIgnoreCase)

let requireTokenWithMtls (next: HttpFunc) (ctx: HttpContext) =
    let cert = ctx.Connection.ClientCertificate
    if cert = null then
        setStatusCode 400 >=> text "Client certificate required" ctx
    else
        let token = ctx.Request.Headers.["x-api-key"]
        if String.IsNullOrEmpty token || not (validateTokenAgainstCert cert token) then
            setStatusCode 401 >=> text "Invalid token for certificate" ctx
        else
            next ctx

let app = 
    choose [
        GET >=> route "/secure" >=> requireTokenWithMtls >=> text "Authorized"
    ]

3. Avoid returning sensitive headers in error responses

Customize exception handling so that tokens are never reflected in error bodies. Use Giraffe’s error handling pipeline to sanitize responses.

let errorHandler (ex: Exception) (ctx: HttpContext) =
    let response = ctx.Response
    response.StatusCode <- 500
    response.ContentType <- "application/json; charset=utf-8"
    // Never include headers or raw input in the response body
    let errorJson = "{ \"error\": \"Internal server error\" }"
    bodyFromString errorJson >=> ctx

let appWithErrorHandling =
    choose [
        try_with errorHandler [
            GET >=> route "/data" >=> requireTokenWithMtls >=> text "Secret data"
        ]
    ]

4. Enforce HTTPS and secure transport settings alongside mTLS

Even when using mTLS, ensure that tokens are never transmitted over insecure channels. Configure Chi to reject HTTP and enforce strict transport security headers.

let enforceHttps (next: HttpFunc) (ctx: HttpContext) =
    if not ctx.Request.IsHttps then
        setStatusCode 400 >=> text "HTTPS required" ctx
    else
        next ctx

let app = 
    choose [
        GET >=> route "/secure" >=> enforceHttps >=> requireTokenWithMtls >=> text "OK"
        set_http_header "Strict-Transport-Security" "max-age=31536000; includeSubDomains"
    ]

5. Rotate and scope tokens independently of certificates

Use short-lived tokens and rotate them independently of client certificates. Do not embed tokens in certificate attributes. Instead, validate tokens via a secure introspection endpoint or local validation logic that is decoupled from the certificate chain.

let isValidToken (token: string) : bool =
    // Call an introspection endpoint or validate signature locally
    token.StartsWith("valid_", StringComparison.Ordinal)

let requireValidToken (next: HttpFunc) (ctx: HttpContext) =
    let token = ctx.Request.Headers.["x-api-key"]
    if String.IsNullOrEmpty token || not (isValidToken token) then
        setStatusCode 403 >=> text "Forbidden token" ctx
    else
        next ctx

let app = 
    choose [
        POST >=> route "/action" >=> requireValidToken >=> text "Action performed"
    ]

By combining these practices, you ensure that token leakage risks are minimized even when mTLS is used. middleBrick can help verify that these controls are effective by scanning endpoints for exposed tokens, even when mTLS is enforced.

Frequently Asked Questions

Does mTLS alone prevent token leakage in Chi applications?
No. Mutual TLS authenticates peers at the transport layer but does not protect application-layer tokens such as API keys or JWTs. Tokens can still be leaked through logs, error messages, or insecure handling in Chi handlers. You must explicitly sanitize headers and enforce token validation alongside mTLS.
Can middleBrick detect token leakage in environments that use Mutual TLS?
Yes. middleBrick tests endpoints for token exposure in responses, logs, and error messages regardless of whether mTLS is used. It checks whether authorization tokens appear where they should be hidden and reports findings with remediation guidance.