HIGH brute force attackhanami

Brute Force Attack in Hanami

How Brute Force Attack Manifests in Hanami

In a Hanami application, brute force attacks typically target authentication endpoints, such as login or password reset routes, where an attacker iterates through credential combinations to gain unauthorized access. Hanami's modular architecture, with separate actions and entities, can inadvertently expose these endpoints if rate limiting is not explicitly enforced at the action level.

A common vulnerable pattern is a SessionsController with a create action that processes POST requests to /sessions without throttling. For example, a naive implementation might directly authenticate via a Hanami model (using ROM or Sequel) and establish a session on success:

# apps/web/controllers/sessions_controller.rb
module Web
  module Controllers
    module Sessions
      class Create
        include Web::Action

        def call(params)
          user = UserRepository.new.find_by_email(params[:email])
          if user && user.authenticate(params[:password])
            session[:user_id] = user.id
            redirect to: '/dashboard'
          else
            flash[:error] = 'Invalid credentials'
            redirect to: '/login'
          end
        end
      end
    end
  end
end

This action lacks any mechanism to limit request frequency. An attacker can script thousands of attempts per minute against /sessions using tools like hydra or burp suite. Because Hanami does not impose global rate limits by default, each request is processed independently, allowing unlimited guesses. The vulnerability is exacerbated if the application reveals whether an email exists (via distinct error messages), enabling user enumeration before the brute force phase.

Additionally, Hanami's use of hanami-action means that without middleware or action-specific throttles, the Rack stack receives unfiltered traffic. Attackers may also target API endpoints that use token-based authentication (e.g., JWT) if no rate limiting exists on the token issuance endpoint (/auth/token), leading to token spraying attacks.

Hanami-Specific Detection

Detecting brute force vulnerabilities in Hanami requires examining both code and runtime behavior. Manually, review all authentication-related actions (e.g., SessionsController#create, PasswordResetsController#update) for the absence of throttling mechanisms. Look for missing throttle declarations or custom Rack middleware that limits requests per IP or per account.

Automated scanning with middleBrick identifies this issue through its Rate Limiting check (one of 12 parallel tests). When you submit a Hanami app's login endpoint URL (e.g., https://your-app.com/sessions), middleBrick sends a rapid series of POST requests with invalid credentials and analyzes the HTTP responses. A lack of 429 Too Many Requests status codes or inconsistent throttling headers (Retry-After) indicates a vulnerability. The scan takes 5–15 seconds and produces a per-category breakdown, highlighting the Rate Limiting risk with severity and remediation guidance specific to Hanami.

You can also integrate this detection into your CI/CD pipeline using middleBrick's GitHub Action. By adding the action to your workflow, you can automatically scan staging Hanami APIs before deployment and fail the build if the rate limiting score drops below your threshold. For terminal-based checks, the middleBrick CLI (npm install -g middlebrick) allows you to run middlebrick scan https://your-hanami-app.com/sessions and get instant JSON output.

Hanami-Specific Remediation

Remediate brute force vulnerabilities in Hanami by implementing request throttling directly in your actions using the hanami-action gem's built-in throttle method. This method limits requests based on IP, session, or custom keys. Apply it to all authentication endpoints.

Here is a corrected SessionsController#create with IP-based throttling (5 attempts per 60 seconds):

# apps/web/controllers/sessions_controller.rb
module Web
  module Controllers
    module Sessions
      class Create
        include Web::Action
        throttle limit: 5, period: 60, by: :ip

        def call(params)
          user = UserRepository.new.find_by_email(params[:email])
          if user && user.authenticate(params[:password])
            session[:user_id] = user.id
            redirect to: '/dashboard'
          else
            flash[:error] = 'Invalid credentials'
            redirect to: '/login'
          end
        end
      end
    end
  end
end

For account-specific locking (preventing attacks on a single user account), combine throttling with a failure counter in your user entity/repository. After n failed attempts, disable the account temporarily:

# apps/web/entities/user.rb
module Web
  module Entities
    class User < Hanami::Entity
      attributes :email, :password_digest, :locked_at, :failed_attempts

      def lock!
        update(locked_at: Time.now, failed_attempts: 0)
      end

      def increment_failed_attempts!
        update(failed_attempts: (failed_attempts || 0) + 1)
        lock! if failed_attempts >= 5
      end
    end
  end
end

Then, in your controller, call user.increment_failed_attempts! on authentication failure. Also, ensure your login form does not reveal whether an email exists—use a generic error message like "Invalid credentials" for both missing users and wrong passwords.

After implementing these fixes, rescan your endpoints with middleBrick to verify the Rate Limiting score improves. For ongoing enforcement, use middleBrick's Pro plan to enable continuous monitoring, which periodically rescans your Hanami APIs and alerts your team via Slack or email if throttling regresses.

Frequently Asked Questions

Why is brute force particularly dangerous in a Hanami app without rate limiting?
Hanami's default configuration does not include global rate limiting. Without throttling on authentication actions, attackers can make unlimited login attempts, potentially guessing weak passwords or enumerating valid user accounts. This violates OWASP API Top 10: API2:2023 — Broken Authentication and can lead to full account compromise.
How does middleBrick's brute force scan differ from manual testing?
middleBrick automatically sends a rapid series of invalid login attempts to your Hanami endpoint and analyzes responses for missing 429 status codes or throttling headers. It does this in 5–15 seconds without credentials, providing a scored report with Hanami-specific remediation steps. Manual testing is slower and may miss subtle rate limit bypasses.