Session Fixation with Mutual Tls
How Session Fixation Manifests in Mutual Tls
Session fixation attacks in Mutual Tls environments exploit the trust established through client certificate authentication while maintaining predictable session identifiers. Unlike basic session fixation where attackers force a known session ID onto victims, Mutual Tls session fixation combines certificate-based authentication with session management vulnerabilities.
// Vulnerable Mutual Tls session handling
public class VulnerableMutualTlsServlet extends HttpServlet {
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// Certificate already authenticated by container
X509Certificate[] certs = (X509Certificate[]) req.getAttribute(
"javax.servlet.request.X509Certificate");
// CRITICAL: Using predictable session ID after Mutual Tls auth
String sessionId = req.getParameter("session_id");
if (sessionId != null) {
req.getSession().invalidate();
req.getSession(true).setAttribute("session_id", sessionId);
}
// Proceed with authenticated session using client cert
handleAuthenticatedRequest(certs, req, resp);
}
}The vulnerability occurs when applications accept client certificates for authentication but then create sessions with predictable or user-controlled identifiers. An attacker can pre-generate a session ID, establish a Mutual Tls connection with their own certificate, and inject the session ID into the application. When the victim connects with their legitimate certificate, they inherit the attacker's session.
Mutual Tls session fixation also manifests through improper session binding. Applications may authenticate users via client certificates but fail to bind the session to the specific certificate presented. This allows session hijacking across different client certificates:
# Vulnerable Flask Mutual Tls endpoint
@app.route('/api/data')
@requires_client_cert
def vulnerable_endpoint():
# Certificate authentication passed, but session not bound to cert
session['user_id'] = get_user_from_cert() # Only stores user ID
# Attacker can now use this session with different certificate
return jsonify(get_sensitive_data())
The core issue is that Mutual Tls provides strong authentication but weak session isolation. Once authenticated, the application loses the binding between the specific client certificate and the session context, creating opportunities for fixation attacks.
Mutual Tls-Specific Detection
| Detection Method | Implementation | middleBrick Integration |
|---|---|---|
| Certificate Session Binding | Verify session contains certificate fingerprint | middleBrick scans for missing certificate binding |
| Session ID Predictability | Check for user-controlled or sequential IDs | middleBrick tests session ID generation patterns |
| Certificate Context Preservation | Ensure certificate context maintained throughout session | middleBrick validates certificate context handling |
Detecting session fixation in Mutual Tls requires examining how applications handle the authenticated certificate context. The primary detection method involves verifying that sessions are properly bound to the specific client certificate presented during authentication.
# middleBrick scan for Mutual Tls session fixation
middlebrick scan https://api.example.com --mutual-tls \
--cert client-cert.pem --key client-key.pem \
--ca ca-cert.pem --test-session-fixation
# Output includes:
# - Session ID generation analysis
# - Certificate binding verification
# - Session context preservation checks
middleBrick's Mutual Tls-specific detection examines the certificate attributes available in the request context and verifies whether the application maintains this binding throughout the session lifecycle. The scanner tests for predictable session identifiers and attempts to establish sessions with different certificates to verify proper isolation.
Key detection indicators include:
- Session IDs that are predictable, sequential, or user-controllable
- Absence of certificate fingerprint storage in session context
- Session data accessible across different client certificates
- Failure to validate certificate revocation status during session use
middleBrick performs active testing by establishing multiple Mutual Tls connections with different certificates and attempting to access shared session data, identifying fixation vulnerabilities through successful cross-certificate session access.
Mutual Tls-Specific Remediation
Remediating session fixation in Mutual Tls environments requires binding sessions to the specific client certificate and ensuring proper session identifier generation. The fundamental principle is maintaining the certificate context throughout the session lifecycle.
// Secure Mutual Tls session handling
public class SecureMutualTlsServlet extends HttpServlet {
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// Get authenticated certificate (already validated by container)
X509Certificate[] certs = (X509Certificate[]) req.getAttribute(
"javax.servlet.request.X509Certificate");
if (certs == null || certs.length == 0) {
resp.sendError(HttpServletResponse.SC_UNAUTHORIZED);
return;
}
X509Certificate clientCert = certs[0];
String certFingerprint = getCertificateFingerprint(clientCert);
// Create secure session with certificate binding
HttpSession session = req.getSession(true);
session.setAttribute("client_cert_fingerprint", certFingerprint);
session.setAttribute("client_cert_subject", clientCert.getSubjectDN().getName());
// Validate certificate binding on each request
validateCertificateBinding(session, clientCert);
handleAuthenticatedRequest(clientCert, req, resp);
}
private void validateCertificateBinding(HttpSession session, X509Certificate currentCert) {
String storedFingerprint = (String) session.getAttribute("client_cert_fingerprint");
String currentFingerprint = getCertificateFingerprint(currentCert);
if (!storedFingerprint.equals(currentFingerprint)) {
throw new SecurityException("Certificate binding violation");
}
}
}The remediation strategy involves three critical components: certificate fingerprint storage, session binding validation, and secure session identifier generation. Applications must store a unique identifier derived from the client certificate (such as a SHA-256 fingerprint) in the session context and validate this binding on each subsequent request.
# Secure Flask Mutual Tls endpoint
from flask import Flask, session, jsonify
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import padding
import hashlib
app = Flask(__name__)
app.secret_key = os.environ.get('SECRET_KEY')
@app.route('/api/data')
@requires_client_cert
def secure_endpoint():
# Get client certificate from request context
client_cert = get_client_certificate()
# Generate certificate fingerprint
cert_fingerprint = hashlib.sha256(
client_cert.public_bytes(serialization.Encoding.DER)
).hexdigest()
# Validate session certificate binding
if 'cert_fingerprint' in session:
if session['cert_fingerprint'] != cert_fingerprint:
return jsonify({'error': 'Certificate binding violation'}), 403
else:
# First request - establish session with certificate binding
session['cert_fingerprint'] = cert_fingerprint
session['user_id'] = get_user_from_cert(client_cert)
return jsonify(get_sensitive_data())
Additional remediation measures include implementing secure session identifier generation using cryptographically random values, enforcing certificate revocation checking throughout the session, and implementing proper session timeout and invalidation mechanisms when certificates change or expire.