Bola Idor in Hanami with Mutual Tls
Bola Idor in Hanami with Mutual Tls — how this combination creates or exposes the vulnerability
BOLA (Broken Object Level Authorization) in Hanami with Mutual TLS centers on how access control and client identity intersect. Even when the server validates the client certificate, application-level authorization must still be enforced per request. Mutual TLS authenticates the client to the transport layer, but it does not by itself ensure that a given client is allowed to access a specific resource or perform a specific action. If authorization checks are missing or inconsistent, an authenticated client can traverse IDs and access or modify objects belonging to other users.
In Hanami, this often appears in routes and controllers that use numeric or UUID identifiers directly from the URL without verifying ownership or scope. For example, an endpoint like GET /api/v1/invoices/:id may verify the client certificate but then return the invoice record if the ID exists, regardless of whether the authenticated client is entitled to view it. Because Mutual TLS provides a client identity (usually via the certificate subject or a mapped attribute), developers might mistakenly assume that transport-layer authentication is sufficient for object-level authorization. This assumption creates a BOLA condition: the attacker who possesses a valid client certificate can iterate through IDs and probe for records they should not see or change.
Real-world attack patterns mirror common OWASP API Top 10 and API security testing practices. Consider an API that exposes /api/v1/users/:user_id/profile. With Mutual TLS, the server may present a client certificate to the Hanami app, and the app may extract a username or ID from the certificate. If the app then loads User.find(params[:user_id]) without confirming that the extracted certificate identity matches user_id, the endpoint is vulnerable. An attacker with a valid certificate can change user_id to another integer or UUID and read or manipulate other users’ profiles. Similar issues occur in nested resources, such as /api/v1/organizations/:org_id/projects/:project_id, where missing ownership checks allow horizontal privilege escalation across teams or departments.
SSRF and external interactions can compound BOLA risks when combined with Mutual TLS. If Hanami services make outbound HTTP calls using parameters derived from user-controlled IDs, an attacker with a valid certificate may force the server to reach internal endpoints or metadata services. Because Mutual TLS ensures the client is trusted, developers might skip rigorous validation of the IDs that determine request targets. This trust can lead to scenarios where manipulated IDs direct outbound requests to internal AWS metadata endpoints or internal services, effectively turning a BOLA flaw into a broader SSRF pathway.
The interplay with OpenAPI/Swagger analysis is important when documenting and testing these endpoints. If your Hanami API is described with OpenAPI 3.0 or 3.1, $ref resolution should consistently map security schemes, including mutual TLS client certificate requirements, to the relevant paths. However, the presence of a security scheme in the spec does not guarantee that object-level authorization is implemented. Runtime findings from scans can highlight mismatches where Mutual TLS is declared but per-operation authorization is missing, helping you detect BOLA during continuous monitoring rather than during a manual review.
Mutual Tls-Specific Remediation in Hanami — concrete code fixes
Remediation focuses on ensuring that every request that accesses or modifies an object validates both the client certificate identity and the authorization to operate on the referenced resource. In Hanami, this typically means adding explicit checks in controllers or using dedicated authorization logic that ties the certificate subject to the domain model.
Example Hanami controller with Mutual TLS identity mapping and object-level authorization:
module Web::Controllers::Invoices
class Show
include Web::Action
# Assume `identity` is extracted from the client certificate by a TLS middleware
# and stored in `request.env['tls_client_identity']` as { id: 'uuid', type: 'client' }
def call(params)
client_identity = request.env['tls_client_identity']
raise HTTP::Forbidden unless client_identity
invoice = InvoiceRepository.new.find(params[:id])
if invoice&.client_id == client_identity[:id]
# Authorized to view this invoice
self.body = { invoice: invoice }
else
raise HTTP::Forbidden
end
end
end
end
Example Hanami controller with UUID-based resource ownership check and explicit error handling:
module Web::Controllers::Projects
class Update
include Web::Action
def call(params)
client_identity = request.env['tls_client_identity']
project = ProjectRepository.new.find(params[:project_id])
if project.nil? || project.organization_id != client_identity[:org_id]
raise HTTP::Forbidden
end
# Proceed with update logic
# ...
end
end
end
Example rack middleware that extracts and normalizes Mutual TLS identity for Hanami (simplified):
class TlsIdentityExtractor
def initialize(app)
@app = app
end
def call(env)
cert = env['ssl_client_cert']
if cert
subject = cert.subject.to_s
# Example: parse CN or SAN to extract a user or client ID
client_id = extract_id_from_subject(subject)
env['tls_client_identity'] = { id: client_id, type: 'client' }
else
env['tls_client_identity'] = nil
end
@app.call(env)
end
private
def extract_id_from_subject(subject)
# Implement robust parsing; this is a simplified example
subject.match(%r{CN=([^,]+)})&.captures&.first || 'unknown'
end
end
When using OpenAPI/Swagger, ensure that paths requiring object-level authorization also document the dependency on Mutual TLS and clearly describe which resource ownership rules apply. Complement automated scans with code reviews that verify that every data-loading operation checks the certificate-derived identity against the target object’s ownership or permissions. middleBrick can surface these authorization gaps during continuous monitoring so you can tighten controls before attackers exploit them.
Related CWEs: bolaAuthorization
| CWE ID | Name | Severity |
|---|---|---|
| CWE-250 | Execution with Unnecessary Privileges | HIGH |
| CWE-639 | Insecure Direct Object Reference | CRITICAL |
| CWE-732 | Incorrect Permission Assignment | HIGH |