Auth Bypass in Hanami with Mutual Tls
Auth Bypass in Hanami with Mutual Tls — how this specific combination creates or exposes the vulnerability
Hanami is a Ruby web framework that encourages explicit routing and layered architecture. When Mutual TLS (mTLS) is used, the server is configured to request and validate a client certificate during the TLS handshake. The intended model is that the certificate itself acts as an authentication credential, allowing the application to skip additional token-based or session-based checks.
Auth bypass can occur in this setup when the Hanami application incorrectly treats the presence of a valid client certificate as sufficient authorization for a given endpoint, without enforcing least-privilege access controls. For example, an endpoint that should be limited to a subset of mTLS-authenticated clients might rely solely on the certificate’s distinguished name (DN) or a mapped user attribute without checking scopes, roles, or tenant boundaries. This mismatch between identity and authorization enables horizontal or vertical privilege escalation.
Another scenario specific to mTLS is when the Hanami app falls back to alternative authentication mechanisms (e.g., API keys or session cookies) if certificate validation fails or is absent. If these fallback paths are not properly guarded, an attacker who can terminate or manipulate the TLS layer (e.g., via a misconfigured proxy) might omit the client certificate intentionally, causing the app to rely on weaker credentials and effectively bypass the intended mTLS requirement. MiddleBrick’s checks for Authentication and BOLA/IDOR can surface such risky configurations by observing unauthenticated or improperly constrained endpoints that should require mTLS-bound identities.
Furthermore, implementation issues in how the certificate is mapped to application-level permissions can introduce Auth Bypass. If the Hanami app uses a simplistic string match on the certificate’s common name (CN) to derive user roles, an attacker who can control or forge a CN in a malicious certificate (e.g., via a subordinate CA) might gain access to admin routes. Additionally, if the application does not validate certificate revocation through OCSP or CRL, a stolen or compromised client certificate could continue to provide access despite revocation. These risks highlight why mTLS must be paired with explicit authorization checks and robust PKI management rather than treated as a standalone gate.
Mutual Tls-Specific Remediation in Hanami — concrete code fixes
To securely implement Mutual TLS in Hanami, treat the client certificate as an identity source and enforce authorization based on application-level policies, not just certificate presence. Below is a concrete example of how to configure an HTTPS server with mTLS in a Hanami-like Ruby setup using Puma and OpenSSL verification.
# config/puma.rb
ssl_bind '0.0.0.0', '8443', {
key: 'path/to/server.key',
cert: 'path/to/server.crt',
ca_file: 'path/to/ca_bundle.crt',
verify_mode: OpenSSL::SSL::VERIFY_PEER
}
In your Hanami application, you can access the client certificate from the Rack environment and map it to an identity while enforcing authorization rules.
# lib/middleware/client_certificate_auth.rb
class ClientCertificateAuth
def initialize(app)
@app = app
end
def call(env)
cert = env['ssl.client_cert']
if cert
subject = cert.subject.to_s
# Extract CN or SAN carefully; do not rely solely on CN
username = extract_username_from_subject(subject)
identity = find_or_create_identity(cert)
# Enforce role/tenant checks here
env['hanami.identity'] = identity
else
# Reject request if mTLS is mandatory
return [403, { 'Content-Type' => 'application/json' }, [{ error: 'mTLS required' }.to_json]]
end
@app.call(env)
end
private
def extract_username_from_subject(subject)
# Example: /CN=alice/...; use a robust parser in production
subject.match(%r{CN=([^,/]+)})&.[1]
end
def find_or_create_identity(cert)
# Map certificate fingerprint to user/role/tenant
fingerprint = cert.hash
Identity.find_or_create_by(cert_fingerprint: fingerprint) do |record|
record.cert_subject = cert.subject.to_s
record.cert_issuer = cert.issuer.to_s
end
end
end
Use this middleware early in the stack and ensure that every controller action requiring specific roles performs an explicit check rather than assuming the certificate maps directly to the required permission. For example:
# app/controllers/api/v1/admin_controller.rb
class Api::V1::AdminController < Hanami::Controller
before_action :require_mtls_identity
before_action :require_admin_role
private
def require_mtls_identity
identity = request.env['hanami.identity']
halt 403, 'Identity not found' unless identity
end
def require_admin_role
identity = request.env['hanami.identity']
halt 403, 'Insufficient permissions' unless identity.admin?
end
end
Additionally, enforce revocation and lifetime checks on the server side by configuring the CA bundle with proper CRL distribution points or enabling OCSP stapling. In Hanami, you can integrate these validations into the certificate mapping step to reject expired or revoked certificates. Avoid using the certificate subject alone for authorization; instead, map the certificate to an internal identity record that enforces application-specific policies, ensuring that even valid mTLS connections are subject to the same RBAC and tenant isolation rules applied to other authentication methods. This layered approach prevents Auth Bypass scenarios where mTLS is assumed to be sufficient without explicit authorization.
Related CWEs: authentication
| CWE ID | Name | Severity |
|---|---|---|
| CWE-287 | Improper Authentication | CRITICAL |
| CWE-306 | Missing Authentication for Critical Function | CRITICAL |
| CWE-307 | Brute Force | HIGH |
| CWE-308 | Single-Factor Authentication | MEDIUM |
| CWE-309 | Use of Password System for Primary Authentication | MEDIUM |
| CWE-347 | Improper Verification of Cryptographic Signature | HIGH |
| CWE-384 | Session Fixation | HIGH |
| CWE-521 | Weak Password Requirements | MEDIUM |
| CWE-613 | Insufficient Session Expiration | MEDIUM |
| CWE-640 | Weak Password Recovery | HIGH |