Credential Stuffing in Hanami with Cockroachdb
Credential Stuffing in Hanami with Cockroachdb — how this specific combination creates or exposes the vulnerability
Credential stuffing is a brute-force technique where attackers use lists of breached username and password pairs to gain unauthorized access. Hanami, a Ruby web framework, often interfaces with CockroachDB as a distributed SQL backend. When Hanami applications rely on weak account policies—such as allowing unlimited login attempts, missing multi-factor authentication, or exposing password reset endpoints without rate controls—an attacker can automate credential stuffing directly against the Hanami app, and the backend CockroachDB instance stores the authentication records that are validated on each attempt.
The combination introduces risk because CockroachDB’s strong consistency and horizontal scalability can inadvertently support high-throughput validation logic if the application does not enforce deliberate throttling. For example, if Hanami sessions authenticate by querying a users table in CockroachDB with a simple equality check on email and password hash, an attacker can issue many concurrent requests without triggering meaningful backpressure. CockroachDB will serve each query quickly, and Hanami may respond with generic timing differences or error messages that leak whether an account exists. Moreover, if CockroachDB is reachable from untrusted networks without strict network policies, credential stuffing traffic can originate from many IPs, amplifying the challenge of mitigation.
Additionally, observability data from CockroachDB might inadvertently expose sensitive information in logs or error traces during authentication flows, aiding attackers in refining their lists. MiddleBrick’s LLM/AI Security checks are valuable here because they detect system prompt leakage and test for output exposure that could reveal authentication states or backend details. Without controls like progressive delays, CAPTCHA, or device fingerprinting integrated into Hanami’s session workflow, credential stuffing against a CockroachDB-backed stack can lead to account takeover and lateral movement within the database.
Cockroachdb-Specific Remediation in Hanami — concrete code fixes
Remediation centers on hardening authentication endpoints in Hanami and configuring CockroachDB to resist high-rate abusive queries while preserving legitimate access. Below are concrete code examples and configurations tailored for Hanami apps using CockroachDB.
1. Account lockout with exponential backoff in Hanami
Track failed attempts per user or IP and progressively delay responses. Use CockroachDB to store counters with TTL to avoid permanent lockout records.
module HanamiApp
class Login
def self.attempt(params)
user = UserRepository.find_by_email(params[:email])
return :not_found unless user
lockout_key = "lockout:#{user.id}"
failures = redis.get(lockout_key).to_i
if failures >= 5
sleep([2 ** failures, 60].min) # exponential backoff capped at 60s
end
if UserRepository.verify_password(user, params[:password])
redis.del(lockout_key)
SessionRepository.create(user_id: user.id)
:success
else
redis.set(lockout_key, failures + 1, ex: 3600)
:failure
end
end
end
end
2. Parameterized SQL to prevent injection and ensure plan stability in CockroachDB
Always use placeholders to avoid SQL injection and ensure CockroachDB can reuse query plans. Hanami’s repository pattern should enforce this.
# user_repository.rb
module Repositories
class UserRepository
def self.find_by_email(email)
DB[%Q{
SELECT id, email, password_hash, mfa_enabled
FROM users
WHERE email = $1
LIMIT 1
}, email].first
end
def self.verify_password(user, password)
BCrypt::Password.new(user[:password_hash]) == password
end
end
end
3. Rate limiting at the CockroachDB level with row-level state
Use a dedicated table to track authentication attempts per IP and enforce limits within a transaction to avoid race conditions.
-- Migration
CREATE TABLE auth_rate_limits (
ip INET PRIMARY KEY,
attempt_count INT NOT NULL DEFAULT 0,
last_attempt TIMESTAMPTZ NOT NULL DEFAULT now(),
reset_after TIMESTAMPTZ NOT NULL
);
-- Check and increment within a transaction
BEGIN;
UPSERT INTO auth_rate_limits (ip, attempt_count, last_attempt, reset_after)
VALUES ($1, 1, now(), now() + INTERVAL '1 hour')
ON CONFLICT (ip) DO UPDATE
SET attempt_count = auth_rate_limits.attempt_count + 1,
last_attempt = now()
WHERE auth_rate_limits.reset_after < now();
SELECT attempt_count INTO STRICT cnt FROM auth_rate_limits WHERE ip = $1;
COMMIT;
-- Enforce limit in Hanami middleware
if cnt > 100
halt 429, { error: 'Too many requests' }.to_json
end
4. Network and schema hardening
Restrict CockroachDB to accept connections only from Hanami application servers using VPC peering or firewall rules. Avoid exposing the DB port to the public internet. In Hanami, ensure password hashing uses strong algorithms like bcrypt or Argon2 and rotate secrets via environment variables rather than storing them in code or schema files.
MiddleBrick’s dashboard can track your authentication endpoints over time, and the CLI can integrate into your Hanami CI/CD pipeline to fail builds if risky patterns are detected. These steps reduce the effectiveness of credential stuffing while maintaining compatibility with CockroachDB’s distributed nature.