HIGH session fixationchimutual tls

Session Fixation in Chi with Mutual Tls

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

Session fixation occurs when an application forces or accepts a session identifier provided by the client. In Chi, this risk persists even when Mutual TLS (mTLS) is used for authentication, because mTLS authenticates the client to the server, but does not inherently bind the application session to the client certificate. If your Chi handler reuses a session token that was set before mTLS client verification, or accepts a session cookie from an unauthenticated initial request, an attacker can force a known session ID onto the user and later present the same session identifier after mTLS authentication completes.

Consider a Chi endpoint that reads an existing session cookie before requiring client certificate validation. An attacker can send a request with a guessed session_id cookie, and the application may associate that session with the authenticated client when the mTLS handshake succeeds. This creates a classic session fixation scenario: the client authenticates with a certificate, but the session was predetermined by the attacker. Because mTLS ensures the client holds the private key for the presented certificate, the server may trust the identity while still relying on an attacker-supplied session token.

The combination of Chi’s composable middleware and session management logic can inadvertently expose this risk if session initialization is not deferred until after successful client certificate verification. For example, if you initialize session state in an early middleware and later perform mTLS verification, the session remains tied to the pre-authentication request. Even when using mTLS, you should ensure that session creation or rotation occurs after certificate validation to prevent fixation.

Mutual Tls-Specific Remediation in Chi — concrete code fixes

Remediation centers on ensuring session state is established only after successful mTLS authentication and that session identifiers are rotated post-authentication. Below are concrete, syntactically correct Chi examples using clj-http–style certificate verification and the cheshire library for JSON handling. These examples assume you validate client certificates via trusted CA files.

Example 1: Deferring session creation until after mTLS verification

(ns myapp.handlers
  (:require [compojure.core :refer [defroutes GET POST]]
            [ring.util.http-response :as resp]
            [cheshire.core :as json]
            [buddy.auth.middleware :refer [wrap-authentication]]
            [buddy.auth.backends.token :refer [jws-backend]]))

(defn verify-client-cert [request]
  ;; In Chi, inspect the :ssl-client-cert key populated by your container/runtime.
  (when (:ssl-client-cert request)
    ;; Perform additional validation as needed (e.g., CN, SAN, CRL).
    (let [subject (:subject (:ssl-client-cert request))]
      (boolean (re-find #"CN=trusted-user" subject)))))

(def app
  (wrap-reload #'handler)
  (fn [request]
    (if (verify-client-cert request)
      ;; Proceed only after successful mTLS verification.
      (let [session-id (java.util.UUID/randomUUID) ; create fresh session after auth
            session {:session/id session-id
                     :identity (:subject (:ssl-client-cert request))
                     :created-at (java.time.Instant/now)}
            response (resp/ok (json/generate-string {:message "Authenticated"}))]
        (-> response
            (assoc-in [:cookies "session-id"] {:value (str session-id)
                                               :path "/"
                                               :http-only true
                                               :secure true})
            (assoc :session session)))
      (resp/unauthorized {:error "Client certificate required"}))))

Example 2: Rotating session identifier after mTLS authentication

(defn rotate-session [request]
  (if (verify-client-cert request)
    (let [old-session (:session request)
          new-session-id (java.util.UUID/randomUUID)
          new-session (assoc old-session :session/id new-session-id :rotated-at (java.time.Instant/now))]
      (-> (resp/ok {:message "Session rotated"})
          (assoc-in [:cookies "session-id"] {:value (str new-session-id)
                                             :path "/"
                                             :http-only true
                                             :secure true})
          (assoc :session new-session)))
    (resp/unauthorized {:error "Client certificate required"})))

Example 3: Middleware ordering to avoid pre-authentication session creation

(def app
  (-> routes-handler
      (wrap-session {:store (memory-store)}) ; Ensure session store is configured.
      (wrap-reload #'handler)))

;; Place mTLS verification before session-dependent routes.
(def secured-app
  (-> app
      (wrap-mtls-verify {:truststore "/path/to/truststore.jks"})
      (wrap-authentication {:handler verify-client-cert})))

These patterns emphasize that mTLS in Chi should be treated as client authentication, while session management must be explicitly tied to post-authentication events. By creating or rotating session identifiers only after verifying the client certificate, you eliminate the fixation vector even when mTLS is in use.

Frequently Asked Questions

Does mTLS alone prevent session fixation in Chi?
No. Mutual TLS authenticates the client but does not automatically bind the session to the certificate. If you create or accept session identifiers before mTLS verification, fixation remains possible. Always establish or rotate session state after successful client certificate validation.
How can I test for session fixation in Chi with mTLS?
Use the middleBrick CLI to scan your Chi endpoints: middlebrick scan . Provide requests that include a pre-set session cookie and a valid client certificate. Review the report for session fixation findings and ensure session creation occurs strictly after certificate verification.