Denial Of Service in Chi with Mutual Tls
Denial Of Service in Chi with Mutual Tls — how this specific combination creates or exposes the vulnerability
Denial of Service (DoS) in the context of a Chi web service with Mutual TLS (mTLS) involves scenarios where legitimate or malicious traffic overwhelms the server, making it unavailable to valid users. mTLS requires both client and server to present valid certificates, which adds handshake overhead. If connection limits, timeouts, or request handling are not carefully tuned, an attacker can exploit this by opening many concurrent TLS handshakes or sending slow/malformed requests during the TLS negotiation phase, exhausting server resources.
Chi routes are compiled at startup and are typically very fast; however, DoS risks shift to the transport and connection-management layer when mTLS is enabled. For example, an attacker might send many incomplete ClientHello messages or repeatedly renegotiate sessions to keep connections open, consuming memory and file descriptors. Similarly, large or numerous HTTP/2 streams without proper request limits can saturate the server even when mTLS is correctly configured. Since Chi does not provide built-in DoS protections out of the box, you must enforce limits around concurrent connections, request body size, idle timeouts, and stream counts to reduce the attack surface in mTLS deployments.
Real-world attack patterns relevant to this setup include HTTP request smuggling techniques that can bypass expected routing when mTLS is improperly terminated, and resource exhaustion via many simultaneous authenticated connections (each requiring certificate validation). These map to OWASP API Top 10 categories such as API4:2023 — Improper Resource Limitation and API7:2023 — Authentication Rate Limiting. Using middleBrick’s 12 security checks, a scan can surface missing rate limiting, missing request size caps, and missing connection caps that would otherwise allow DoS against a Chi service with mTLS.
Consider a minimal Chi server with mTLS enabled:
(ns myapp.server
(:require [cheshire.core :as json]
[clj-http.client :as http]
[io.pedestal.http :as http]
[io.pedestal.http.route :as route]
[org.httpcomponents.client5.httpclient5.impl.io :as tls]
[org.httpcomponents.client5.httpclient5.ssl.SSLConnectionSocketFactory]))
(def service-env (atom {}))
(defn authenticated-routes [{{:keys [certificates] :as request} :request}]
(if (some-> request :ssl-client-certificate some?) ; ensure client cert present
{:status 200 :body (json/generate-string {:ok true})}
{:status 401 :body (json/generate-string {:error "mTLS required"})}))
(def routes
(route/expand-routes
[["/api" {:middleware [(fn [handler]
(fn [request respond raise)
(if (get-in request [:headers "x-request-start"])
(handler request respond raise)
(respond {:status 400 :body "Bad Request"})))]
:get authenticated-routes}]]))
(defn create-server []
(let [ssl-context (doto (javax.net.ssl.SSLContext/getDefault)
(.init nil nil nil))]
(http/create-server
{:port 8443
:ssl? true
:keystore-path "server-keystore.jks"
:keystore-password "changeit"
:truststore-path "server-truststore.jks"
:truststore-password "changeit"
:client-auth :need
:routes routes})))
In this example, :client-auth :need enforces mTLS. Without additional limits, an attacker could open many simultaneous TLS connections, each completing the handshake but then sending slow or large requests, eventually exhausting thread or memory resources. Proper remediation includes setting connection caps, request body size limits, and timeouts at the Chi/pedestal level, and optionally fronting Chi with a proxy or load balancer that enforces these limits before traffic reaches the application.
Mutual Tls-Specific Remediation in Chi — concrete code fixes
To harden Chi services with mTLS against DoS, apply limits on connections, request size, and idle timeouts. Use middleware to reject oversized bodies early and enforce per-client connection caps. Configure your SSL engine to avoid renegotiation and prefer session reuse to reduce CPU load.
Below is a concrete Chi configuration that incorporates these mitigations:
(ns myapp.server-secure
(:require [cheshire.core :as json]
[io.pedestal.http :as http]
[io.pedestal.http.body-params :as body-params]
[io.pedestal.interceptor :as interceptor]
[io.pedestal.http.route :as route]))
(def max-body-bytes (* 1 1024 1024)) ; 1 MB limit
(defn enforce-body-size [request]
(let [content-length (Long/parseLong (or (get-in request [:headers "content-length"]) "0"))]
(if (> content-length max-body-bytes)
{:status 413 :body (json/generate-string {:error "Payload Too Large"})} ; early exit
request)))
(def security-interceptors
[(body-params/body-params)
(interceptor/interceptor
{:name ::enforce-body-size
:enter enforce-body-size})])
(def secure-routes
(route/expand-routes
[["/api" {:middleware security-interceptors
:connection-throttle {:max-idle-connections 200 :per-client 10 :window-ms 1000}
:request-size max-body-bytes
:timeout 30000
:get (fn [request]
{:status 200
:body (json/generate-string {:mtls-verified true})})}]]))
(defn create-secure-server []
(let [ssl-context (doto (javax.net.ssl.SSLContext/getDefault)
(.init nil nil nil))]
(http/create-server
{:port 8443
:ssl? true
:keystore-path "server-keystore.jks"
:keystore-password "changeit"
:truststore-path "server-truststore.jks"
:truststore-password "changeit"
:client-auth :need
:ssl-session-timeout 3600
:ssl-protocols ["TLSv1.2" "TLSv1.3"]
:ciphers #{"TLS_AES_256_GCM_SHA384" "TLS_CHACHA20_POLY1305_SHA23"}
:routes secure-routes})))
Key points:
:client-auth :needensures mTLS is required for every request.:request-sizeand the customenforce-body-sizeinterceptor prevent large payloads that can exhaust memory.:timeoutlimits how long a connection can remain idle, reducing slowloris-style exhaustion.:ssl-session-timeoutand restricted:ciphersreduce CPU overhead during handshake and renegotiation.:connection-throttlecaps concurrent connections overall and per client to mitigate connection-flood attacks.
If you use a reverse proxy or load balancer (e.g., NGINX, Envoy) in front of Chi, apply DoS protections there as well: limit concurrent TLS handshakes per source IP, set strict timeouts, and enable TLS session resumption to lower repeated handshake costs. middleBrick can scan your Chi endpoints to verify that these limits and mTLS configurations are present and correctly enforced.
Related CWEs: resourceConsumption
| CWE ID | Name | Severity |
|---|---|---|
| CWE-400 | Uncontrolled Resource Consumption | HIGH |
| CWE-770 | Allocation of Resources Without Limits | MEDIUM |
| CWE-799 | Improper Control of Interaction Frequency | MEDIUM |
| CWE-835 | Infinite Loop | HIGH |
| CWE-1050 | Excessive Platform Resource Consumption | MEDIUM |