Auth Bypass in Hanami with Api Keys
Auth Bypass in Hanami with Api Keys — how this specific combination creates or exposes the vulnerability
Hanami is a Ruby web framework that encourages explicit routing and controller design. When API keys are used for authentication, implementation details—such as where keys are read, how they are compared, and whether they are required for every action—directly affect whether an auth bypass is possible.
An auth bypass occurs when a protected endpoint can be accessed without presenting a valid API key, or when a key intended for one scope or tenant is accepted for another. With Hanami, common contributors include:
- Key lookup returning
nilfor an empty or missing header, and the controller continuing without raising an error. - Use of a non-constant-time comparison (e.g.,
==) that permits timing-based leakage or weak matching logic. - Conditional checks that are skipped for certain HTTP methods, formats (e.g., HTML fallback), or when a parameter is present, allowing unauthenticated access through alternative paths.
- Reuse of the same key across multiple services without scoping, enabling lateral movement across endpoints that should enforce distinct identities.
Because middleBrick tests unauthenticated attack surfaces, it can detect endpoints that do not enforce key validation consistently. For example, if a Hanami controller defines a before filter that only runs on POST but not on GET, or if a developer accidentally writes a branch like if api_key.present? instead of enforcing presence, the scan may highlight the missing enforcement as a high-severity finding.
In OpenAPI terms, missing or inconsistent key requirements may not be reflected in the spec, or the spec may use a global security scheme that does not map to each operation. middleBrick cross-references the declared securitySchemes and operations with runtime behavior, which helps expose mismatches where the spec claims key-based security but some paths do not actually enforce it.
Api Keys-Specific Remediation in Hanami — concrete code fixes
Remediation focuses on making key validation mandatory, consistent, and resilient. Below are concrete, idiomatic Hanami examples that reflect secure practices.
1. Enforce presence and use secure comparison
Always validate that the key is present and non-empty before proceeding. Use a constant-time comparison when dealing with secrets to reduce timing attack risk. Hanami does not include a built-in constant-time comparator, so use a reliable library such as secure_compare.
# Gemfile
gem 'secure_compare'
# app/actions/api/base.rb
require 'secure_compare'
module Api
class BaseAction < Hanami::Action
before :authenticate_api_key
private
def authenticate_api_key(ctx)
provided = ctx.env['HTTP_X_API_KEY']
expected = ENV['API_KEY']
unless provided&.present? && SecureCompare.secure_compare(provided, expected)
ctx.status = 401
ctx.body = { error: 'Unauthorized' }.to_json
ctx.halt
end
end
end
end
2. Apply globally and scope per operation
Use a base action for all API endpoints and ensure each operation explicitly inherits it. Avoid optional skipping unless absolutely necessary, and if you must allow bypass for certain routes, do so through configuration rather than ad-hoc conditionals.
# app/actions/articles/show.rb
class Articles::ShowAction < Api::BaseAction
# inherits authentication from base; no extra conditionals
def handle(params)
article = ArticleRepository.new.find(params[:id])
ctx.status = 200
ctx.body = ArticleEntity.new(article).serializable_hash
end
end
3. Reject ambiguous formats and enforce strict content negotiation
Ensure your API does not fall back to HTML or other formats when the client fails to provide a valid key. Configure route constraints and response handling to keep the surface minimal.
# config/routes.rb
Rails.application.routes.draw do
scope '/api', defaults: { format: :json } do
get 'articles/:id', to: 'articles#show', constraints: ->(req) { req.headers['X-API-KEY'].present? }
end
end
4. Rotate keys and avoid shared keys across services
Treat API keys as scoped credentials. If a key is compromised, limit the blast radius by ensuring it is valid only for a specific service or tenant.
# Example environment setup
# .env.production
API_KEY=prod_service_a_32byte_secure_random_value_here
Related CWEs: authentication
| CWE ID | Name | Severity |
|---|---|---|
| CWE-287 | Improper Authentication | CRITICAL |
| CWE-306 | Missing Authentication for Critical Function | CRITICAL |
| CWE-307 | Brute Force | HIGH |
| CWE-308 | Single-Factor Authentication | MEDIUM |
| CWE-309 | Use of Password System for Primary Authentication | MEDIUM |
| CWE-347 | Improper Verification of Cryptographic Signature | HIGH |
| CWE-384 | Session Fixation | HIGH |
| CWE-521 | Weak Password Requirements | MEDIUM |
| CWE-613 | Insufficient Session Expiration | MEDIUM |
| CWE-640 | Weak Password Recovery | HIGH |