HIGH dangling dnsfeathersjsbasic auth

Dangling Dns in Feathersjs with Basic Auth

Dangling Dns in Feathersjs with Basic Auth — how this specific combination creates or exposes the vulnerability

A dangling DNS record occurs when a hostname (e.g., internal.api.example.com) still points to an IP address, but the service or application that previously owned that address is no longer configured to handle it. In FeathersJS, if a service route is defined under a hostname that resolves to a dangling target, requests may be forwarded to an unintended host that could be misconfigured or exposed.

When Basic Auth is used in FeathersJS, credentials are typically passed via the Authorization header on every request. If the client is configured to send requests to a hostname that resolves to a dangling DNS record, the Basic Auth credentials may be inadvertently forwarded to an unexpected endpoint. This can expose credentials to an unintended service or cause authentication to be evaluated against a different backend than intended, bypassing intended access controls.

For example, suppose a FeathersJS client is configured to call https://legacy-api.example.com, and DNS for legacy-api.example.com now points to a server that is not part of the application’s trusted infrastructure. Because Basic Auth sends the username and password with each request, the credentials could be accepted and logged by the dangling host, creating a risk of credential exposure or unauthorized access if the dangling host behaves unexpectedly or is compromised.

middleBrick detects this risk by scanning the API endpoint and checking for mismatches between declared hosts in the OpenAPI spec and runtime resolution. It flags scenarios where DNS resolution leads to unexpected endpoints and highlights Basic Auth usage as an elevated concern when host integrity cannot be assured. Findings include severity, guidance, and references to the relevant OWASP API Top 10 categories.

Basic Auth-Specific Remediation in Feathersjs — concrete code fixes

To remediate risks associated with dangling DNS when using Basic Auth in FeathersJS, ensure that service hosts are explicitly defined, that DNS records are stable and correct, and that credentials are not sent to untrusted endpoints. Below are concrete code examples demonstrating secure configuration.

1. Pin host configuration and avoid dynamic resolution of sensitive endpoints

Instead of relying on DNS-based service discovery for authenticated routes, configure the remote endpoint explicitly in your FeathersJS client configuration.

// src/client.js
const { Application } = require('@feathersjs/feathers');
const fetch = require('feathers-fetch');

const app = new Application();

app.configure(fetch({
  // Explicitly set the remote host; do not rely on runtime DNS for Basic Auth endpoints
  url: 'https://api.example.com',
  // Ensure credentials are only sent to the intended origin
  crossDomain: false
}));

app.use('/secure', require('./secure-service'));

module.exports = app;

2. Use a custom fetch hook to validate host and reject requests to unresolved or suspicious hosts

Implement a before hook that checks the request URL against an allowlist of known, stable hosts before sending credentials.

// src/hooks/ensure-trusted-host.js
module.exports = function ensureTrustedHost(options = {}) {
  const allowedHosts = new Set(['api.example.com', 'app.example.com']);

  return function(hook) {
    const url = new URL(hook.params.url || hook.app.get('url'));
    if (!allowedHosts.has(url.hostname)) {
      throw new Error('Request to untrusted host: ' + url.hostname);
    }
    return hook;
  };
};

Register the hook on your service:

// src/secure-service.js
const { Service } = require('feathersjs-communication');
const ensureTrustedHost = require('./hooks/ensure-trusted-host');

class SecureService extends Service {
  setup(app, path) {
    super.setup(app, path);
    this.hooks({
      before: {
        all: [ensureTrustedHost()]
      }
    });
  }
}

module.exports = SecureService;

3. Use token-based authentication where possible and avoid Basic Auth for high-risk endpoints

Replace Basic Auth with short-lived tokens for sensitive operations. If Basic Auth is required, scope it tightly and rotate credentials frequently.

// src/hooks/basic-auth.js — only use when host is verified
const { AuthenticationError } = require('@feathersjs/errors');

module.exports = function basicAuthHook(options) {
  return function(hook) {
    const auth = hook.params.headers.authorization;
    if (!auth || !auth.startsWith('Basic ')) {
      throw new AuthenticationError('Unauthorized');
    }
    const token = auth.slice('Basic '.length);
    const expected = process.env.BASIC_AUTH_TOKEN;
    if (token !== expected) {
      throw new AuthenticationError('Invalid credentials');
    }
    return hook;
  };
};

Apply selectively to routes that must use Basic Auth:

// src/legacy-basic-auth-service.js
const { Service } = require('feathersjs-communication');
const basicAuthHook = require('./hooks/basic-auth');

class LegacyBasicAuthService extends Service {
  setup(app, path) {
    super.setup(app, path);
    this.hooks({
      before: {
        all: [basicAuthHook()]
      }
    });
  }
}

module.exports = LegacyBasicAuthService;

4. Validate DNS and certificate information in CI/CD

Use scripts in your pipeline to confirm that hostnames resolve to expected IP ranges and that certificates are valid before deploying configurations that use Basic Auth.

// scripts/validate-dns.js (run in CI)
const dns = require('dns').promises;
const expectedIPs = new Set(['192.0.2.10', '192.0.2.11']);

async function validate() {
  const addresses = await dns.resolve4('api.example.com');
  const ok = addresses.every(a => expectedIPs.has(a));
  if (!ok) {
    console.error('DNS resolution mismatch:', addresses);
    process.exit(1);
  }
  console.log('DNS validation passed');
}
validate();

Frequently Asked Questions

How does middleBrick detect dangling DNS risks in API scans?
middleBrick compares declared hosts in OpenAPI specs with runtime DNS resolution and flags mismatches, highlighting Basic Auth usage as an elevated concern when host integrity cannot be assured.
Can Basic Auth in FeathersJS be safely used if DNS is stable?
Yes, if hostnames are pinned, DNS is verified, and credentials are not sent to untrusted endpoints. Use explicit remote URLs, preconnection host allowlists, and avoid Basic Auth for high-risk endpoints when possible.