Cache Poisoning in Hanami with Bearer Tokens
Cache Poisoning in Hanami with Bearer Tokens — how this specific combination creates or exposes the vulnerability
Cache poisoning occurs when an attacker causes a cache to store malicious responses that are served to other users. In Hanami applications, when endpoints that include per-user Bearer tokens are inadvertently cached, the cached response can be reused across different users, leading to information disclosure or privilege confusion. This typically arises when a caching layer (e.g., a CDN, reverse proxy, or in-memory cache) uses the request URL as the cache key but does not consider the Authorization header. If an endpoint like /api/profile is cached based on the URL alone, a response containing a valid Bearer token in the Authorization header could be served to another user who did not authenticate as the original subject.
Hanami applications that use token-based authentication must ensure that responses containing sensitive Authorization headers are not cached, or that cache keys explicitly exclude or incorporate the Authorization header to prevent cross-user contamination. For example, a request with Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9 might return user-specific data; if cached without header-aware keying, another user’s request to the same URL could receive this cached response and be incorrectly authenticated as the first user.
Real-world attack patterns mirror findings from OWASP API Top 10 and common misconfigurations in API gateways. A scanner that tests unauthenticated attack surfaces, such as middleBrick, can detect whether responses vary correctly with Authorization headers and whether caching headers (e.g., Cache-Control, Vary) are properly configured. Without such validation, an attacker may exploit predictable cache behavior to access another user’s data, akin to Insecure Direct Object Reference (IDOR) when object-level authorization is not enforced in combination with caching logic.
Concrete examples of risky Hanami controller actions include those that render JSON without excluding the Authorization header from cache considerations:
# config/routes.rb
Rack::Builder.new do
use Rack::Cache,
metastore: 'file:/var/cache/rack/meta',
entitystore: 'file:/var/cache/rack/body'
run MyApp::Routes
end
In this setup, if the application does not set appropriate Vary headers, a cached response for GET /api/widgets/1 with a Bearer token could be served to another user. The fix requires ensuring that responses containing Authorization tokens are marked as private or vary by the Authorization header, preventing unintended reuse across users.
Bearer Tokens-Specific Remediation in Hanami — concrete code fixes
Remediation focuses on ensuring that cached responses are not shared across users when Bearer tokens are present. In Hanami, this involves configuring HTTP caching headers correctly and ensuring that the Authorization header is part of the cache key or that sensitive responses are marked as non-cacheable.
1. Set Vary: Authorization on responses that depend on the Authorization header. This instructs caches to store separate versions per token.
# app/controllers/api/base.rb
module Api
class Base < Hanami::Action
def call(params)
super do |headers, status, body|
headers['Vary'] = 'Authorization'
end
end
end
end
2. Avoid caching responses that contain or depend on Bearer tokens. Use no-store for sensitive endpoints.
# app/controllers/api/users/show.rb
class Api::Users::Show < Hanami::Action
def handle_request
headers['Cache-Control'] = 'no-store'
# ... action logic
end
end
3. For endpoints that must be cached, ensure the cache key incorporates the token or user identifier explicitly, or restrict caching to public endpoints that do not require authentication.
# app/actions/api/widgets/show.rb
class Api::Widgets::Show < Hanami::Action
def expose
token = request.env['HTTP_AUTHORIZATION']&.split(' ')&.last
cache_key = ["widgets/#{params[:id]}", Digest::SHA256.hexdigest(token)].join(':')
# Use cache_key with your caching backend
end
end
These code examples illustrate how to align Hanami application logic with secure caching practices when Bearer tokens are used. By varying cache by Authorization and avoiding caching of sensitive responses, you reduce the risk of cache poisoning across users.