HIGH credential stuffinghanamiruby

Credential Stuffing in Hanami (Ruby)

Credential Stuffing in Hanami with Ruby

Hanami, a lightweight web framework for Ruby, can be vulnerable to credential stuffing when its authentication mechanisms are implemented without proper rate limiting or credential throttling. Since Hanami does not include built-in authentication by default, developers often implement custom solutions using Rack middleware or third-party gems. When these implementations lack sufficient protection, attackers can automate login attempts across multiple endpoints using credential lists obtained from prior data breaches, exploiting the framework’s simplicity to test large volumes of username/password combinations.

For example, a typical Hanami controller action for login might directly compare submitted credentials against a database without any throttling:

# apps/web/controllers/auth/login.rb
class Auth::LoginController < Hanami::Controller
  include Hanami::Validations

  def create
    user = UserRepository.find_by(email: params[:email])
    if user && BCrypt::Password.new(user.encrypted_password) == params[:password]
      session[:user_id] = user.id
      redirect_to '/dashboard'
    else
      flash[:error] = 'Invalid credentials'
      redirect_back
    end
  end
end

This code has no rate limiting, no lockout after failed attempts, and no CAPTCHA or behavioral analysis. As a result, an attacker can script thousands of requests against the /auth/login endpoint using credentials from sources like the Have I Been Pwned database. Because Hanami applications are often deployed behind reverse proxies or on modest infrastructure, there may be no additional WAF or DDoS protection to absorb such traffic.

Credential stuffing attacks against Hanami apps are particularly effective when:

  • Multiple independent endpoints accept login parameters (e.g., /auth/login, /sign_in, /authenticate)
  • Password reset or registration endpoints lack progressive throttling
  • User enumeration is possible through differential error messages (e.g., “Invalid email” vs “Invalid password”)

These conditions align with the OWASP API Top 10 category A04:2023 - Insecure Design, specifically around insufficient security controls during authentication. Without proactive defenses, Hanami applications are exposed to automated credential stuffing at scale.

Ruby-Specific Remediation in Hanami

To mitigate credential stuffing in Hanami applications using Ruby, developers must implement rate limiting, account lockout, and response uniformity at the application level. Since Hanami does not provide built-in security controls, these protections must be added via Rack middleware or dedicated gems like rack-attack. Below is a correct Ruby implementation using rack-attack to secure the login endpoint.

# config/initializers/rack_attack.rb
Rack::Attack.defer = false
Rack::Attack.throttle "login throttling",
  limit: 5,
  period: 1.minute,
  receptors: [Rack::Attack::Throttle::IPReceptor.new]

Rack::Attack.on_throttled_response = (
  env -> response
) do |response|
  if response.throttled?
    response.status = 429
    response.headers["Retry-After"] = "60 seconds"
    response.body = { error: "Too many login attempts. Please try again later." }.to_json
  end
end

# apps/web/controllers/auth/login.rb
class Auth::LoginController < Hanami::Controller
  include Hanami::Validations

  def create
    user = UserRepository.find_by(email: params[:email])
    unless user
      fail_with 401, "Invalid credentials"
    end

    unless BCrypt::Password.new(user.encrypted_password) == params[:password]
      fail_with 401, "Invalid credentials"
    end

    session[:user_id] = user.id
    redirect_to '/dashboard'
  end

  private

  def fail_with(status)
    response.status = status
    response.format :json
    response.body = { error: "Invalid credentials" }.to_json
  end
end

This code introduces two critical protections:

  • Throttling by IP: Only 5 login attempts per minute per IP address are allowed, blocking automated credential stuffing scripts.
  • Uniform error responses: Both invalid email and invalid password return the same generic message, preventing user enumeration.

Additionally, pairing this with HTTPS enforcement and multi-factor authentication (MFA) significantly reduces risk. Developers should also integrate monitoring to detect spikes in login failures, which may indicate ongoing attack attempts.

Frequently Asked Questions

Can Hanami automatically prevent credential stuffing without custom code?
No. Hanami does not include built-in protection against credential stuffing. Developers must implement rate limiting, throttling, and uniform error responses using middleware like rack-attack or external services. Without such measures, the application remains vulnerable to automated login brute-force attacks.
Is credential stuffing only a concern for large Hanami deployments?
No. Credential stuffing targets any publicly accessible login endpoint, regardless of deployment size. Small and medium Hanami applications are often more vulnerable due to limited infrastructure for DDoS mitigation or monitoring, making them attractive targets for low-cost automation tools.