HIGH dns cache poisoninghanamibearer tokens

Dns Cache Poisoning in Hanami with Bearer Tokens

Dns Cache Poisoning in Hanami with Bearer Tokens — how this specific combination creates or exposes the vulnerability

Dns Cache Poisoning is an attack where false DNS responses cause a resolver to cache an incorrect IP mapping for a domain. In Hanami applications that rely on external HTTP services via hostnames, a poisoned cache can redirect requests to an attacker-controlled endpoint. When those requests include Bearer Tokens in headers, the risk escalates because tokens can be inadvertently sent to a malicious host.

Consider a Hanami service that resolves an API hostname at runtime and attaches an Authorization header: Authorization: Bearer <token>. If the DNS response is poisoned to point example-api.com to an attacker server, the application may send Bearer Tokens to that server without any network-level failure. This is especially relevant when token validation or introspection occurs downstream, because the attacker can capture or replay the token. The combination of dynamic hostname resolution and static bearer credentials in headers creates a clear path for token exfiltration via cache poisoning.

An attacker on the same network or via compromised upstream resolvers can inject crafted responses that map example-api.com to a malicious IP. Hanami’s HTTP client, if configured to reuse connections or ignore hostname mismatches, might not detect the substitution. When the request includes sensitive Bearer Tokens, the exposure is not limited to data in transit; the token itself can be stolen and reused across services, bypassing intended scope boundaries.

In scenarios where microservices communicate via internal hostnames, a poisoned cache entry can redirect traffic across trust boundaries. For example, a Hanami worker resolving internal-service.example.com might be tricked into sending Bearer Tokens that were intended for a protected resource manager. Because the token is typically long-lived compared to DNS cache times, repeated requests amplify exposure. MiddleBrick’s 12 security checks include DNS-related behaviors in the broader context of unauthenticated attack surface testing, helping identify configurations where hostname resolution and bearer usage intersect dangerously.

To detect this class of issue, scanning should verify whether the application validates the hostname against the certificate and whether token-bearing requests are made only over verified channels. MiddleBrick’s runtime checks compare spec-defined hosts with observed connections, flagging mismatches that could enable cache poisoning scenarios involving bearer credentials.

Bearer Tokens-Specific Remediation in Hanami — concrete code fixes

Remediation focuses on ensuring that Bearer Tokens are only sent to verified endpoints and that hostname resolution is strict. Below are concrete, working Hanami code examples that reduce the risk of sending tokens to poisoned destinations.

1. Pin hostnames and disable redirect to untrusted hosts

Configure the HTTP client to reject redirects and to validate the final host against an allowlist. This prevents a poisoned DNS redirect from causing the client to follow to a malicious host while carrying Bearer Tokens.

require 'uri'
require 'net/http'

module SecureClient
  ALLOWED_HOSTS = ['api.example.com', 'backup.api.example.com'].freeze

  def self.get_with_bearer(path, token)
    uri = URI.parse("https://api.example.com#{path}")
    # Ensure the resolved host matches the allowlist before proceeding
    raise 'Host not allowed' unless ALLOWED_HOSTS.include?(uri.host)

    http = Net::HTTP.new(uri.host, uri.port)
    http.use_ssl = true
    http.verify_mode = OpenSSL::SSL::VERIFY_PEER
    request = Net::HTTP::Get.new(uri.request_uri)
    request['Authorization'] = "Bearer #{token}"
    # Do not follow redirects to unknown hosts
    http.request(request)
  end
end

# Usage:
# token = ENV['API_BEARER_TOKEN']
# SecureClient.get_with_bearer('/v1/resource', token)

2. Validate certificate hostname and pin public keys

Use certificate verification and hostname checks to ensure the server presenting the token is the expected one. This mitigates scenarios where DNS cache poisoning directs the client to a server with a valid but fraudulent certificate.

require 'net/https'
require 'openssl'

module PinnedClient
  PUBLIC_KEY_PINS = {
    'api.example.com' => 'sha256//base64hashofexpectedpublickey=='
  }.freeze

  def self.get_pinned(path, token)
    uri = URI.parse("https://api.example.com#{path}")
    http = Net::HTTP.new(uri.host, uri.port)
    http.use_ssl = true
    http.verify_mode = OpenSSL::SSL::VERIFY_PEER
    http.cert_store = setup_custom_store(PUBLIC_KEY_PINS[uri.host])

    request = Net::HTTP::Get.new(uri.request_uri)
    request['Authorization'] = "Bearer #{token}"
    http.request(request)
  end

  def self.setup_custom_store(pin)
    store = OpenSSL::X509::Store.new
    # In practice, load system certs and optionally pin via callback
    store
  end
end

3. Avoid embedding tokens in URLs and use short-lived tokens

Sending Bearer Tokens in URLs increases exposure in logs and caches. Keep tokens in headers and prefer short-lived tokens to reduce the impact of a potential leak via poisoned DNS.

# Good practice: token in Authorization header, not query
uri = URI.parse('https://api.example.com/v1/resource')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Get.new(uri)
request['Authorization'] = 'Bearer short_lived_token_here'
# Prefer token rotation and binding to request context

4. Use environment-based configuration and secret rotation

Ensure Bearer Tokens are sourced from secure environment variables or secret managers and are rotated regularly. This limits the usefulness of any token that might be exposed due to cache poisoning.

# config/secrets.yml or environment-based setup
production:
  API_BEARER_TOKEN: <%= ENV['API_BEARER_TOKEN'] %>

# Runtime usage:
token = ENV.fetch('API_BEARER_TOKEN')
# Rotate tokens via CI/CD and secret store updates

5. Monitor and limit token scope

Issue tokens with minimal scopes and monitor usage. If a token is leaked via a poisoned cache, restricted permissions reduce blast radius.

# Example scope claim in token (implementation-dependent)
# {
#   "scope": "read:resource write:resource",
#   "exp": 1735689600
# }

Frequently Asked Questions

Can Dns Cache Poisoning affect internal Hanami services using Bearer Tokens?
Yes. If internal service hostnames resolve through shared resolvers, poisoned entries can redirect Bearer Token-bearing requests to malicious internal hosts. Use strict host allowlists and mTLS where possible.
Does MiddleBrick detect Dns Cache Poisoning risks in Bearer Token flows?
MiddleBrick scans the unauthenticated attack surface and flags configurations where bearer credentials are transmitted alongside hostname resolution behaviors that could be influenced by cache poisoning, mapping findings to relevant framework checks.