HIGH brute force attackchicockroachdb

Brute Force Attack in Chi with Cockroachdb

Brute Force Attack in Chi with Cockroachdb — how this specific combination creates or exposes the vulnerability

A brute force attack in the context of a Chi-based service using CockroachDB typically involves repeated authentication attempts or token probes aimed at user accounts. Because Chi is a minimal, compositional routing library for Clojure web services, it does not inherently enforce account lockout or rate limiting; those controls must be added explicitly. When these controls are missing or misconfigured, an attacker can submit many password guesses or session tokens against endpoints routed through Chi without triggering defenses.

CockroachDB, a distributed SQL database, stores user credentials and session records. If the application queries CockroachDB with a non-parameterized statement or constructs SQL by string concatenation, the service may leak timing differences that help an attacker distinguish valid usernames from invalid ones. Even when the application uses parameterized queries, a lack of server-side rate limiting or per-user attempt tracking enables high-volume requests that CockroachDB must process, increasing load and potentially degrading availability.

Chi routes are often defined as a series of nested middlewares. If authentication checks are applied after routing but before hitting CockroachDB, an attacker can still probe valid endpoints without credentials. In distributed deployments, CockroachDB’s multi-node architecture can mask aggressive request volumes from simple network-level throttling, allowing a brute force campaign to continue longer than expected. Because the scan methodology of middleBrick tests unauthenticated attack surfaces, it can identify endpoints under Chi routing that accept repeated requests without proper controls, and highlight missing rate limiting or weak authentication logic that would facilitate brute forcing.

During a middleBrick scan, findings may map this attack pattern to the BFLA/Privilege Escalation and Authentication categories, noting missing rate limiting and weak account protections. The scan also checks input validation to ensure guesses do not trigger injection paths against CockroachDB. Real-world examples include endpoints like /api/login or /api/account/reset where Chi routes accept POST payloads without requiring prior authentication, and where CockroachDB returns distinct error timing for existing users.

Cockroachdb-Specific Remediation in Chi — concrete code fixes

Remediation focuses on reducing the attack surface exposed by Chi routes and hardening interactions with CockroachDB. Use parameterized SQL to prevent injection and ensure consistent response timing, and enforce server-side rate limiting at the Chi middleware layer to limit attempts per identity or IP address.

Chi routing with authentication and rate limiting

Define a protected route that checks credentials before reaching handlers that query CockroachDB. Apply a rate limiter middleware early in the route chain to restrict request volume per client.

(ns myapp.routes
  (:require [compojure.core :refer [defroutes POST]]
            [ring.util.response :as resp]
            [no.en.core :refer [read-env]]
            [cheshire.core :as json]
            [hiccup2.core :refer [html]]
            [ring.middleware.rate-limit :refer [wrap-rate-limit]]))

(defonce attempts (atom {}))

(defn rate-limiter [handler]
  (fn [request]
    (let [ip (:remote-addr request)
          key (str ip (:uri request))]
      (swap! attempts update key (fnil inc 0))
      (if (> (@attempts key) 10)
        (resp/response "Too many requests")
        (handler request)))))

(defn verify-credentials [username password]
  (let [db (doto (java.sql/->pooled-datasource {:dbtype "cockroachdb"
                                                :dbname "appdb"
                                                :host "localhost"
                                                :port 26257
                                                :user "appuser"
                                                :password (System/getenv "DB_PASSWORD")})
              .getConnection)
        sql ["SELECT password_hash FROM users WHERE username = ?" username]
        result (.executeQuery db sql)]
    (if (.next result)
      (let [stored-hash (.getString result "password_hash")]
        (if (bcrypt/checkpw password stored-hash)
          true
          false))
      false)))

(defn login-handler [request]
  (let [body (json/parse-string (slurp (:body request)) true)
        username (get body "username")
        password (get body "password")]
    (if (verify-credentials username password)
      (resp/response {:status "ok"})
      (resp/bad-request {:error "invalid credentials"}))))

(defroutes app-routes
  (POST "/api/login" [] login-handler)
  (route/not-found "Not found"))

(def app
  (-> app-routes
      (wrap-rate-limit {:limit 10 :period 60}) ; 10 requests per minute per key
      rate-limiter))

Parameterized SQL against CockroachDB

Always use prepared statements or parameterized queries to avoid SQL injection and timing leaks. The following example uses next.jdbc with a pooled CockroachDB connection.

(ns myapp.db
  (:require [next.jdbc :as jdbc]
            [next.jdbc.result-set :as rs]))

(def db
  {:dbtype "cockroachdb"
   :dbname "appdb"
   :host "localhost"
   :port 26257
   :user "appuser"
   :password (System/getenv "DB_PASSWORD")
   :poolName "cockroach-pool"})

(defn find-user-by-username [username]
  (jdbc/with-db-connection [conn db]
    (jdbc/execute-one! conn
      ["SELECT id, username, password_hash FROM users WHERE username = ?" username]
      {:builder-fn rs/as-unqualified-lower-case-maps})))

(defn verify-password [username password]
  (if-let [user (find-user-by-username username)]
    (do
      ;; Use a constant-time comparison where possible
      (if (bcrypt/verify password (:password_hash user))
        user
        nil))
    nil))

Server-side per-user attempt tracking

Track attempts in a distributed cache or via CockroachDB to enforce per-username limits. This example uses an in-memory atom for simplicity but should be replaced with a shared store in production.

(ns myapp.security
  (:require [next.jdbc :as jdbc]
            [next.jdbc.result-set :as rs]))

(defonce username-attempts (atom {}))

(defn record-failed-attempt [username]
  (swap! username-attempts update username (fnil inc 0)))

(defn reset-attempts-if-valid [username]
  (when (<= (@username-attempts username 0) 5)
    (swap! username-attempts assoc username 0)))

(defn enforce-max-attempts [username]
  (when (> (@username-attempts username 0) 5)
    (throw (ex-info "Account temporarily locked" {:status 429}))))

(defn secure-login [username password]
  (enforce-max-attempts username)
  (if (verify-password username password)
    (do
      (reset-attempts-if-valid username)
      {:status :success})
    (do
      (record-failed-attempt username)
      {:status :failure})))

Database-side safeguards in CockroachDB

Create indexes and constraints to ensure efficient lookups and avoid accidental full scans. Use role-based access control to limit what the application user can do.

-- Create an index on username for fast lookups
CREATE INDEX idx_users_username ON users (username);

-- Create a read-write user for the application
CREATE USER appuser WITH PASSWORD 'strong-password';
GRANT SELECT, INSERT, UPDATE ON users TO appuser;

Frequently Asked Questions

Can middleBrick detect brute force risks in Chi services backed by CockroachDB?
Yes, middleBrick scans unauthenticated attack surfaces and can identify endpoints under Chi routing that accept repeated requests without rate limiting or authentication, highlighting risks that could enable brute force attacks against accounts stored in CockroachDB.
Does middleBrick test for timing leaks when usernames are queried in CockroachDB?
middleBrick checks input validation and authentication patterns that may introduce timing variability. While it does not perform active timing measurements, it flags missing parameterized SQL and weak authentication controls that can contribute to timing-based username enumeration.