Dns Rebinding in Chi with Mutual Tls
Dns Rebinding in Chi with Mutual Tls — how this specific combination creates or exposes the vulnerability
Dns Rebinding is a client-side attack where a malicious webpage tricks a victim’s browser into sending requests to an internal or otherwise restricted host by changing the DNS answer after the initial connection. When this occurs in a Chi application protected by Mutual TLS (mTLS), the interaction between TLS client certificate validation and Chi routing can create subtle exposure paths if the server relies solely on the TLS client identity without additional network-level checks.
Chi is a functional routing library for Clojure on the JVM. In a setup with mTLS, the server requests and validates client certificates on each connection. If the server uses the client certificate subject or Common Name to make authorization or routing decisions (for example, mapping a principal to an allowed internal service), an attacker who can chain a DNS Rebind to a TLS-terminated endpoint may exploit this by obtaining a valid client certificate for an initial domain, then rebinding to an internal IP while the TLS session is reused. Because Chi routes based on request properties that may include authenticated identity, an attacker can pivot to internal endpoints that would otherwise be unreachable from the public Internet.
The vulnerability is not in mTLS itself, which remains strong for peer authentication and encryption, but in how application logic incorporates TLS-derived attributes into access control. For example, if a Chi handler reads a certificate attribute to decide whether a request may access an internal admin route, and the server does not re-validate the target network location or enforce strict host-based constraints, the attacker can bypass intended network segregation. This is especially relevant when services use mTLS within a cluster and assume that possessing a valid cert is sufficient proof to reach a particular service within the environment.
middleBrick detects this risk pattern by correlating unauthenticated endpoint behavior with TLS-derived identity usage and host-header dynamics. It flags scenarios where identity-based routing or authorization occurs without corroborating network restrictions, providing findings mapped to the OWASP API Top 10 and SOC2 controls. With the Pro plan, continuous monitoring can alert you if your Chi endpoints show configurations that could enable such bypasses, and the GitHub Action can gate merges when risk scores exceed your threshold.
Mutual Tls-Specific Remediation in Chi — concrete code fixes
Remediation focuses on decoupling authorization from TLS identity and enforcing explicit network and host validation in Chi routes. Do not rely on the client certificate subject to determine access to internal network paths; instead, use it as authentication only and apply strict host and IP allowlists at the router or handler level.
Below are concrete, working examples of mTLS setup in Chi. The first shows a minimal HTTPS server with client certificate verification using buddy-sign and http-kit (commonly paired with Chi via middleware). The second shows how to enforce host and IP checks in Chi routes to mitigate DNS Rebinding when mTLS is in use.
(ns myapp.mtls
(:require [httpkit.server :as server]
[cheshire.core :as json]
[buddy.sign.middleware :refer [wrap-jws]]))
(defn client-certificate-allowed?
"Validate client certificate details against an allowlist."
[cert]
(let [subject (:subject cert)
cn (:common-name subject)]
(contains? #{"trusted-client-a" "trusted-client-b"} cn)))
(defn wrap-mtls-auth [handler]
(fn [request]
(let [client-cert (get-in request [:ssl-client-cert :certificates 0])]
(if (and client-cert (client-certificate-allowed? client-cert))
(handler request)
{:status 403 :body "Client certificate not allowed"}))))
;; Example Chi routes with host/IP validation
(defn routes []
(let [allowed-hosts #{"api.example.com" "app.example.com"}
allowed-subnets ["10.0.0.0/8" "192.168.0.0/16"]]
(-> (router
{"/public" ["GET" (fn [_] {:status 200 :body "public"})]
"/admin" ["GET" (wrap-mtls-auth (fn [req]
(if (some #(netmask/in-subnet? (:remote-addr req) %)
allowed-subnets)
{:status 200 :body "admin"}
{:status 403 :body "network not allowed"})))}])
(wrap-mtls-auth)
(wrap-host-allowed allowed-hosts))))
(defn -main []
(server/run-routes routes {:port 8443
:ssl {:cert-file "server.crt"
:key-file "server.key"
:need-client-cert true
:truststore-file "truststore.jks"}}))
Key points in the remediation:
- Use
wrap-mtls-authto validate the client certificate but not to derive authorization to internal services. - Maintain explicit allowlists for hosts and IP subnets in Chi routes, and check the request’s remote address against those lists before granting access to sensitive routes such as
/admin. - Do not embed sensitive routing or policy logic in certificate metadata; treat the certificate as proof of possession, not as a policy token.
With these practices, you retain mTLS benefits while eliminating a path an attacker could exploit via DNS Rebinding. middleBrick can surface configurations where identity-based routing is too permissive and suggest tighter network-based rules, and the CLI makes it easy to integrate checks into local development and CI/CD via the middlebrick npm package.