HIGH graphql introspectionchimutual tls

Graphql Introspection in Chi with Mutual Tls

Graphql Introspection in Chi with Mutual Tls — how this specific combination creates or exposes the vulnerability

GraphQL introspection in Chi can expose schema details even when the endpoint is protected by Mutual TLS (mTLS). Introspection queries (e.g., __schema { queryType { name } }) return full type definitions, which can reveal internal models, queries, and business logic. When mTLS is used, the server validates client certificates, but if the route handling GraphQL requests does not enforce strict authorization, an authenticated client may still issue introspection queries. This creates a risk of information disclosure because mTLS ensures identity but does not limit what authenticated clients can query.

In Chi, this typically occurs when a GraphQL handler is mounted under a route that lacks per-operation or per-field authorization checks. Because introspection is often enabled by default in development and sometimes left accessible in production for debugging, an attacker with a valid client certificate (obtained through compromised credentials or provisioning) can retrieve the schema and plan further attacks, such as BOLA/IDOR or property authorization flaws. The combination therefore does not introduce a new protocol weakness, but it can amplify the impact of missing operation-level controls.

Real-world findings from scans often map this to OWASP API Top 10:2023 A1 — Broken Object Level Authorization, where valid mTLS-authenticated sessions can still run introspection or queries against unauthorized resources. For example, a query like { user(id: "123") { email } } may be allowed simply because the request presents a valid certificate, even though the user context should restrict fields. middleBrick detects such scenarios under its Property Authorization and BOLA/IDOR checks, highlighting that mTLS alone is insufficient to prevent information leakage via introspection.

Mutual Tls-Specific Remediation in Chi — concrete code fixes

To secure GraphQL endpoints in Chi when using Mutual TLS, you must combine mTLS with explicit authorization for introspection and query operations. This means checking scopes or claims from the client certificate before allowing introspection, and applying field-level or operation-level permissions based on authenticated identity.

Example: Conditional Introspection in Chi

Allow introspection only for specific authenticated roles (e.g., clients with a particular certificate extended key usage or SAN). Use Chi routes and middleware to inspect the TLS client certificate and decide whether introspection is permitted.

// src/graphql_handler.clj
(ns myapp.graphql-handler
  (:require [cheshire.core :as json]
            [clojure.string :as str]
            [io.pedestal.http :as http]
            [io.pedestal.http.route :as route]
            [com.walmartlabs.lacinia.execute :as exec]
            [com.walmartlabs.lacinia.schema :as schema]))

(defn client-certificate-allowed? [request]
  (let [client-cn (get-in request [:ssl-client-cert :common-name])]
    (contains? #{"trusted-admin" "schema-reader"} client-cn)))

(defn graphql-handler [request]
  (if-let [query (:query (http/body request))]
    (if (and (= "__schema" (some-> query str/lower-case))
             (not (client-certificate-allowed? request)))
      {:status 403
       :body (json/generate-string {:error "introspection not allowed"})}
      ;; proceed with schema execution
      {:status 200
       :body (json/generate-string (exec/execute schema/query-schema query))})
    {:status 400
     :body (json/generate-string {:error "missing query"})}))

(def service
  {::http/routes [["/graphql" {:post graphql-handler}]]
   ::http/chain-validator (fn [request] (when-not (get-in request [:ssl-client-cert])
                                         (throw (ex-info "mTLS required" {:status 401}))))
   ::http/type :jetty
   ::http/port 8443})

Example: Role-Based Field Authorization

Even with mTLS, ensure that fields like email or internal IDs are only accessible to authorized roles. This example demonstrates wrapping the GraphQL execution to enforce claims-based checks.

// src/myapp/authorization.clj
(ns myapp.authorization
  (:require [clojure.set :as set]))

(defn authorized-fields [request permitted-fields]
  (let [client-roles (get-in request [:ssl-client-cert ::roles])]
    (if (some #(contains? client-roles %) #{"admin" "support"})
      permitted-fields
      (set/difference permitted-fields #{:User_email :Account_ssn})}))

(defn build-schema-with-auth []
  (schema/merge-schemas
    {:schema-doc "type Query { user(id: ID!): User } type User { id: ID! email: String }"}
    {:resolvers {:Query
                 {:user (fn [_ _ ctx value args]
                          (let [permitted (authorized-fields ctx #{:User_id :User_name})]
                            (if (contains? permitted :User_email)
                              {:id value :email "[email protected]"}
                              {:id value}))))}}}})

With these patterns, mTLS in Chi provides strong client authentication, while explicit checks prevent introspection abuse and over-fetching. middleBrick’s LLM/AI Security and Property Authorization checks can validate that introspection is appropriately gated and that roles align with intended access boundaries.

Related CWEs: dataExposure

CWE IDNameSeverity
CWE-200Exposure of Sensitive Information HIGH
CWE-209Error Information Disclosure MEDIUM
CWE-213Exposure of Sensitive Information Due to Incompatible Policies HIGH
CWE-215Insertion of Sensitive Information Into Debugging Code MEDIUM
CWE-312Cleartext Storage of Sensitive Information HIGH
CWE-359Exposure of Private Personal Information (PII) HIGH
CWE-522Insufficiently Protected Credentials CRITICAL
CWE-532Insertion of Sensitive Information into Log File MEDIUM
CWE-538Insertion of Sensitive Information into Externally-Accessible File HIGH
CWE-540Inclusion of Sensitive Information in Source Code HIGH

Frequently Asked Questions

Does mTLS alone prevent GraphQL introspection abuse?
No. Mutual TLS provides client authentication but does not restrict what an authenticated client can query. You must add route-level and operation-level checks to block or limit introspection for specific certificates or roles.
How can middleBrick help detect GraphQL introspection risks in Chi with mTLS?
middleBrick runs unauthenticated and authenticated-like scans (when credentials are provided) and flags scenarios where introspection is accessible to valid mTLS clients without proper authorization, mapping findings to OWASP API Top 10 and compliance frameworks.