Api Key Exposure in Hanami with Hmac Signatures
Api Key Exposure in Hanami with Hmac Signatures — how this specific combination creates or exposes the vulnerability
Hanami is a Ruby web framework that encourages explicit request handling and can integrate Hmac Signatures to verify the integrity and origin of incoming requests. When Hmac Signatures are used incorrectly, they can inadvertently expose API keys or related secrets, increasing the risk of unauthorized access. This specific combination becomes a vulnerability when developers inadvertently expose the secret key or related configuration through logs, error messages, client-side code, or insufficient key management practices within the Hanami app.
In a Hanami application, Hmac Signatures typically involve generating a signature on the client using a shared secret and including that signature in request headers. If the shared secret is stored in environment variables that are accidentally logged or exposed via debugging endpoints, an attacker who sees a single valid request and signature can attempt to brute-force or deduce the secret. MiddleBrick’s scan checks for such exposures by analyzing unauthenticated endpoints and cross-referencing runtime behavior with the OpenAPI spec, flagging cases where secrets might be derivable or observable.
Another exposure path arises when the Hanami app returns detailed errors that include the secret or parts of the signature logic. For example, a poorly rescued exception during signature verification might print the key or the computed digest, giving an attacker hints. Since middleBrick tests unauthenticated attack surfaces, it can detect endpoints where error responses reveal stack traces or configuration details that reference the Hmac secret. Additionally, if the client-side code (such as JavaScript embedded in views) contains the key or a derivation of it, middleBrick’s Data Exposure and Unsafe Consumption checks can flag this as a finding because client-accessible code should never hold shared secrets.
SSRF and Inventory Management checks also highlight risks when the Hanami service calls internal metadata services or external endpoints using keys embedded in headers that are not properly isolated. If an attacker can trigger an SSRF via user-controlled URLs in a Hanami endpoint that signs requests, they may be able to force the app to sign arbitrary internal requests, exposing patterns that make the API key usage detectable. The scan runs 12 checks in parallel, including Authentication and BOLA/IDOR, to surface cases where key usage is inconsistent or overly permissive.
Using the middleBrick CLI, you can scan a Hanami API endpoint to see whether Hmac Signature implementations leak keys or create weak verification paths. The report includes severity-ranked findings and remediation guidance, helping you understand how the combination of Hanami and Hmac Signatures can expose sensitive material without proper safeguards. Remember that middleBrick detects and reports these conditions but does not modify your code or infrastructure; it provides prioritized guidance to help you harden the integration.
Hmac Signatures-Specific Remediation in Hanami — concrete code fixes
To remediate Api Key Exposure when using Hmac Signatures in Hanami, focus on keeping the shared secret out of logs, client-side code, and error messages, and enforce strict verification logic. Below are concrete code examples that demonstrate secure practices for generating and verifying Hmac Signatures within a Hanami application.
Secure Hmac Signature generation and verification in Hanami
Use environment variables to inject the secret at runtime and avoid hardcoding it. Keep the secret at the server side only, and ensure that any logging or exception handling scrubs sensitive values.
# config/initializers/hmac.rb
require 'openssl'
require 'base64'
module HmacSecurity
SECRET = ENV.fetch('HMAC_SECRET_KEY') # Ensure this is set in the server environment
def self.generate_signature(payload)
digest = OpenSSL::Digest.new('sha256')
Base64.strict_encode64(OpenSSL::HMAC.digest(digest, SECRET, payload))
end
def self.verify_signature(payload, received_signature)
expected = generate_signature(payload)
# Use secure compare to avoid timing attacks
ActiveSupport::SecurityUtils.secure_compare(expected, received_signature)
rescue
false
end
end
In your Hanami controller, validate the signature before processing the request:
# app/controllers/api/base.rb
require 'hanami/controller'
require_relative '../../initializers/hmac'
module Api
class Base < Hanami::Action
before :verify_hmac_signature
private
def verify_hmac_signature
payload = request.body.read
request.body.rewind
signature = request.env['HTTP_X_API_SIGNATURE']
unless HmacSecurity.verify_signature(payload, signature)
halt 401, { error: 'invalid_signature' }.to_json
end
rescue => e
# Avoid leaking exception details or secrets in logs
Hanami.logger.warn('Hmac verification failed')
halt 401, { error: 'unauthorized' }.to_json
end
end
end
On the client side, generate the signature using the same algorithm and include it in headers without exposing the secret:
# Example client code (not part of Hanami server)
require 'openssl'
require 'base64'
def build_auth_headers(api_key, method, path, body)
# api_key is used to retrieve the shared secret from a secure vault, not passed raw
secret = fetch_secret_for_key(api_key)
payload = "#{method}\n#{path}\n#{body}"
digest = OpenSSL::Digest.new('sha256')
signature = Base64.strict_encode64(OpenSSL::HMAC.digest(digest, secret, payload))
{
'X-API-Key' => api_key,
'X-API-Signature' => signature
}
end
Ensure that the secret is stored in a secure vault or environment configuration that is not accessible to the client or exposed in error traces. middleBrick’s Pro plan includes continuous monitoring and GitHub Action integration to enforce that such secrets are not present in code or logs by scanning your endpoints and flagging risky patterns during CI/CD pipelines.