HIGH identification failureshanamimongodb

Identification Failures in Hanami with Mongodb

Identification Failures in Hanami with Mongodb — how this specific combination creates or exposes the vulnerability

Identification failures occur when an application cannot reliably confirm the identity of a subject or cannot correctly enforce access controls tied to that identity. In Hanami applications using MongoDB as the persistence layer, this risk arises from a mismatch between how identities are represented in Ruby objects and how they are stored, queried, and enforced in MongoDB. Hanami encourages domain-driven design with value objects and entities that have explicit identity semantics, but if those semantics are not consistently mapped to MongoDB document identifiers, access control checks can be bypassed or misapplied.

MongoDB’s flexible schema and default use of _id as a primary key can contribute to identification failures when Hanami entities do not explicitly define an identifier strategy or when string-based IDs from external inputs are used directly in queries without normalization. For example, if a Hanami entity relies on a string UUID provided by the client and that value is used to construct a MongoDB _id query without validation, an attacker can manipulate the identifier to access resources belonging to other users. This is a BOLA/IDOR pattern, and it is especially dangerous when authorization checks are performed at a higher layer but rely on an untrusted identifier to locate the document.

Additionally, Hanami’s use of repositories can obscure identification issues if repository methods do not enforce scoping by the current subject’s identity. A repository method that queries MongoDB by a property such as user_id must ensure that the query is parameterized from the current session or token rather than from user-supplied input. If the query accidentally uses an ID from request parameters without verifying that the requesting user owns that ID, the control fails to bind the operation to the authenticated subject, effectively breaking identification and enabling horizontal privilege escalation.

The interaction with the 12 security checks in middleBrick amplifies the impact of these issues. For example, the Authentication check may pass if the session is valid, but the BOLA/IDOR check can flag scenarios where an endpoint accepts an item_id parameter and uses it directly in a MongoDB query like collection.find({'_id': BSON::ObjectId.from_string(params[:item_id])}) without confirming that the item belongs to the current user. Input validation checks may also highlight that string identifiers are not being canonicalized or checked against a strict format before use, increasing the risk of malformed or malicious identifiers causing incorrect document retrieval. Properly binding identification to the subject and normalizing identifiers before querying ensures that even when using a flexible store like MongoDB, Hanami applications maintain a robust identity boundary.

Mongodb-Specific Remediation in Hanami

To remediate identification failures when using MongoDB with Hanami, enforce strict binding between the authenticated subject and every query, validate and normalize all identifiers, and avoid passing raw user input directly into MongoDB queries. Below are concrete code examples that demonstrate secure patterns for repository methods and request handling.

First, ensure that your Hanami entity defines an explicit identity. For a Task aggregate rooted by a UUID, define the entity with a value object for ID and a repository that scopes queries to the current user’s ID.

# entity/task.rb
class Task
  include Hanami::Entity
  attribute :id, Types::Strict::String.constructor { |v| v.to_s.strip.downcase }
  attribute :user_id, Types::Strict::String
  # other attributes …
end

# value_objects/task_id.rb
class TaskId
  include ValueObject
  attribute :value, Types::Strict::String

  def self.generate
    new(value: SecureRandom.uuid)
  end
end

Second, implement a repository that uses the current user’s identity to scope MongoDB queries. Use a session or context object to supply the subject identifier rather than accepting it from request parameters.

# repositories/task_repo.rb
class TaskRepo
  def initialize(collection)
    @collection = collection
  end

  def for_user(user_id)
    self.class.new(@collection.find('user_id' => user_id))
  end

  def find_by_id(user_id, task_id)
    document = @collection.find_one(
      { 'user_id' => user_id, '_id' => ::BSON::ObjectId.from_string(task_id) }
    )
    Task.new(id: document['_id'].to_s, user_id: document['user_id'], name: document['name'])
  rescue ::Mongo::Error::InvalidObjectId
    nil
  end

  def create(task)
    object_id = ::BSON::ObjectId.from_string(task.id.value)
    @collection.insert_one('_id' => object_id, 'user_id' => task.user_id, 'name' => task.name)
  end
end

Third, in your use case or action, derive the user identifier from the authenticated session and pass it explicitly to the repository. Never use parameters such as params[:id] as the sole source of the document identifier for access checks.

# actions/tasks/show.rb
class Tasks::Show
  def initialize(user_id, task_repo)
    @user_id = user_id
    @task_repo = task_repo
  end

  def call(params)
    task_id = params.fetch(:id, nil)
    return Failure.new(:not_found) unless task_id

    task = @task_repo.find_by_id(@user_id, task_id)
    if task
      Success.new(task: task)
    else
      Failure.new(:not_found)
    end
  end
end

Finally, normalize and validate identifiers before constructing queries. If your MongoDB uses string IDs, ensure they conform to expected formats and avoid type confusion by explicitly converting values. When using ObjectId, validate that the string is a valid ObjectId and handle conversion errors to prevent exceptions that could leak information or bypass identification checks.

These practices align with the findings that middleBrick may report under the BOLA/IDOR and Input Validation checks, providing remediation guidance that maps to real patterns such as OWASP API Top 10 A01 and A07. By tightly coupling identification to the authenticated subject and rigorously validating identifiers, you reduce the attack surface even when using a schema-less store like MongoDB.

Frequently Asked Questions

How can I ensure my Hanami + MongoDB queries are scoped to the current user?
Always pass the authenticated subject’s identifier (e.g., user_id) explicitly into repository methods and include it in every MongoDB query predicate, instead of relying solely on the document’s _id supplied by the client.
What should I do if middleBrick flags identification issues in my API scan?
Review the specific endpoints and query patterns reported, validate and normalize all identifiers, enforce server-side scoping by user context, and use strict type conversions for MongoDB _id values to prevent tampering and privilege escalation.