HIGH cache poisoninghanami

Cache Poisoning in Hanami

How Cache Poisoning Manifests in Hanami

Cache poisoning in Hanami typically occurs when dynamic request values—such as Accept-Language, X-Forwarded-Host, or cookie fragments—are embedded into cache keys without normalization or validation. Hanami’s default production adapter uses a Rack-based cache, and if the key derivation includes attacker-controlled inputs, a malicious client can cause the application to serve one user’s response to another, or even inject crafted content into the cache. For example, a route like GET /products/:id that varies cache by a raw params[:currency] value can be abused: an attacker requests /products/123?currency=EUR and then requests /products/123?currency=, leading to a poisoned entry that later serves reflected script to other users if the cache is shared across users.

Hanami-specific code paths where this appears include custom cache stores set via config.cache.store and view fragment caching in templates. In a Hanami controller, calling cache([params[:action], params[:id], params[:filter]]) without sanitizing params[:filter] can introduce injection because the cache key becomes mutable by the client. Similarly, using Hanami::View::Partials with dynamic locals that are included in the cache namespace can produce predictable, mutable keys. Attack patterns include locale-based cache poisoning via the Accept-Language header, host-based poisoning via X-Forwarded-Host, and parameter pollution where repeated or unexpected keys alter the cache key in unintended ways, leading to content replacement or cross-user leakage.

Hanami-Specific Detection

To identify cache poisoning in Hanami, focus on how cache keys are constructed in production and whether they include unvalidated request inputs. Review configuration for config.cache.store and any custom key builders. Look for patterns where params, headers, or cookies directly influence the cache namespace without normalization, hashing, or scope isolation. You can detect risky constructs by scanning your Hanami app with middleBrick, which runs 12 security checks in parallel, including BFLA/Privilege Escalation and Input Validation tests that surface cache key manipulation risks. The scanner analyzes your OpenAPI/Swagger spec (2.0, 3.0, 3.1) with full $ref resolution and cross-references spec definitions with runtime findings to highlight endpoints where unauthenticated or user-influenced cache behavior may exist.

Using the middleBrick CLI, run middlebrick scan <url> to perform a black-box scan against your Hanami endpoint. The report will flag findings such as missing input validation on parameters that influence caching, missing rate limiting that enables cache flooding, and data exposure risks where poisoned cache entries could reveal PII. The LLM/AI Security checks unique to middleBrick also probe for indirect risks, such as whether public endpoints inadvertently expose cache controls that could be abused. With the GitHub Action, you can integrate these checks into CI/CD and fail builds if the risk score drops below your chosen threshold, while the Web Dashboard lets you track how cache-related findings evolve as your codebase changes.

Hanami-Specific Remediation

Remediate cache poisoning in Hanami by ensuring cache keys are deterministic, scoped, and free of attacker-controlled variability. Use Hanami’s built-in utilities to normalize inputs before they enter the cache key. For example, instead of directly interpolating params, derive a stable fragment with permitted keys and explicit defaults:

# Good: deterministic, sanitized cache key fragment
currency = params.fetch(:currency, 'USD')
unless %w[USD EUR GBP].include?(currency)
  currency = 'USD'
end
cache_key = [params[:action], params[:id], currency]
cache(cache_key) do
  # render partial or data
end

When configuring the cache store, scope caches per-tenant or per-user where appropriate to prevent cross-user pollution. Hanami’s support for custom cache stores lets you wrap entries with a namespaced key that excludes volatile headers:

# config/initializers/cache.rb
Hanami.configure do |config|
  config.cache = { store: :redis, namespace: 'hanami_app_v1' }
end

In views, avoid injecting raw request values into partial cache names. Instead, map them to a controlled set:

# app/views/products/show.html.erb
<% filter = SafeFilterService.call(params[:filter])
cache([params[:action], params[:id], filter]) do %>
  <%= render 'product', product: @product %>
<% end %>

Combine these practices with input validation libraries permitted by Hanami to reject malformed values early, and ensure that shared caches differentiate by tenant or user ID explicitly. These steps reduce the risk of cache poisoning while preserving performance benefits.

Frequently Asked Questions

Can middleBrick detect cache poisoning in Hanami apps without access to source code?
Yes. middleBrick performs black-box scanning, so it can identify endpoints where cache behavior varies on unvalidated inputs such as headers or query parameters, even without source code. It cross-references your OpenAPI/Swagger spec with runtime findings to highlight risky cache-dependent routes.
Does middleBrick’s LLM/AI Security testing help identify cache poisoning risks in Hanami?
While LLM/AI Security focuses on prompt injection and model-specific risks, middleBrick’s broader checks like Input Validation and BFLA/Privilege Escalation help surface cache poisoning indicators by testing how endpoints behave with manipulated inputs and role-based access patterns.