MEDIUM clickjackinghanamicockroachdb

Clickjacking in Hanami with Cockroachdb

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

Clickjacking is a client-side UI vulnerability where an attacker tricks a user into interacting with a hidden or disguised element inside an invisible or transparent page. In a Hanami application that uses Cockroachdb as the backend datastore, the risk arises not from Cockroachdb itself, but from how Hanami serves pages and frames that may lack proper anti-clickjacking protections. If a Hanami view embeds third-party content in an <iframe> or fails to set the X-Frame-Options header or Content-Security-Policy frame-ancestors directive, an attacker can overlay invisible controls on top of authenticated pages, such as fund transfers or profile updates, that ultimately commit actions against the Cockroachdb-backed persistence layer.

Because Hanami is a full-stack Ruby framework, it often renders server-generated HTML with embedded state tokens, and if those pages are inadvertently framed, the token and user session remain valid within the hidden context. Cockroachdb, as the distributed SQL store, will faithfully persist whatever operations Hanami executes, including unauthorized state changes triggered via clickjacked interactions. For example, an attacker might load the Hanami dashboard in an iframe, set the opacity to zero, and place a button or form submission over a sensitive action like changing an email address. When the victim clicks what they believe is a benign page, the hidden form submits with the user’s credentials and session, and Hanami processes the request, writing the change to Cockroachdb.

In practice, this combination becomes critical when Hanami serves administrative or sensitive endpoints without frame-protection headers. Even if Cockroachdb enforces strong consistency and permissions, the application layer must ensure that responses include frame-deny policies. Without Content-Security-Policy: frame-ancestors or explicit X-Frame-Options, the browser will render the page in a frame regardless of the underlying database security model. Therefore, the exposure stems from missing HTTP headers and insecure view composition in Hanami, which allow an attacker to leverage the user’s authenticated session to perform actions that ultimately mutate data in Cockroachdb.

Cockroachdb-Specific Remediation in Hanami — concrete code fixes

Remediation focuses on preventing pages from being embedded in frames and ensuring that state-modifying requests cannot be triggered via invisible forms. In Hanami, you can enforce this at the application level by configuring default headers and tightening view rendering. Below are concrete steps and code examples tailored for a Hanami app backed by Cockroachdb.

1. Set HTTP headers to prevent framing

Ensure every response includes Content-Security-Policy with frame-ancestors and X-Frame-Options. In Hanami, you can use a middleware or a before action to inject these headers.

# config/initializers/security_headers.rb
module SecurityHeaders
  def self.registered(app)
    app.before do
      response['X-Frame-Options'] = 'DENY'
      response['Content-Security-Policy'] = "frame-ancestors 'none'"
    end
  end
end

Hanami.configure do |config|
  config.middleware.insert_after Rack::Runtime, SecurityHeaders
end

This configuration ensures that browsers will not render any Hanami page inside a frame, mitigating clickjacking regardless of how the Cockroachdb layer processes the request.

2. Use strong authenticity tokens and verify origins

Hanami includes built-in CSRF protection which should be leveraged to ensure that state-modifying POST, PUT, PATCH, and DELETE requests originate from your own pages. Combine this with strict referrer checks on sensitive endpoints.

# app/actions/web/account/update_email.rb
module Web::Account
  class UpdateEmail
    include Hanami::Action

    def handle(request)
      # Verify origin and referer as an additional safeguard
      referer = request.env['HTTP_REFERER']
      unless referer&.start_with?(request.env['HTTP_HOST'])
        raise Hanami::Action::UnauthorizedError, 'Invalid referer'
      end

      # Ensure CSRF token is validated (Hanami does this automatically for forms)
      # Proceed only if request is authenticated and token matches
      user = request.session[:user_id]
      new_email = params[:email]

      # Safe Cockroachdb interaction using Hanami::Repository
      account_repo = AccountRepository.new
      account_repo.update_email(user, new_email)

      response.status = 200
      response.body = { message: 'Email updated' }.to_json
    end
  end
end

# db/repositories/account_repository.rb
class AccountRepository
  def initialize
    @db = Cockroachdb::Database.new(ENV.fetch('DATABASE_URL'))
  end

  def update_email(user_id, new_email)
    # Cockroachdb SQL with explicit parameterization to avoid injection
    @db.execute(
      'UPDATE users SET email = $1 WHERE id = $2',
      new_email, user_id
    )
  end
end

In this example, the action verifies the HTTP Referer header and relies on Hanami’s CSRF token validation. The Cockroachdb interaction uses parameterized queries via Hanami::Repository to prevent SQL injection, ensuring that even if clickjacking bypasses UI layers, unauthorized data mutation is still blocked by server-side checks.

3. Isolate sensitive actions behind additional UI and server-side checks

For critical operations, consider requiring re-authentication or a one-time token. This ensures that even if a page is framed, the attacker cannot forge a valid request without the user’s explicit consent.

# app/actions/web/account/change_password.rb
module Web::Account
  class ChangePassword
    include Hanami::Action

    def handle(request)
      # Require explicit re-auth for sensitive changes
      unless request.session[:reauth_at] && request.session[:reauth_at] > 10.minutes.ago
        redirect_to '/reauth?next=/account/change_password'
        return
      end

      # Proceed with Cockroachdb update using Hanami::Repository
      password_repo = PasswordRepository.new
      password_repo.update(request.session[:user_id], params[:new_password])

      response.status = 200
      response.body = { message: 'Password changed' }.to_json
    end
  end
end

By requiring recent re-authentication, you reduce the impact of clickjacking vectors, as an attacker cannot force a user to enter credentials again without their knowledge.

Frequently Asked Questions

Does middleBrick detect clickjacking in Hanami apps using Cockroachdb?
middleBrick scans the HTTP response headers and UI composition of unauthenticated endpoints. It will flag missing X-Frame-Options or weak Content-Security-Policy frame-ancestors that could enable clickjacking in a Hanami app backed by Cockroachdb, providing remediation guidance to add DENY/SAMEORIGIN policies.
Can Cockroachdb permissions alone prevent clickjacking?
No. Cockroachdb enforces database-level permissions and consistency, but clickjacking is an application-layer issue. You must configure Hanami to send anti-framing headers and validate origins; the database cannot prevent UI-based social engineering attacks.