HIGH clickjackinghanamihmac signatures

Clickjacking in Hanami with Hmac Signatures

Clickjacking in Hanami with Hmac Signatures — how this specific combination creates or exposes the vulnerability

Clickjacking is a client-side UI redress attack where an attacker tricks a user into interacting with a hidden or disguised element inside an invisible or overlaying page. In Hanami, relying only on Hmac Signatures for request verification does not prevent clickjacking because the signature is typically computed over parameters and a timestamp, not over the rendered frame context or the presence of framing headers. If a Hanami endpoint renders HTML intended for embedding but does not set X-Frame-Options or Content-Security-Policy with frame-ancestors, an attacker can embed the page in an <iframe> and overlay transparent controls to capture clicks.

Hmac Signatures in Hanami are commonly used to ensure request integrity—for example, to validate webhook payloads or signed query parameters. However, if the signature is included in a query string or header without protection against being read and reused in a forged framed request, clickjacking can still occur. An attacker can load the legitimate Hanami page in a frame, read the visible UI (if same-origin or via other leaks), and replay the signed request by tricking the user into clicking through the invisible frame. Because the Hmac Signature does not inherently bind the request to a specific frame context or referrer, the server may accept it as valid even though the user did not intend the interaction.

For example, a Hanami webhook endpoint that verifies an Hmac Signature on the payload will still process the request if the attacker can cause the user’s browser to submit a valid signed request via a forged form inside an iframe. The signature may be intact, but the lack of anti-clickjacking headers means the user interface was socially engineered rather than intentionally activated. This is especially relevant when the signed request performs state-changing operations, such as updating settings or initiating transactions. Therefore, Hmac Signatures must be complemented by frame protection mechanisms to mitigate clickjacking in Hanami.

A realistic Hanami controller that uses Hmac Signatures for webhook validation but omits frame protections might look like this:

module Webhooks
  class PaymentsController < Hanami::Action
    def create
      payload = request.body.read
      signature = request.headers['X-Signature']
      expected = generate_hmac(payload)
      if Rack::Utils.secure_compare(expected, signature)
        # Process payment — vulnerable if embedded in a clickjacked frame
        render json: { status: 'ok' }
      else
        render json: { error: 'invalid signature' }, status: 401
      end
    end

    private

    def generate_hmac(data, key = ENV['WEBHOOK_SECRET'])
      OpenSSL::HMAC.hexdigest('sha256', key, data)
    end
  end
end

Hmac Signatures-Specific Remediation in Hanami — concrete code fixes

To remediate clickjacking risks when using Hmac Signatures in Hanami, you should combine cryptographic integrity checks with anti-framing defenses. Hmac Signatures ensure the request has not been tampered with, but they do not prevent the page from being embedded. Add HTTP headers to restrict framing and ensure that signed endpoints are not usable in an unintended context.

First, configure your Hanami application to set X-Frame-Options and a strict Content Security Policy with frame-ancestors. This prevents browsers from rendering your pages inside iframes unless explicitly allowed. For public-facing endpoints that do not need to be framed, this is a strong mitigation.

Second, when validating Hmac Signatures, consider including additional context such as a nonce or referrer check if your use case requires higher assurance. Below is a concrete Hanami controller example that combines Hmac verification with frame protection headers and a basic origin check to reduce clickjacking risk:

module Webhooks
  class PaymentsController < Hanami::Action
    def create
      # Anti-clickjacking headers
      response.headers['X-Frame-Options'] = 'DENY'
      response.headers['Content-Security-Policy'] = "frame-ancestors 'none'"

      payload = request.body.read
      signature = request.headers['X-Signature']
      expected = generate_hmac(payload)

      if Rack::Utils.secure_compare(expected, signature)
        # Optionally verify origin for additional safety
        unless allowed_origin?(request.env['HTTP_ORIGIN'])
          raise Hanami::Action::UnauthorizedError, 'Origin not allowed'
        end

        render json: { status: 'ok' }
      else
        render json: { error: 'invalid signature' }, status: 401
      end
    end

    private

    def generate_hmac(data, key = ENV['WEBHOOK_SECRET'])
      OpenSSL::HMAC.hexdigest('sha256', key, data)
    end

    def allowed_origin?(origin)
      return false if origin.nil?
      # Example: allow only your frontend origin
      origin == 'https://app.yourapp.com'
    end
  end
end

For non-webhook endpoints that render HTML, ensure that layout or application-wide headers enforce frame restrictions. You can use Hanami's middleware configuration to set these headers globally, reducing the chance that any page protected by Hmac Signatures is embedded maliciously. Remember that Hmac Signatures protect integrity and authenticity, but clickjacking defense requires explicit framing controls.

Frequently Asked Questions

Do Hmac Signatures alone prevent clickjacking in Hanami?
No. Hmac Signatures ensure request integrity but do not prevent a page from being embedded in an iframe. You must add X-Frame-Options and Content-Security-Policy frame-ancestors rules to mitigate clickjacking.
Can a signed URL be exploited via clickjacking in Hanami?
Yes. If a signed URL is loaded in a hidden frame and the user is tricked into clicking through transparent overlays, the signed request can be replayed. Combine signature validation with anti-framing headers to reduce this risk.