HIGH auth bypasshanami

Auth Bypass in Hanami

How Auth Bypass Manifests in Hanami

Auth bypass in Hanami applications often stems from misconfigured action filters, missing authorization checks, or improper session handling. The framework's modular architecture, while flexible, can create subtle security gaps when authentication logic isn't consistently applied across all endpoints.

One common pattern involves actions that inherit from a base class but accidentally override or remove authentication filters. Consider this vulnerable structure:

class ApplicationController < Hanami::Action
  before :authenticate_user

  private

  def authenticate_user
    redirect_to '/login' unless session[:user_id]
  end
end

class Dashboard::Show < ApplicationController
  # Inherits authentication
end

class Public::Show < ApplicationController
  skip_before :authenticate_user
  # Now completely open
end

The skip_before call in Public::Show removes authentication entirely, potentially exposing sensitive data if the action name is misleading or reused incorrectly.

Another Hanami-specific vulnerability occurs with route constraints that don't align with authentication requirements. The framework allows defining constraints that might bypass middleware:

Hanami::Router.new do
  get '/admin', to: Admin::Show
    .constraints(format: 'json')
    .middleware(AuthenticationMiddleware)
    
  get '/admin', to: Admin::Show
    .constraints(format: 'html')
    # No middleware here!
end

This creates a situation where HTML requests to /admin bypass authentication entirely while JSON requests remain protected.

Session fixation attacks are particularly relevant in Hanami due to its Rack-based session handling. If session IDs aren't properly regenerated on login:

class Sessions::Create < Hanami::Action
  def call(params)
    user = UserRepository.new.find_by_email(params[:email])
    if user && user.authenticate(params[:password])
      session[:user_id] = user.id
      # Missing: regenerate_session_id!
      redirect_to '/dashboard'
    else
      self.status = 401
    end
  end
end

An attacker who knows or predicts session IDs can hijack authenticated sessions.

Hanami-Specific Detection

Detecting auth bypass in Hanami requires examining both the routing configuration and action filters systematically. Start by analyzing your config/routes.rb file for inconsistent middleware application:

routes = Hanami::Router.new do
  # Check for routes without authentication middleware
  get '/admin', to: Admin::Show
    .constraints(accept: 'application/json')
    # Verify this has proper auth
    
  get '/settings', to: Settings::Show
    # Is this protected?
end

Use Hanami's built-in route inspection capabilities to audit all endpoints:

puts Hanami.app.router.routes.map do |route|
  "#{route.request_method} #{route.path} -> #{route.action.class.name} (#{route.middleware.inspect})"
end

Look specifically for routes that lack authentication middleware or have inconsistent middleware stacks.

Code review should focus on action inheritance patterns. Use this script to identify potentially vulnerable actions:

def find_unprotected_actions(app)
  unprotected = []
  
  app.actions.each do |action_class|
    next if action_class == Hanami::Action
    
    # Check if it inherits from ApplicationController
    if action_class.ancestors.include?(ApplicationController)
      # Look for skip_before calls or missing authentication
      if action_class.instance_methods(false).include?(:before) == false
        unprotected << action_class
      end
    end
  end
  
  unprotected
end

Automated scanning with middleBrick can identify auth bypass vulnerabilities by testing unauthenticated access to protected endpoints. The scanner attempts requests without session cookies or authentication headers and flags any successful access to endpoints that should require authentication:

$ middlebrick scan https://your-hanami-app.com

✓ Authentication bypass detected
  Severity: High
  Endpoint: POST /api/v1/users
  Issue: Endpoint accepts unauthenticated requests
  Recommendation: Add authentication middleware to this route

middleBrick's black-box scanning approach is particularly effective for Hanami applications since it tests the actual runtime behavior without requiring source code access.

Hanami-Specific Remediation

Hanami provides several native mechanisms for robust authentication that prevent bypass vulnerabilities. The most reliable approach uses action filters consistently across your application:

class ApplicationController < Hanami::Action
  before :authenticate!

  private

  def authenticate!
    halt 401 unless authenticated?
  end

  def authenticated?
    session[:user_id] && UserRepository.new.find(session[:user_id])
  end
end

class Admin::Dashboard < ApplicationController
  # Automatically protected
end

For routes that legitimately need to be public, create a separate base class to avoid inheritance mistakes:

class PublicApplicationController < Hanami::Action
  # No authentication filters
end

class Public::Show < PublicApplicationController
  # Explicitly public, cannot accidentally bypass auth
end

Implement proper session management with ID regeneration:

class Sessions::Create < Hanami::Action
  include Hanami::Action::Session

  def call(params)
    user = UserRepository.new.find_by_email(params[:email])
    if user && user.authenticate(params[:password])
      session.regenerate_id
      session[:user_id] = user.id
      redirect_to '/dashboard'
    else
      self.status = 401
    end
  end
end

Hanami's middleware system allows consistent authentication across all routes. Configure it in config/application.rb:

middleware.use AuthenticationMiddleware

class AuthenticationMiddleware
  def initialize(app)
    @app = app
  end

  def call(env)
    request = Rack::Request.new(env)
    
    if protected_route?(request.path) && !authenticated?(request)
      return [401, {}, ['Unauthorized']]
    end
    
    @app.call(env)
  end

  private

  def protected_route?(path)
    path.start_with?('/admin') || path.start_with?('/api')
  end

  def authenticated?(request)
    request.session[:user_id]
  end
end

For comprehensive protection, combine action-level filters with route-level middleware. This defense-in-depth approach ensures that even if one mechanism fails, the other provides protection.

middleBrick's continuous monitoring (Pro plan) can automatically scan your Hanami application on a schedule, alerting you if new auth bypass vulnerabilities are introduced:

$ middlebrick monitor --schedule=daily --threshold=80

Monitoring Hanami API...
✓ No auth bypass vulnerabilities detected
✓ Authentication coverage: 95% of endpoints
✓ Last scan: 2 hours ago

This proactive approach catches authentication regressions before they reach production.

Related CWEs: authentication

CWE IDNameSeverity
CWE-287Improper Authentication CRITICAL
CWE-306Missing Authentication for Critical Function CRITICAL
CWE-307Brute Force HIGH
CWE-308Single-Factor Authentication MEDIUM
CWE-309Use of Password System for Primary Authentication MEDIUM
CWE-347Improper Verification of Cryptographic Signature HIGH
CWE-384Session Fixation HIGH
CWE-521Weak Password Requirements MEDIUM
CWE-613Insufficient Session Expiration MEDIUM
CWE-640Weak Password Recovery HIGH

Frequently Asked Questions

How can I verify that all my Hanami API endpoints are properly authenticated?
Use middleBrick's free scanning to test unauthenticated access to your endpoints. The scanner attempts requests without authentication credentials and flags any successful access to endpoints that should be protected. For comprehensive coverage, combine this with a code review of your routing configuration and action filters.
What's the difference between action filters and middleware for authentication in Hanami?
Action filters (like before :authenticate!) provide fine-grained control at the controller level and are specific to Hanami's action architecture. Middleware operates at the Rack level, affecting all requests before they reach your actions. For maximum security, use both: middleware for baseline protection and action filters for additional validation specific to your business logic.