HIGH shellshockhanamimutual tls

Shellshock in Hanami with Mutual Tls

Shellshock in Hanami with Mutual Tls — how this specific combination creates or exposes the vulnerability

Shellshock (CVE-2014-6271 and related variants) is a command injection vulnerability in Bash that arises from improper environment variable handling. In a Hanami application, which is a Ruby web framework, Shellshock can be triggered when the app invokes system commands or spawns subprocesses with user-controlled data that propagates into the environment. This commonly occurs through CGI-style invocations, background job processors, or any code that uses system, exec, or backticks with unsanitized input.

When Mutual TLS (mTLS) is enforced, the server requests and validates client certificates. Hanami can integrate mTLS at the reverse proxy or load balancer (e.g., NGINX, HAProxy) or within the app via a middleware that inspects client certificates. If the certificate validation logic or associated metadata (such as the Common Name or Subject Alternative Names from the client certificate) is used to construct command-line arguments—intentionally or inadvertently—attackers may inject shell metacharacters into certificate fields that are later passed to Bash. For example, a malicious client certificate containing crafted values in its Distinguished Name could be concatenated into a logging or revocation-check command, turning a trusted mTLS channel into a vector for remote code execution.

In a typical Hanami deployment with mTLS, the application may rely on the web server to terminate TLS and forward client certificate details via headers (e.g., X-SSL-Client-Cert). If Hanami code parses these headers and uses them in system calls—such as invoking openssl to validate a certificate fingerprint—unsanitized input from the attacker’s certificate can lead to command injection. The combination of a framework that performs system calls and an mTLS setup that exposes attacker-influenced data increases the risk of Shellshock exploitation when input validation is insufficient.

An example of a vulnerable Hanami service might involve a background task that checks certificate revocation via a shell command:

cert_fingerprint = ENV['SSL_CLIENT_CERT_FP']
system("openssl verify -CAfile /path/to/ca.pem #{cert_fingerprint}")

If cert_fingerprint contains shell metacharacters (e.g., ; rm -rf /), the command injection occurs. MiddleBrick scans detect such patterns by correlating OpenAPI specifications with runtime behavior, identifying endpoints that accept certificate-derived input and checking for insecure command construction.

Mutual Tls-Specific Remediation in Hanami — concrete code fixes

To remediate Shellshock risks in Hanami when using mTLS, avoid passing any client-influenced data directly into shell commands. Instead, use language-native libraries for cryptographic operations and strictly validate and sanitize any data derived from mTLS certificates.

Below are concrete, secure code examples for handling mTLS in Hanami without invoking the shell.

1. Use Ruby’s OpenSSL library instead of shelling out

Replace system calls for certificate verification with Ruby’s built-in OpenSSL API. This removes the shell as an intermediary and prevents injection.

require 'openssl'
require 'base64'

cert_der = Base64.strict_decode64(ENV['SSL_CLIENT_CERT_B64'])
cert = OpenSSL::X509::Certificate.new(cert_der)

# Verify against a trusted CA store
store = OpenSSL::X509::Store.new
store.add_file('/path/to/ca.pem')
store.verify(cert)

2. Validate certificate fields safely

If you need to inspect certificate fields (e.g., Common Name), treat them as untrusted input. Do not concatenate them into commands or eval-like constructs. Use strict allowlists for expected values.

allowed_organizations = ['MyTrustedOrg']

cert = OpenSSL::X509::Certificate.new(cert_der)
subject = cert.subject
org = subject.collect(&:value).find { |val| subject.to_a.flatten.include?('O') }

if allowed_organizations.include?(org)
  # Proceed with trusted logic
else
  raise 'Unauthorized certificate organization'
end

3. Configure Hanami middleware to reject invalid mTLS without shell interaction

Implement a Rack middleware that validates client certificates using Ruby and integrates cleanly with Hanami’s pipeline. This avoids any need for shell-based checks.

# lib/middleware/client_cert_auth.rb
class ClientCertAuth
  def initialize(app)
    @app = app
  end

  def call(env)
    cert_der = env['SSL_CLIENT_CERT']&.to_der
    if cert_der
      cert = OpenSSL::X509::Certificate.new(cert_der)
      # Perform validation using Ruby, not shell
      if valid_certificate?(cert)
        @app.call(env)
      else
        [403, { 'Content-Type' => 'text/plain' }, ['Forbidden']]
      end
    else
      [400, { 'Content-Type' => 'text/plain' }, ['Bad Request']]
    end
  end

  private

  def valid_certificate?(cert)
    # Implement your validation logic here, e.g., check issuer, expiry, CN allowlist
    true
  end
end

# config/initializers/middleware.rb
Hanami.configure do
  middleware.insert_after Rack::Runtime, ClientCertAuth
end

By using these approaches, you maintain the security benefits of mTLS while eliminating Shellshock risks. MiddleBrick’s scans can help verify that no dangerous shell invocations remain in your API surface and that certificate handling adheres to secure coding practices.

Frequently Asked Questions

How does Hanami handle client certificate data in a secure way?
Hanami should process client certificate data using Ruby’s OpenSSL library and avoid any shell command construction. Validate certificate fields with allowlists and use language-native cryptographic verification instead of invoking system commands.
Can MiddleBrick detect Shellshock risks in mTLS-enabled APIs?
Yes, MiddleBrick scans correlate OpenAPI specifications with runtime inputs to identify places where certificate-derived data might reach shell commands, flagging potential command injection paths even in mTLS configurations.