HIGH session fixationaspnetmutual tls

Session Fixation in Aspnet with Mutual Tls

Session Fixation in Aspnet with Mutual Tls — how this specific combination creates or exposes the vulnerability

Session fixation occurs when an application accepts a session identifier provided by the client without validating or reissuing it after authentication. In ASP.NET applications using Mutual TLS (mTLS), the presence of a client certificate can create a false sense of strong authentication while the server still relies on a predictable or reusable session token. If the server issues the same session ID before and after login, an attacker who knows or can guess that ID can hijack the authenticated session, even when mTLS binds the connection to a client certificate.

With mTLS, the client presents a certificate during the TLS handshake, and the server can map the certificate to a user or authorization context. However, if session establishment happens before authentication (for example, creating a session cookie based on the certificate thumbprint but not reissuing a new session identifier after successful login), the session ID remains tied to the pre‑auth state. An attacker who can force a known session ID (e.g., via a URL or subdomain that shares cookies) can later authenticate with their own certificate, and the server may still treat the session as belonging to the original user because it associates the session ID with the certificate presented at login.

ASP.NET Core’s default session and authentication mechanisms do not automatically reissue session identifiers after authentication when mTLS is used. If the application uses cookie-based authentication with a static session key and does not call RenewAuthCookie or explicitly regenerate the session identifier, the same cookie value persists across the authentication boundary. This creates a window where the session identifier is predictable or shared across certificate-bound contexts. Additionally, if the server validates the client certificate but does not bind the session securely to a fresh identifier, deserialization or mapping logic that relies on certificate fields without additional entropy can be abused to fixate a session.

Real-world examples include scenarios where the server uses the certificate’s subject or thumbprint to initialize a session token without salting it with a server-side random value. In such cases, an attacker can induce a victim to use a known session ID (for instance, via a crafted link that sets a cookie), and after the victim authenticates with mTLS, the attacker can reuse that session ID. Although mTLS prevents many network-level attacks, it does not mitigate application-level session fixation when the server does not treat authentication as a session reset event.

To detect this during a middleBrick scan, the unauthenticated checks test whether session identifiers are reissued after authentication and whether session binding incorporates fresh entropy rather than relying solely on TLS-level attributes. The scanner evaluates cookie attributes, authentication middleware configuration, and whether the application explicitly calls methods to renew the authentication ticket or session token when using ASP.NET Core’s authentication stack.

Mutual Tls-Specific Remediation in Aspnet — concrete code fixes

Remediation focuses on ensuring that authentication resets the session identifier and binds the session securely to post‑login state, independent of the TLS session attributes. In ASP.NET Core, you should explicitly renew the authentication cookie or issue a new session token after successful mTLS authentication, and avoid deriving session identifiers directly from certificate fields.

Example: Configure authentication to require mTLS and renew the cookie after login.

// Program.cs or Startup configuration
builder.Services.AddAuthentication(options =>
{
    options.DefaultAuthenticateScheme = "MutualTls";
    options.DefaultChallengeScheme = "MutupalTls";
    options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
})
.AddCookie(CookieAuthenticationDefaults.AuthenticationScheme, options =>
{
    options.Cookie.Name = "session_auth";
    options.Cookie.HttpOnly = true;
    options.Cookie.SecurePolicy = CookieSecurePolicy.Always;
    options.ExpireTimeSpan = TimeSpan.FromMinutes(30);
    options.SlidingExpiration = true;
})
.AddMutualTls(options =>
{
    options.AllowedCertificateTypes = AllowedCertificateTypes.All;
    options.RevocationMode = X509RevocationMode.NoCheck;
    // map client certificate to claims as needed
    options.Events = new MutualTlsEvents
    {
        OnCertificateValidated = context =>
        {
            var claims = new List<Claim>
            {
                new Claim(ClaimTypes.NameIdentifier, context.ClientCertificate.Thumbprint),
                // map certificate fields to claims, but do not use them as session IDs
            };
            var identity = new ClaimsIdentity(claims, context.Scheme.Name);
            context.Principal = new ClaimsPrincipal(identity);
            context.Success();
            return Task.CompletedTask;
        }
    };
});

// After successful authentication, renew the cookie to bind a fresh session identifier
app.UseAuthentication();
app.UseAuthorization();
app.Use(async (context, next) =>
{
    if (context.User.Identity?.IsAuthenticated == true)
    {
        // Ensure a fresh authentication ticket is issued after mTLS validation
        await context.SignInAsync(
            CookieAuthenticationDefaults.AuthenticationScheme,
            new ClaimsPrincipal(context.User.Identity),
            new AuthenticationProperties { IsPersistent = false, ExpiresUtc = DateTimeOffset.UtcNow.AddMinutes(30) });
    }
    await next();
});

Ensure that session identifiers are not derived from certificate thumbprints or subjects. Instead, rely on server-side random values and bind them to claims stored in the authenticated ticket. Use short-lived cookies with Secure, HttpOnly, and SameSite=Strict where applicable, and avoid reusing pre‑auth session tokens post‑login.

In the dashboard, middleBrick flags missing session reissuance after authentication in mTLS-enabled endpoints. The CLI can be used to verify remediation by scanning the endpoint before and after applying the cookie renewal logic, ensuring that session identifiers change after authentication.

Frequently Asked Questions

Does mTLS alone prevent session fixation in ASP.NET?
No. mTLS binds the connection to a client certificate but does not automatically reset session identifiers at authentication. If the server reuses the same session ID before and after login, fixation remains possible. Explicit session reissuance after authentication is required.
How can I verify that my ASP.NET app properly renews sessions with mTLS?
Use the middleBrick CLI to scan the endpoint before and after authentication and compare session identifiers. Ensure the application calls authentication ticket renewal methods after mTLS validation and does not derive session tokens directly from certificate fields.