HIGH dns rebindinggrapebasic auth

Dns Rebinding in Grape with Basic Auth

Dns Rebinding in Grape with Basic Auth — how this specific combination creates or exposes the vulnerability

DNS Rebinding is an application-layer attack that manipulates DNS responses to make a victim’s browser believe a remote host is both attacker-controlled and an internal host. When combined with HTTP Basic Auth in a Grape-based API, the interaction can bypass same-origin protections and credential expectations in specific deployment configurations.

Consider a Grape API that protects a sensitive endpoint with HTTP Basic Auth:

class ProtectedAPI < Grape::API
  format :json

  before do
    authenticated? || error!('Unauthorized', 401)
  end

  helpers do
    def authenticated?
      request.authorization && request.authorization[:basic] &&
        request.authorization[:basic][:password] == ENV['API_KEY']
    end
  end

  get :admin do
    { secret: 'internal-data' }
  end
end

In a typical setup, the API is served from api.example.com and requires Basic Auth with a static API key. An attacker registers a domain (e.g., evil.com) and configures it to initially resolve to the attacker’s server, then rebind to a private IP such as 127.0.0.1 or an internal service like 192.168.1.10. When a logged-in user visits a page containing a malicious script, the browser makes a request to api.example.com/admin with the stored Basic Auth credentials (username/password or the base64-encoded token). Due to the rebinding, the request reaches an internal host that may not enforce the same authentication or may expose a management interface without external protections.

Grape by itself does not prevent DNS Rebinding; the framework processes the request as a normal HTTP call once it arrives. The vulnerability surface arises from two factors:

  • The API trusts the request host header or IP-based assumptions rather than validating the origin strictly.
  • Basic Auth credentials are sent automatically by the browser to the resolved host, even if it pivots to an internal address, enabling the attacker to relay or replay authenticated requests to internal services that lack proper access controls.

This combination means that an attacker can effectively probe internal infrastructure using authenticated requests issued by the victim, potentially bypassing network segregation because the API endpoint does not validate the canonical hostname or enforce strict source checks. The API’s authentication mechanism (Basic Auth) remains valid, but the context of the request target is manipulated.

Basic Auth-Specific Remediation in Grape — concrete code fixes

Remediation focuses on ensuring that the request target is authoritative and that credentials are not inadvertently relayed to non-expected origins. Below are concrete changes you can apply to a Grape API to reduce DNS Rebinding risk when using Basic Auth.

1. Validate the Host Header

Reject requests where the Host header does not match your expected domain. This prevents the browser from sending requests to internal IPs even if DNS is manipulated.

class ProtectedAPI < Grape::API
  format :json

  before do
    allowed_hosts = ['api.example.com', 'www.api.example.com']
    unless allowed_hosts.include?(request.host)
      error!('Forbidden', 403)
    end

    authenticated? || error!('Unauthorized', 401)
  end

  helpers do
    def authenticated?
      request.authorization && request.authorization[:basic] &&
        request.authorization[:basic][:password] == ENV['API_KEY']
    end
  end

  get :admin do
    { secret: 'internal-data' }
  end
end

2. Avoid Using Request Host for Authorization Decisions

Do not rely on request.host, request.domain, or request.port to determine access. Instead, enforce authorization via tokens or scopes and keep Basic Auth for primary credential verification only.

3. Use Secure Flag and HttpOnly for Session Cookies (if any)

If your API sets cookies (e.g., for session management alongside Basic Auth), ensure the Secure and HttpOnly flags are set to reduce exposure over insecure channels.

# config/initializers/session_store.rb (if using cookies)
Rails.application.config.session_store :cookie_store,
  key: '_your_app_session',
  secure: Rails.env.production?,
  httponly: true

4. Enforce Strict Transport Security and CORS

Serve your API exclusively over HTTPS and configure CORS to limit origins. This reduces the window for protocol-switching attacks that rely on rebinding HTTP to HTTPS contexts.

class ProtectedAPI < Grape::API
  format :json

  before do
    allowed_origin = 'https://app.example.com'
    unless request.env['HTTP_ORIGIN'] == allowed_origin
      error!('Forbidden', 403)
    end

    authenticated? || error!('Unauthorized', 401)
  end

  helpers do
    def authenticated?
      request.authorization && request.authorization[:basic] &&
        request.authorization[:basic][:password] == ENV['API_KEY']
    end
  end

  get :admin do
    { secret: 'internal-data' }
  end
end

By combining host validation with strict transport and origin policies, you ensure that even if DNS is manipulated, the request will either be rejected or not be processed against internal endpoints when authenticated via Basic Auth.

Frequently Asked Questions

Does middleBrick detect DNS Rebinding in Grape APIs with Basic Auth?
Yes. middleBrick runs network-based checks that can identify mismatches between expected and resolved hosts, including scenarios where authentication is present, and flags DNS Rebinding as a finding with severity and remediation guidance.
Can Basic Auth alone prevent DNS Rebinding?
No. Basic Auth provides credentials but does not prevent the browser from sending those credentials to a maliciously resolved host. You must explicitly validate the request target and enforce strict origin and host checks.