HIGH dns cache poisoningfeathersjsjavascript

Dns Cache Poisoning in Feathersjs (Javascript)

Dns Cache Poisoning in Feathersjs with Javascript — how this specific combination creates or exposes the vulnerability

DNS cache poisoning (also known as DNS spoofing) occurs when an attacker causes a DNS resolver to return a malicious IP address for a domain. In a FeathersJS application written in JavaScript, this typically manifests as your service making HTTP requests to a hostname that an upstream resolver has poisoned. Because FeathersJS often relies on external services (for example, a user service, notification service, or database endpoint), the framework may perform hostname resolution at request time via Node.js built-in modules such as dns or libraries like axios and node-fetch. If the remote service’s hostname is not validated and the DNS response is not protected, FeathersJS may unknowingly route traffic to an attacker-controlled server.

Consider a FeathersJS app configured in JavaScript that calls a payment provider via hostname without additional safeguards:

const axios = require('axios');

app.use('/payments', {
  async create(data) {
    // Vulnerable: relies on DNS resolution of payment.example.com at runtime
    const url = `https://payment.example.com/v1/charge`;
    const response = await axios.post(url, data);
    return response.data;
  }
});

If an attacker can poison the cache for payment.example.com (e.g., via a compromised resolver or a TTL manipulation attack), the DNS query may return an IP under the attacker’s control. The FeathersJS service then sends sensitive payment data to the malicious host. This risk is elevated when the application uses short DNS TTLs or when the runtime environment shares a resolver with other potentially compromised services. Moreover, if your FeathersJS server is deployed in a containerized or serverless environment that caches DNS at the OS layer, poisoned entries may persist across requests, allowing the attack to remain effective for an extended period.

Another scenario involves service discovery patterns where FeathersJS resolves internal hostnames dynamically. For example, if your app queries a service registry using a hostname and then passes that hostname to HTTP clients, a poisoned cache can redirect internal traffic and facilitate lateral movement. Because the vulnerability arises from the interaction between DNS behavior and the way FeathersJS invokes network calls, it is not a bug in FeathersJS itself but a configuration and dependency concern that must be mitigated at the application and infrastructure level.

Javascript-Specific Remediation in Feathersjs — concrete code fixes

Remediation focuses on ensuring that hostname resolution is either pre-validated, performed against a trusted resolver, or bypassed entirely by using direct IP addresses or pinned connections. Below are JavaScript-specific fixes tailored for FeathersJS services.

1. Use an IP address or a fixed, trusted endpoint

Instead of relying on runtime DNS resolution, configure your HTTP client to connect directly to a known IP address or a fixed hostname with a long-lived, trusted DNS record. This approach eliminates cache poisoning risk for the targeted domain.

const axios = require('axios');

app.use('/payments', {
  async create(data) {
    // Use a pinned IP or a trusted, long-lived hostname
    const url = `https://203.0.113.42/v1/charge`;
    const response = await axios.post(url, data);
    return response.data;
  }
});

2. Override the DNS resolution in Node.js for critical requests

You can use the dns module to perform a one-time, verified lookup and then cache the result for the lifetime of the process. This ensures that only a trusted resolver is used and that subsequent calls skip system-level caching.

const dns = require('dns').promises;
const axios = require('axios');

async function getPaymentEndpoint() {
  // Explicitly choose a trusted resolver (e.g., 1.1.1.1)
  const records = await dns.resolve4('payment.example.com', { servers: ['1.1.1.1'] });
  return `https://${records[0]}/v1/charge`;
}

app.use('/payments', {
  async create(data) {
    const url = await getPaymentEndpoint();
    const response = await axios.post(url, data);
    return response.data;
  }
});

3. Pin certificates and enforce HTTPS strict transport

Even if DNS is poisoned, certificate pinning or strict HTTPS validation can prevent a man-in-the-middle from successfully impersonating the service if they cannot present a valid, expected certificate. With FeathersJS, you can configure your HTTP client to verify certificates strictly and optionally pin public key hashes.

const axios = require('axios');
const https = require('https');

const agent = new https.Agent({
  cert: fs.readFileSync('/path/to/cert.pem'),
  ca: fs.readFileSync('/path/to/ca.pem'),
  checkServerIdentity: (host, cert) => {
    // Perform additional validation or pin a fingerprint
    if (cert.fingerprint !== 'EXPECTED_FINGERPRINT') {
      throw new Error('Certificate pinning failure');
    }
    return undefined;
  }
});

app.use('/payments', {
  async create(data) {
    const client = axios.create({ httpsAgent: agent });
    const url = `https://payment.example.com/v1/charge`;
    const response = await client.post(url, data);
    return response.data;
  }
});

4. Harden the runtime environment

Configure your container or host to use a secure, trusted DNS resolver (such as 1.1.1.1 or 8.8.8.8) and disable unnecessary DNS features like DNS rebinding protection if it interferes with legitimate internal lookups. Ensure that your FeathersJS application does not fall back to unverified resolution paths when a lookup fails.

# Example container-level configuration (not JS code, but often set in Docker or k8s)
# --dns 1.1.1.1 --dns 8.8.8.8

These JavaScript-focused measures reduce the attack surface and ensure that FeathersJS-based services remain resilient against DNS cache poisoning. Always validate external dependencies and prefer fixed endpoints or verified resolution whenever handling sensitive operations.

Frequently Asked Questions

Does middleBrick test for DNS cache poisoning during scans?
middleBrick focuses on unauthenticated attack surface checks such as input validation and SSRF. DNS cache poisoning is typically evaluated through infrastructure testing and resolver configuration audits, which are outside the scope of this scanner.
Can the middleBrick CLI or GitHub Action detect DNS-related misconfigurations?
The middleBrick CLI and GitHub Action run 12 security checks including Input Validation and SSRF, which can surface indicators that may lead to DNS poisoning. For definitive DNS cache poisoning assessments, combine middleBrick findings with specialized network and resolver testing.