HIGH clickjackinghanamiapi keys

Clickjacking in Hanami with Api Keys

Clickjacking in Hanami with Api Keys — how this specific combination creates or exposes the vulnerability

Clickjacking is a client-side UI redress attack where an attacker tricks a user into clicking or interacting with a hidden or disguised element within a transparent or opaque overlay. In a Hanami application that exposes API keys in responses or UI flows, the combination of clickjacking and leaked keys can lead to unauthorized actions and key exfiltration. Hanami, being a Ruby web framework that encourages explicit views and minimal magic, does not automatically protect against frame embedding unless developers opt in with modern headers.

When API keys are returned in HTML responses, embedded in JavaScript variables, or rendered in forms without anti-clickjacking protections, an attacker can craft a page that loads the Hanami app inside an <iframe> and overlay invisible controls to capture key disclosures or trigger key-using endpoints. For example, an endpoint that returns a JSON representation of a key in a browser (e.g., for debugging or developer experience) might be invoked via a form or link that an attacker can mask with a transparent layer. If the response includes keys in plaintext and lacks frame-busting or Content-Security-Policy frame-ancestors rules, the key can be exposed to a logged-in user who is tricked into interacting with the invisible overlay.

Moreover, if the Hanami app embeds API keys in frontend JavaScript (e.g., for client-side libraries or service integrations), clickjacking can be used to drive the user to perform actions that send those keys to attacker-controlled endpoints. The risk is amplified when API keys are used for third-party integrations and the app lacks strict referrer and CSP policies. OWASP Top 10 A05:2021 (Security Misconfiguration) and A02:2021 (Cryptographic Failures) are relevant when keys are exposed in responses without adequate transport protections or frame-ancestor restrictions. middleBrick scans for such exposures under Data Exposure and Input Validation checks, flagging endpoints that leak secrets in unauthenticated contexts.

Api Keys-Specific Remediation in Hanami — concrete code fixes

Remediation centers on preventing key leakage in responses and hardening the UI against framing. Below are concrete Hanami patterns and code examples you can apply.

1. Prevent key leakage in JSON responses

Ensure API keys are never returned in HTML or JSON responses unless strictly necessary and properly scoped. Use view models or serializers that exclude sensitive fields in non-admin contexts.

# app/views/api_keys/show.json.eye
object.only(*allowed_attributes)
object.except!(:value) if current_user.admin? == false

# Allowed attributes might exclude :value or :raw_key
allowed_attributes = [:id, :name, :created_at] unless current_user.admin?

2. Set HTTP headers to prevent framing

Add middleware or a base controller to enforce X-Frame-Options and Content-Security-Policy frame-ancestors. In Hanami, you can do this in a base action or via a Rack middleware configuration outside of Hanami’s internal concerns.

# config/initializers/frame_protection.rb
Rack::Protection::FrameOptions.default_options[:block] = true

# Alternatively, in a Hanami controller concern
module FrameProtection
  def self.included(base)
    base.before :set_frame_headers
  end

  def set_frame_headers
    response.headers['X-Frame-Options'] = 'DENY'
    response.headers['Content-Security-Policy'] = "frame-ancestors 'none'"
  end
end

class ApplicationController < Hanami::Controller
  include FrameProtection
end

3. Avoid embedding keys in JavaScript

Do not serialize API keys into HTML or inline scripts. If client-side keys are required, serve them via a protected endpoint with strict CORS and short-lived tokens instead of long-lived API keys.

# BAD: exposes key in HTML source
<script>const apiKey = '<%= ENV['EXTERNAL_API_KEY'] %>'</script>

# BETTER: obtain via an authenticated endpoint that returns a scoped token
fetch('/api/v1/token', {
  method: 'POST',
  headers: { 'Authorization': 'Bearer ' + session_jwt },
  body: JSON.stringify({ scope: 'external_service' })
}).then(r => r.json()).then(data => useToken(data.token))

4. Enforce strict Content-Security-Policy

Limit where frames can be embedded from. Use a restrictive CSP in production to mitigate clickjacking even if X-Frame-Options is absent.

# config/initializers/content_security_policy.rb
Hanami::Middleware::ContentSecurityPolicy.configure do |policy|
  policy.frame_ancestors none: true
  policy.default_src :self, :https
  policy.script_src :self, :https, :unsafe_inline # avoid :unsafe_eval
end

5. Validate and sanitize inputs to prevent injection via UI

Ensure that any user-controlled data used in views does not enable injection that could facilitate clickjacking vectors (e.g., open redirects that lead to key-bearing pages).

# app/validators/api_key_input_validator.rb
class ApiKeyInputValidator
  include Hanami::Validations::FormValidator

  validations do
    required(:name).filled(:str?) 
    required(:value).filled(:str?, format?: /^[A-Za-z0-9\-_]+$/)
  end
end

Frequently Asked Questions

How does middleBrick detect clickjacking-related data exposure in Hanami apps?
middleBrick runs unauthenticated scans with 12 parallel checks including Data Exposure and Input Validation. It examines responses for leaked API keys in plaintext, reviews CSP and X-Frame-Options headers via spec and runtime cross-referencing, and flags endpoints that return secrets without anti-framing protections.
Can middleBrick test active clickjacking scenarios against Hanami endpoints that use API keys?
middleBrick does not perform interactive exploitation or active clickjacking execution. It detects insecure configurations and data exposure findings with remediation guidance, but it does not block, patch, or exploit vulnerabilities.