HIGH jwt misconfigurationchicockroachdb

Jwt Misconfiguration in Chi with Cockroachdb

Jwt Misconfiguration in Chi with Cockroachdb — how this specific combination creates or exposes the vulnerability

When building HTTP services in Haskell with the chi library backed by CockroachDB, JWT misconfigurations often arise from a mismatch between token validation practices and the trust boundary introduced by the database layer. A typical setup might initialize a JWT verification middleware in chi that decodes and validates the token, then pass the resulting claims into a database connection that is reused across requests. If the JWT secret or public key is loaded once at startup and never refreshed, an attacker who obtains a copy of the secret can forge tokens indefinitely. In a CockroachDB context, this risk is amplified when application-level roles are derived directly from JWT claims without additional authorization checks, enabling Horizontal Privilege Escalation (BOLA/IDOR) across tenant rows stored in the same cluster.

Another common pattern is to store user identifiers or scopes inside the JWT payload and use them to construct dynamic SQL such as SELECT * FROM tenant_data WHERE tenant_id = $1, binding the value from the token. If the token is accepted without signature verification or with an overly permissive algorithm (e.g., none), an attacker can manipulate the subject or tenant claim to access rows belonging to other tenants. Because CockroachDB supports multi-region replication and strong consistency, a single malicious request can read or write across nodes before detection. The chi pipeline may appear to enforce authentication, but without per-request validation of key material and strict claim checks, the database becomes an unintended data plane for token abuse.

Middleware configuration errors also contribute to the exposure. For example, placing the JWT verification middleware after route handlers that already query CockroachDB based on URL parameters creates a window where unauthenticated requests can trigger SQL execution paths. In distributed deployments, inconsistent secret rotation across instances means some nodes accept tokens signed by an older key, allowing token replay across the cluster. These issues align with the broader API security checks run by tools such as middleBrick, which tests for Authentication weaknesses, BOLA/IDOR, and Unsafe Consumption in unauthenticated scans. The tool can surface findings related to missing or misconfigured JWT validation and highlight how these map to frameworks such as OWASP API Top 10 and PCI-DSS controls.

To illustrate, a vulnerable chi router might look like this, where the database connection is initialized globally and used directly after a permissive JWT check:

{-# LANGUAGE OverloadedStrings #-}
import qualified Network.Wai as Wai
import qualified Network.Wai.Handler.Warp as Warp
import Network.Wai.Middleware.JWT (jwtAuth, jwtCfg, secret)
import Network.Wai.Middleware.RequestLogger (logStdoutDev)
import Database.PostgreSQL.Simple (connectPostgreSQL, Connection)
import qualified Database.PostgreSQL.Simple as SQL

jwtCfg' :: Wai.Middleware
jwtCfg' = jwtAuth (secret "insecure-default-secret-should-not-be-used-in-cockroachdb-prod")

app :: Connection -> Wai.Application
app conn req respond = do
  let tenantId = "placeholder" -- supposed to come from validated JWT claims
  rows <- liftIO $ SQL.query_ conn "SELECT data FROM tenant_data WHERE tenant_id = ?" (tenantId :: SQL.Only String)
  -- respond with rows
  Wai.responseLbs Wai.status200 [("Content-Type", "application/json")] "{...}"

main :: IO ()
main = do
  conn <- connectPostgreSQL "postgresql://user:password@localhost:26257/defaultdb?sslmode=disable"
  Warp.run 8080 (jwtCfg' (app conn))

In this example, the JWT secret is hardcoded, the algorithm is not explicitly restricted, and the tenant identifier is not bound to the validated claims before issuing SQL against CockroachDB. An attacker can send a request with any Authorization: Bearer token or none at all, and the application may still execute queries with a default or manipulated tenant ID. middleBrick would flag this as a combination of weak Authentication and BOLA/IDOR findings, emphasizing the need for strict claim validation and parameterized tenant resolution before any database interaction.

Cockroachdb-Specific Remediation in Chi — concrete code fixes

Remediation focuses on strict JWT validation before any database interaction and ensuring that claims used for CockroachDB queries are verified, scoped, and parameterized. In chijwt-simple or jwt with explicit algorithm settings, and avoid global secrets that are reused across environments. The connection to CockroachDB should be established after successful authentication, or at least key material should be refreshed periodically to limit the impact of secret leakage.

Below is a more secure pattern that validates JWT claims, extracts a tenant identifier, and uses parameterized queries to interact with CockroachDB:

{-# LANGUAGE OverloadedStrings #-}
import qualified Network.Wai as Wai
import qualified Network.Wai.Handler.Warp as Warp
import Network.Wai.Middleware.JWT (jwtAuth, jwtCfg, secret, getToken)
import Network.Wai (requestHeaders, lookupHeader)
import Network.HTTP.Types (status401)
import qualified Data.ByteString.Lazy as LBS
import qualified Data.Text.Lazy as TL
import qualified Data.Text.Lazy.Encoding as TE
import Database.PostgreSQL.Simple (Connection, connectPostgreSQL, query)
import Database.PostgreSQL.Simple.FromRow (FromRow, field)
import Data.ByteString (ByteString)
import qualified Data.ByteString.Char8 as BS
import Crypto.JWT (Secret, hmacSecret, decodeSigned, stringOrURI)

-- Assume a simple claim type
data TenantClaim = TenantClaim { tenantId :: String } deriving (Show)

parseClaims :: ByteString -> Either String TenantClaim
parseClaims token = do
  secretKey <- either (const $ Left "invalid secret") Right (hmacSecret "strong-cockroachdb-secret-key")
  claims <- either (const $ Left "invalid token") Right (decodeSigned secretKey token)
  tid <- maybe (Left "missing tenant claim") Right (stringOrURI "tenant_id" claims)
  return (TenantClaim tid)

jwtCfgStrict :: Wai.Middleware
jwtCfgStrict app req respond = case lookupHeader "Authorization" req of
  Just authHeader ->
    case BS.stripPrefix "Bearer " authHeader of
      Just tokenStr -> case parseClaims (TE.encodeUtf8 (TL.toStrict (TE.decodeUtf8 tokenStr))) of
        Right claims -> app (req { requestHeaders = ("X-Tenant-ID", TE.encodeUtf8 (tenantId claims)) : requestHeaders req }) respond
        Left err -> respond $ Wai.responseLbs status401 [("Content-Type", "application/json")] ("{\"error\":\"" <> TE.encodeUtf8 (TL.pack err) <> "\"}")
  Nothing -> respond $ Wai.responseLbs status401 [("Content-Type", "application/json")] "{\"error\":\"missing authorization\"}"

appSafe :: Connection -> Wai.Application
appSafe conn req respond = do
  let mTenant = lookup "X-Tenant-ID" (requestHeaders req)
  case mTenant of
    Just tid -> do
      rows <- liftIO $ SQL.query conn "SELECT data FROM tenant_data WHERE tenant_id = ?" (tid :: SQL.Only String)
      Wai.responseLbs Wai.status200 [("Content-Type", "application/json")] ("{...}")
    Nothing -> Wai.responseLbs status400 [("Content-Type", "application/json")] "{\"error\":\"invalid tenant\"}"

main :: IO ()
main = do
  conn <- connectPostgreSQL "postgresql://user:password@localhost:26257/defaultdb?sslmode=require"
  Warp.run 8080 (jwtCfgStrict (appSafe conn))

This example enforces explicit secret handling, validates the token before any CockroachDB interaction, and binds the tenant identifier from verified claims to a parameterized query. By combining chi middleware discipline with CockroachDB’s strong consistency and parameterized SQL, you reduce the risk of token-based BOLA/IDOR and ensure that each request operates within its intended security boundary.

For teams using middleBrick, running an unauthenticated scan can surface JWT misconfiguration findings and map them to compliance frameworks such as OWASP API Top 10 and SOC2. The CLI tool can be integrated into scripts to validate remediation, while the Pro plan enables continuous monitoring to detect secret rotation needs or new misconfigurations introduced after deployments.

Related CWEs: authentication

CWE IDNameSeverity
CWE-287Improper Authentication CRITICAL
CWE-306Missing Authentication for Critical Function CRITICAL
CWE-307Brute Force HIGH
CWE-308Single-Factor Authentication MEDIUM
CWE-309Use of Password System for Primary Authentication MEDIUM
CWE-347Improper Verification of Cryptographic Signature HIGH
CWE-384Session Fixation HIGH
CWE-521Weak Password Requirements MEDIUM
CWE-613Insufficient Session Expiration MEDIUM
CWE-640Weak Password Recovery HIGH

Frequently Asked Questions

How can I test my Chi + Cockroachdb API for JWT misconfiguration without a pentest vendor?
You can use the middleBrick CLI to scan your endpoint from the terminal: middlebrick scan https://api.example.com. It runs unauthenticated checks in 5–15 seconds and reports issues such as weak JWT validation and BOLA/IDOR risks specific to your Cockroachdb-backed Chi service.
Does middleBrick fix JWT or database issues found during a scan?
middleBrick detects and reports findings with remediation guidance, but it does not fix, patch, block, or remediate. You should use the provided guidance to harden JWT validation, rotate secrets, and parameterize queries against CockroachDB.