Identification Failures in Hanami (Ruby)
Identification Failures in Hanami with Ruby — how this specific combination creates or exposes the vulnerability
Identification failures occur when an application cannot reliably establish or maintain a verified identity for a user or resource across a request lifecycle. In Hanami, a Ruby web framework that emphasizes explicit architecture and immutable objects, these failures often stem from how identity is modeled, persisted, and retrieved. Hanami encourages rich domain models and value objects; if identity is represented only by a primitive like an Integer or String without proper validation and scoping, it becomes easier for an attacker to manipulate references.
Because Hanami is built on Ruby, the language’s metaprogramming and flexible type system can inadvertently contribute to identification gaps when developers override equality methods or rely on unchecked parameter binding. For example, using params.fetch(:id) to locate a record without confirming that the authenticated subject has the right to access that specific ID exposes a classic Insecure Direct Object Reference (IDOR), which falls under the BOLA/IDOR category in middleBrick’s checks. Hanami’s use of repositories that are often plain Ruby classes means developers must explicitly scope queries; omitting scope filters leads to over-privileged data access.
Another Ruby-specific factor is the implicit conversion and duck typing. If an ID is supplied as a string (e.g., from JSON or URL parameters) and compared with an Integer-based primary key without careful coercion, it can bypass intended checks or match unintended records. Hanami’s emphasis on value objects helps, but if identity validation is deferred to runtime without strict type and presence checks, an attacker can supply ambiguous or missing identifiers to enumerate resources. The framework does not enforce identity constraints automatically; developers must design entities with identity as a first-class concern, ensuring that every lookup includes authorization context.
Middleware and routing in Hanami also play a role. If route constraints or endpoint parameters are not validated against a canonical identity representation, requests can be routed to actions that assume a verified identifier without ensuring the identifier is trustworthy. middleBrick’s BOLA/IDOR and Property Authorization checks examine these runtime paths, comparing the spec’s defined object references with what the implementation actually exposes. Without explicit authorization checks in each repository or service call, identification failures become reachable through predictable IDs, missing ownership checks, or overly permissive HTTP verbs.
Additionally, Hanami’s support for different persistence backends can magnify identification issues if the mapping between domain identity and storage keys is inconsistent. For example, using UUIDs as identifiers requires strict format validation; failing to validate UUID format in Ruby allows injection of malformed or non-unique values that break identification logic. middleBrick’s Input Validation and Inventory Management checks look for such inconsistencies between OpenAPI/Swagger definitions and runtime behavior, highlighting mismatches in expected identifier formats and actual handling.
Ruby-Specific Remediation in Hanami
Remediation centers on making identity explicit, validated, and scoped within Hanami’s architecture. Use Hanami entities and value objects to encapsulate identity, and enforce strict type and presence checks before using identifiers in repository lookups. Always scope repository queries by the current subject’s permissions, and avoid relying on raw params for object identification.
Hanami entity with strict identity validation
module Types
include Hanami::Types
class StrictPositiveInt = Integer > 0
end
class ArticleEntity
include Hanami::Entity
attribute :id, Types::StrictPositiveInt
attribute :slug, Types::Strict::String
end
Scoped repository lookup with authorization context
class ArticleRepository
def by_id_for_user(id, user)
# Ensure id is properly cast and validated
validated_id = Types::StrictPositiveInt.(id)
# Scope by user_id to prevent BOLA/IDOR
dataset.where(id: validated_id, user_id: user.id).one
end
end
Controller parameter handling with coercion and checks
class Articles::Show
include Hanami::Action
def handle(request, response)
id = request.params.fetch(:id, nil)
user = request.env['current_user']
# Explicit presence and type validation
unless id && id.match?(/\A\d+\z/)
response.status = 400
return response.body = { error: 'invalid_id_format' }.to_json
end
article = article_repo.by_id_for_user(id.to_i, user)
if article.nil?
response.status = 404
return response.body = { error: 'not_found' }.to_json
end
response.status = 200
response.body = ArticleEntity.new(article).to_json
end
private
def article_repo
ArticleRepository.new
end
end
Using Hanami’s dry-validation for input contracts
class ArticleInputContract
include Hanami::ValidForm
validations do
required(:id).filled(:int?, gt?: 0)
required(:user_id).filled(:int?, gt?: 0)
end
end
contract = ArticleInputContract.new(params)
if contract.valid?
# safe to use contract[id] and contract[user_id]
else
# handle validation errors
end
Ensure authorization on every data access
Do not assume that fetching a record by ID is sufficient. Integrate a policy or scope that checks ownership or role-based access before returning data. In Hanami, compose services that accept both the identifier and the actor, returning data only when the relationship is verified.
Consistent identifier formats and OpenAPI alignment
Define identifier types in your OpenAPI spec and validate them in Ruby using strict types or custom validators. This reduces mismatches between documentation and runtime behavior, lowering the risk of identification failures flagged by middleBrick’s cross-referencing checks.