HIGH cache poisoninghanamibearer tokens

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.

Frequently Asked Questions

How does middleBrick detect cache poisoning risks related to Bearer tokens?
middleBrick performs unauthenticated scans that test whether responses vary correctly with the Authorization header and checks for missing Vary or Cache-Control headers. It reports findings when cached responses could be reused across users.
Can middleBrick integrate with Hanami CI/CD workflows to prevent caching misconfigurations?
Yes, with the Pro plan, the GitHub Action can be added to CI/CD pipelines to fail builds if security scores drop below your threshold, helping catch caching misconfigurations before deployment.