Beast Attack in Hanami with Bearer Tokens
Beast Attack in Hanami with Bearer Tokens — how this specific combination creates or exposes the vulnerability
A Beast Attack (short for Brute-force Security Testing) in the Hanami web framework becomes more impactful when Bearer Tokens are used for API authentication because predictable or leaked tokens reduce the entropy required to compromise an endpoint. Hanami encourages explicit, application‑level authentication; if Bearer Tokens are issued with low randomness, stored in logs, or transmitted without TLS, an attacker can enumerate valid tokens and leverage them across routes that rely on token‑based authorization.
Hanami’s default configuration does not enforce strict token binding or rotation, so a Beast Attack can exploit weak token generation to iterate through possible values and observe differences in responses (e.g., 200 vs 403) to infer validity. When combined with endpoints that return sensitive data or perform state changes, this becomes a practical authorization bypass. The unauthenticated attack surface scanned by middleBrick can detect such behaviors—missing rate limiting on token validation routes, inconsistent error handling, and missing authorization checks on sensitive actions.
Additionally, if Bearer Tokens are passed via query parameters or non‑HTTPS channels, network sniffing increases the risk of token leakage, enabling replay or lateral movement within the application. The 12 security checks in middleBrick test these conditions in parallel, including Authentication, Input Validation, and Data Exposure, to identify whether Hanami endpoints inadvertently expose token handling weaknesses. Findings from these checks map to OWASP API Top 10 controls and help prioritize remediation specific to token‑based flows.
Bearer Tokens-Specific Remediation in Hanami — concrete code fixes
Remediation focuses on strengthening token generation, transmission, and validation within Hanami. Use cryptographically secure random values for tokens, enforce HTTPS, and ensure tokens are validated server‑side on every request. Below are concrete code examples for secure Bearer Token handling in Hanami.
1. Generate a secure Bearer token
Use SecureRandom.uuid or SecureRandom.hex to generate high‑entropy tokens:
require 'securerandom'
class App::Entities::Account
def self.generate_access_token
SecureRandom.uuid # 128-bit entropy, URL‑safe
end
end
# Example usage:
token = App::Entities::Account.generate_access_token
# => "f47ac10b-58cc-4372-a567-0e02b2c3d479"
2. Transmit tokens only over HTTPS and via headers
Ensure tokens are sent in the Authorization header and never in URLs or query parameters:
# config/environments/production.rb
Rack::Builder.new do
use Rack::SSL if ENV['RACK_ENV'] == 'production'
run App::Web
end
# In a controller filter (Hanami::Action):
class Api::V1::Base < Hanami::Action
def before(params)
auth_header = request.env['HTTP_AUTHORIZATION']
raise Hanami::Action::Unauthorized unless auth_header&.start_with?('Bearer ')
token = auth_header.split(' ').last
raise Hanami::Action::Unauthorized unless valid_token?(token)
end
private
def valid_token?(token)
# Compare using constant‑time comparison to avoid timing attacks
ActiveSupport::SecurityUtils.secure_compare(
token,
lookup_token_for_user(request.ip)
)
end
end
3. Enforce token binding and scope checks
Validate token scope and bind tokens to specific routes or actions to limit privilege escalation:
class Api::V1::Payments < Hanami::Action
def handle
token_payload = decode_jwt(request.env['HTTP_AUTHORIZATION'].split(' ').last)
unless token_payload['scope']&.include?('payments:write')
raise Hanami::Action::Forbidden
end
# proceed with payment logic
end
private
def decode_jwt(token)
# Use a verified JWT library; ensure secret/key management is handled externally
JWT.decode(token, ENV['JWT_SECRET_KEY'], true, { algorithm: 'HS256' }).first
rescue JWT::DecodeError
raise Hanami::Action::Unauthorized
end
end
4. Add rate limiting on token validation endpoints
Prevent brute‑force attempts by limiting requests per IP or token:
# Using a simple in‑memory store for demonstration; prefer Redis in production
class RateLimiter
def initialize(limit: 5, period: 60)
@limit = limit
@period = period
@store = {} # key: ip, value: { count: Integer, first_seen: Time }
end
def allowed?(ip)
now = Time.now
record = @store[ip] || { count: 0, first_seen: now }
if now - record[:first_seen] > @period
record = { count: 1, first_seen: now }
else
record[:count] += 1
end
@store[ip] = record
record[:count] <= @limit
end
end
# In your action:
limiter = RateLimiter.new(limit: 10, period: 30)
unless limiter.allowed?(request.ip)
raise Hanami::Action::TooManyRequests
end
5. Logging and monitoring without exposing tokens
Ensure logs never capture full Bearer Tokens. Use filters or redaction:
# config/initializers/filter_parameter_logging.rb
Hanami::.configure do |config|
config.filter_parameters += [:authorization, :token]
end