Api Key Exposure in Hanami with Bearer Tokens
Api Key Exposure in Hanami with Bearer Tokens — 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 handled as Bearer tokens, they are typically transmitted in the Authorization header as Authorization: Bearer <token>. If a Hanami application inadvertently exposes these tokens—through logs, error messages, misconfigured headers, or insecure client-side code—an attacker who intercepts or views the token can impersonate the client or service. This exposure commonly occurs when developers accidentally render the Authorization header in HTML or JSON responses, log full headers including bearer values, or pass tokens through query parameters for convenience, which can leak via browser history or referrer headers.
In a black-box scan, middleBrick tests unauthenticated attack surfaces and checks for unsafe data exposure across 12 security checks. For endpoints that rely on Bearer tokens, middleBrick examines whether tokens might be echoed back in responses, included in error details, or transmitted over non-encrypted channels. Even when TLS is used, tokens can be exposed if the application includes them in logs that are accessible to attackers or if debug modes reveal header contents. Because Bearer tokens function like passwords, any exposure can lead to unauthorized access to protected resources, data exfiltration, or privilege escalation depending on the scope of the token.
Another vector involves improper handling of token storage in JavaScript or mobile clients that interact with Hanami backends. If a Hanami API returns tokens in JSON payloads or if client-side code stores them insecurely (e.g., in localStorage without additional protections), third-party scripts or compromised browsers can read these values. middleBrick’s Data Exposure check looks for sensitive data in responses and headers, flagging cases where bearer-like values appear in output. The LLM/AI Security checks also scan for system prompt leakage and output patterns that might inadvertently reveal structured secrets, helping identify scenarios where AI integrations or logging mechanisms expose token-like strings.
Middleware and instrumentation in Hanami applications can inadvertently amplify these risks. For example, logging middleware that serializes the full request environment may include the Authorization header verbatim. If those logs are centralized or archived without access controls, any token passed as a Bearer value becomes a long-lived secret in a potentially accessible store. Similarly, development or test configurations that disable security headers or use permissive CORS rules can widen the attack surface. middleBrick’s Inventory Management and Property Authorization checks help surface such configurations by analyzing the API specification and runtime behavior, ensuring that token-bearing routes are correctly protected and that overly permissive rules are identified.
When integrating third-party services that call a Hanami API using Bearer tokens, the risk of exposure increases if token rotation or scope management is inconsistent. Compromised tokens from external systems may grant broader access than intended, especially if the Hanami backend does not validate token scopes rigorously. middleBrick tests for BFLA and Privilege Escalation by attempting to access resources with modified identifiers or insufficient authorization context, which can reveal whether Bearer tokens are being validated in isolation or in combination with proper ownership checks. This helps highlight cases where token exposure leads not only to read access but also to unauthorized mutations.
Bearer Tokens-Specific Remediation in Hanami — concrete code fixes
To reduce the risk of Api Key Exposure in Hanami when using Bearer tokens, apply targeted code and configuration changes that minimize token leakage and enforce strict handling practices. Always transmit tokens exclusively via the Authorization header using the Bearer scheme, and avoid embedding them in URLs, HTML attributes, or JavaScript variables that are accessible to client-side code. Ensure that no middleware or logging logic captures the full Authorization header. Below are concrete examples that demonstrate secure patterns for Hanami controllers and configurations.
Secure Authorization Header Usage
When making authenticated requests to external services from a Hanami app, set the Authorization header explicitly without logging it:
# app/services/api_client.rb
require 'net/http'
require 'uri'
module ApiClient
def self.get_resource(access_token)
uri = URI('https://api.example.com/v1/resource')
request = Net::HTTP::Get.new(uri)
request['Authorization'] = "Bearer #{access_token}"
# Ensure the access_token variable is not logged or inspected
request['Accept'] = 'application/json'
response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
http.request(request)
end
JSON.parse(response.body)
end
end
On the receiving side, a Hanami controller should extract the token without echoing it:
# app/controllers/api_proxy.rb
require 'hanami/controller' # or 'hanami/action' depending on setup
class ApiProxy
include Hanami::Controller::Action
def call(ctx)
authorization = ctx.env['HTTP_AUTHORIZATION']
token = nil
if authorization&.start_with?('Bearer ')
token = authorization.slice(7..-1)
end
# Use token for backend calls; do not include it in responses or logs
result = ExternalService.fetch(token)
ctx.status = 200
ctx.response.body = { data: result }.to_json
end
end
Logging and Error Handling Controls
Configure logging to redact sensitive headers. In your Hanami application configuration or custom logger wrapper, filter out the Authorization header:
# config/initializers/filter_params.rb
class SensitiveHeaderFilter
def initialize(app)
@app = app
end
def call(env)
request = Rack::Request.new(env)
# Remove Authorization header from logs
env.delete('HTTP_AUTHORIZATION')
@app.call(env)
ensure
# Restore if needed for internal secure tracing with strict access controls
# env['HTTP_AUTHORIZATION'] = request.env['HTTP_AUTHORIZATION']
end
end
# config/application.rb
use SensitiveHeaderFilter
Ensure that error pages and rescue blocks do not include header details:
# app/errors/failure_app.rb
class FailureApp
def initialize(app)
@app = app
end
def call(env)
begin
@app.call(env)
rescue => e
# Do not expose env or request headers in error output
{ status: 500, headers: { 'Content-Type' => 'application/json' }, body: [{ error: 'Internal server error' }].to_json }
end
end
end
Token Storage and Client-Side Handling
If your Hanami application serves frontend JavaScript, avoid placing Bearer tokens in the browser-accessible scope. Use httpOnly cookies for session tokens when possible, or ensure that tokens are stored in memory only and never written to localStorage or sessionStorage. For API requests, set credentials to omit credentials unless necessary, and enforce strict CORS rules:
# config/initializers/cors.rb
Rack::Cors do
allow do
origins 'https://trusted-frontend.example.com'
resource '*',
headers: :any,
methods: %i[get post],
expose: ['X-Custom-Header'],
max_age: 3600
end
end