Identification Failures in Hanami with Cockroachdb
Identification Failures in Hanami with Cockroachdb — how this specific combination creates or exposes the vulnerability
Identification failures occur when an application cannot reliably establish and maintain the identity of a subject (user, service, or process) across interactions. In Hanami, this often maps to Authentication and Authorization checks that rely on session or token handling. When paired with Cockroachdb, a distributed SQL database, certain patterns in connection handling, transaction isolation, and query construction can inadvertently expose identification weaknesses.
One common scenario is using Cockroachdb’s SERIALIZABLE isolation with long-lived sessions where identity context is not consistently carried in every transaction. If a Hanami app reuses a database connection pool across requests without re-validating identity (e.g., user ID or API key) on each transaction, an attacker may exploit connection multiplexing to infer or manipulate identity context. This is a BOLA/IDOR vector: the app trusts the connection context rather than verifying the subject on each operation.
Additionally, Cockroachdb’s secondary indexes and distributed tables can cause subtle identification issues if queries are constructed with insufficient scoping. For example, a Hanami repository method that fetches records by user_id might omit tenant or ownership checks when using Cockroachdb’s AS OF SYSTEM TIME for historical reads. An attacker could use time-travel queries to access data they should not see, bypassing application-level identification controls.
Another vector involves authentication tokens stored in cookies or headers. If a Hanami app issues a session cookie without binding it to the client’s Cockroachdb connection metadata (e.g., IP or certificate fingerprint), an attacker who steals the cookie can reuse it across different nodes. Cockroachdb’s lack of built-in application-layer session binding means the database cannot enforce identity correlation, placing the burden entirely on the Hanami app to validate and rotate identifiers securely.
SSRF and unsafe consumption patterns can also amplify identification failures. A Hanami service that accepts a Cockroachdb connection string or SQL identifier from user input may inadvertently allow an attacker to redirect queries to internal nodes, exposing system-level metadata that reveals identification schemes. Proper input validation and strict allowlists are essential to prevent this class of vulnerability.
Cockroachdb-Specific Remediation in Hanami — concrete code fixes
Remediation focuses on ensuring identity is verified at the application layer for every transaction and that Cockroachdb features are used in a way that preserves identification boundaries.
1. Validate identity on every repository call
Never rely on connection or session state alone. Pass the subject (user ID or API key) explicitly into repository methods.
module Repositories
class OrderRepository
def initialize(db)
@db = db
end
# Explicitly require user_id for scoping
def for_user(user_id)
@db["SELECT * FROM orders WHERE user_id = $1", user_id].to_a
end
end
end
# In your Hanami action
class Web::Orders::Index
include Hanami::Action
def initialize(order_repo: Repositories::OrderOrderRepository.new(DB))
@order_repo = order_repo
end
def call(params)
user_id = params[:user_id] # from authenticated session
@result = @order_repo.for_user(user_id)
end
end
2. Use Cockroachdb placeholders and avoid string interpolation
Always use parameterized queries to prevent SQL injection that could bypass identification logic.
# Good: parameterized query
DB["SELECT * FROM users WHERE id = $1 AND tenant_id = $2", user_id, current_tenant.id].one
# Bad: string interpolation (vulnerable)
DB["SELECT * FROM users WHERE id = #{user_id}"].one
3. Bind identity to connection options where possible
While Cockroachdb does not enforce session binding, you can encode tenant or user context in application-level options and enforce it in SQL.
# Use application-set search_path to isolate tenant
DB.execute("SET search_path TO tenant_#{tenant_id}")
# Then ensure all repository queries are scoped to that search_path
# This is a mitigation, not a replacement for row-level checks
4. Avoid time-travel queries that bypass identification
If you use Cockroachdb’s AS OF SYSTEM TIME, re-apply identification filters on the historical data.
user_id = 123
as_of = "2024-01-15 12:00:00+00"
orders = DB[
"SELECT * FROM orders AS OF SYSTEM TIME $1 WHERE user_id = $2",
as_of, user_id
].to_a
5. Rotate and bind authentication tokens
Do not store raw tokens in cookies without additional binding. Use signed, HttpOnly cookies and rotate session identifiers after login.
# Example of setting a secure cookie in Hanami
response.set_cookie(
'session_id',
value: SecureRandom.uuid,
httponly: true,
secure: true,
same_site: :strict
)
# Store mapping server-side with user_id and expiry
6. Validate inputs that influence database routing
If your app selects database nodes or schemas based on input, validate against a strict allowlist.
ALLOWED_TENANTS = %w[acme widget corp]
tenant = params[:tenant]
raise ArgumentError unless ALLOWED_TENANTS.include?(tenant)
DB = PG.connect(dbname: "tenant_#{tenant}", host: "cockroachdb.example.com")