HIGH dns cache poisoningbasic auth

Dns Cache Poisoning with Basic Auth

How DNS Cache Poisoning Manifests in Basic Auth

DNS cache poisoning (also known as DNS spoofing) tricks a resolver into returning an attacker‑controlled IP address for a legitimate domain. When an application builds an outbound request that uses HTTP Basic Auth, the resolver’s poisoned answer can cause the Authorization header – containing base64‑encoded username:password – to be sent to the attacker’s server instead of the intended service.

Typical vulnerable code paths involve taking a user‑supplied hostname (e.g., from a query parameter, header, or configuration service) and using it to construct a request that includes a Basic Auth header. If the application does not validate or whitelist the resolved host, an attacker who has poisoned the DNS cache can redirect the request to a malicious endpoint and harvest credentials. This pattern has been observed in real‑world incidents such as CVE-2008-1447 (the Kaminsky attack), where poor source‑port randomization made cache poisoning practical, and in API‑gateway plugins that forward requests to user‑specified back‑ends using Basic Auth for upstream authentication.

// Vulnerable Node.js example: hostname taken directly from request query
const http = require('http');
function handle(req, res) {
  const targetHost = req.query.host; // user‑controlled
  const auth = Buffer.from(`${process.env.USERNAME}:${process.env.PASSWORD}`).toString('base64');
  const options = {
    hostname: targetHost,   // <-- DNS lookup performed here
    port: 443,
    path: '/api/data',
    method: 'GET',
    headers: {
      Authorization: `Basic ${auth}`
    }
  };
  const httpsReq = https.request(options, (apiRes) => {
    // pipe response back to client
    apiRes.pipe(res);
  });
  httpsReq.on('error', (err) => res.statusCode = 502, res.end());
  httpsReq.end();
}

In the snippet above, if an attacker has poisoned the DNS entry for targetHost, the outbound request will be sent to the attacker’s IP, leaking the Basic Auth credentials.

Basic Auth‑Specific Detection

middleBrick performs unauthenticated, black‑box scanning of the API surface. It detects DNS cache poisoning risk in Basic Auth flows by:

  • Sending requests that inject user‑controlled host values (via query string, headers, or body) and observing whether the resulting outbound traffic contains a Basic Auth header directed to an external host.
  • Checking for missing host validation: if the reflector echoes the supplied host without whitelist verification, the scan flags a potential DNS‑poisoning vector.
  • Correlating findings with the Basic Auth detection module to ensure the leaked header is indeed an Authorization: Basic … value.

The scan does not need any agents or credentials; you simply provide the public URL of the API. For example, using the middleBrick CLI:

# Scan an API endpoint for DNS cache poisoning and other risks
middlebrick scan https://api.example.com/v1/resources

The resulting report will list a finding under the "Input Validation" category (or similar) with severity "high", describing that user‑supplied host values are used to construct outbound Basic Auth requests without validation. The finding includes remediation guidance, such as implementing an allow‑list of trusted hosts or disabling outbound requests to user‑provided domains.

Basic Auth‑Specific Remediation

The most effective defense is to never let untrusted input dictate the destination of an outbound request that carries Basic Auth credentials. Apply the following mitigations:

  • Validate or whitelist hostnames before performing DNS lookups. Only allow domains that are explicitly approved for upstream communication.
  • Enforce HTTPS and verify the server’s TLS certificate; reject connections to hosts with mismatched or self‑signed certificates unless explicitly pinned.
  • Avoid following redirects to untrusted hosts; disable automatic redirect handling or validate each redirect destination against the same whitelist.
  • If possible, avoid using Basic Auth altogether for external calls; prefer token‑based authentication with short‑lived, scoped credentials that are useless if intercepted.
  • Deploy DNSSEC‑validating resolvers on the host running the application to reduce the chance of successful cache poisoning.

Below is a corrected version of the Node.js example that implements a simple host allow‑list:

// Fixed Node.js example with host whitelist
const https = require('http');
const ALLOWED_HOSTS = new Set(['api.internal.example.com', 'payments.provider.net']);

function handle(req, res) {
  const userHost = req.query.host;
  if (!ALLOWED_HOSTS.has(userHost)) {
    return res.statusCode = 400, res.end('Invalid host');
  }
  const auth = Buffer.from(`${process.env.USERNAME}:${process.env.PASSWORD}`).toString('base64');
  const options = {
    hostname: userHost,   // DNS lookup now only for trusted host
    port: 443,
    path: '/api/data',
    method: 'GET',
    headers: {
      Authorization: `Basic ${auth}`
    }
  };
  const httpsReq = https.request(options, (apiRes) => {
    apiRes.pipe(res);
  });
  httpsReq.on('error', (err) => {
    console.error(err);
    res.statusCode = 502;
    res.end();
  });
  httpsReq.end();
}

In Python with the requests library, the same principle applies:

import requests
ALLOWED = {'api.internal.example.com', 'payments.provider.net'}

def call_api(user_host):
    if user_host not in ALLOWED:
        raise ValueError('Host not allowed')
    auth = requests.auth.HTTPBasicAuth('user', 'pass')
    resp = requests.get(f'https://{user_host}/api/data', auth=auth, timeout=5, verify=True)
    resp.raise_for_status()
    return resp.json()

These changes ensure that even if an attacker succeeds in poisoning the DNS cache, the application will refuse to connect to the malicious host, keeping Basic Auth credentials confined to legitimate services.

Frequently Asked Questions

Can middleBrick prevent DNS cache poisoning attacks on its own?
No. middleBrick only detects the vulnerability by scanning for unsafe use of user‑supplied host values in outbound Basic Auth requests and provides remediation guidance. Preventing the attack requires implementing host validation, TLS verification, and DNSSEC on the target system.
Is Basic Auth ever safe to use for external APIs if DNS cache poisoning is a concern?
Basic Auth can be used safely over TLS when the destination host is strictly validated and the credentials are short‑lived or scoped. However, for external calls where the host may be derived from user input, consider using token‑based authentication or avoid exposing the Authorization header altogether.