HIGH dangling dnsfeathersjsjwt tokens

Dangling Dns in Feathersjs with Jwt Tokens

Dangling Dns in Feathersjs with Jwt Tokens — how this specific combination creates or exposes the vulnerability

A Dangling DNS condition occurs when a service endpoint is unintentionally exposed or when internal hostnames resolve to unexpected destinations in production. In a FeathersJS application that uses JWT tokens for authentication, this can expose authorization boundaries or authentication bypass paths if service discovery, client configuration, or token validation logic rely on hostnames that do not reliably resolve to the intended service.

FeathersJS typically exposes services over HTTP/HTTPS and can be configured with custom transports such as REST or Socket.io. When JWT tokens are used, the API surface often includes unauthenticated endpoints—such as /login or token-introspection routes—that issue or validate tokens. If these endpoints or their upstream dependencies (e.g., authentication servers, user directories, or internal microservices) rely on hostnames that later resolve incorrectly, an attacker may be able to redirect token flows or reach unintended internal endpoints.

Consider a FeathersJS service that validates JWTs by forwarding introspection or public-key discovery requests to an identity provider hostname configured via environment variables. If that hostname is a placeholder or an internal name that accidentally resolves in production—perhaps due to DNS misconfiguration or leftover deployment artifacts—the service might accept tokens issued for a different audience or skip proper validation. This can lead to authorization issues across services that share the same token format, a pattern often seen in microservice meshes where inter-service communication depends on predictable DNS resolution.

The risk is compounded when JWT tokens carry metadata such as tenant identifiers or service-specific scopes. If FeathersJS routes or middleware use hostname-based logic to enforce tenant isolation—for example, by checking a host header or a service location embedded in token claims—a dangling DNS resolution can cause tenant boundaries to blur. An attacker may leverage this by directing requests to a hostname that resolves to a less-restricted service, effectively bypassing intended access controls without modifying the token itself.

In practice, this attack surface is tested by middleBrick during its unauthenticated scan: 12 security checks run in parallel, including Authentication, BOLA/IDOR, Input Validation, and Unsafe Consumption. For JWT-using FeathersJS deployments, the scanner can detect whether public endpoints rely on ambiguous or internal hostnames in token validation flows, whether CORS rules expose token issuance to unexpected origins, and whether introspection or key-discovery endpoints are reachable from unauthenticated contexts.

Because middleBrick does not fix or block, it reports findings with severity and remediation guidance. A typical recommendation includes hardening hostname resolution, validating token audience and issuer claims strictly, and ensuring that services do not trust host-derived metadata for authorization decisions. The dashboard and CLI (via middlebrick scan <url>) surface these issues so teams can align DNS, service configuration, and token validation logic before an attacker exploits a dangling resolution path.

Jwt Tokens-Specific Remediation in Feathersjs — concrete code fixes

To remediate Dangling DNS risks in a FeathersJS application using JWT tokens, focus on making token validation independent of environment-specific hostnames and on tightening claims validation. Below are concrete code examples that you can apply in your FeathersJS service configuration.

First, configure the JWT authentication strategy with explicit options rather than relying on environment-derived hostnames for discovery or audience parameters. In src/authentication.js, set the audience and issuer explicitly:

const authentication = require('@feathersjs/authentication');
const jwt = require('@feathersjs/authentication-jwt');

module.exports = function (app) {
  const authentication = authentication(app);

  authentication.configure({
    secret: process.env.JWT_SECRET,
    entity: 'user',
    service: 'authentication',
    strategies: ['jwt'],
    jwt: {
      // Explicitly set audience and issuer; do not derive from hostnames
      audience: 'https://api.myproduct.com',
      issuer: 'https://auth.myproduct.com',
      algorithms: ['RS256']
    }
  });

  app.configure(jwt());
};

Second, in your service hooks, validate token claims rigorously and avoid using host-based logic for tenant or scope resolution. For example, in a hook that ensures tenant scope:

// src/hooks/validate-tenant.js
module.exports = function (options = {}) {
  return async context => {
    const { user } = context;
    // Assume tenantId is embedded as a custom claim in the JWT
    const { tenantId } = user;

    if (!tenantId) {
      throw new Error('Unauthorized: missing tenant claim');
    }

    // Use tenantId from the token, not from request hostname or headers
    context.params.tenantId = tenantId;
    return context;
  };
};

Third, ensure that any key discovery or introspection logic—whether for local validation or microservice calls—uses fixed, known endpoints rather than dynamic hostname resolution. When using a JWKS endpoint, pin the hostname and enforce HTTPS:

const jwksClient = require('jwks-rsa');

const client = jwksClient({
  jwksUri: 'https://auth.myproduct.com/.well-known/jwks.json',
  cache: true,
  rateLimit: true,
  jwksRequestsPerMinute: 5
});

function getKey(header, callback) {
  client.getSigningKey(header.kid, (err, key) => {
    if (err) {
      return callback(err);
    }
    const signingKey = key.publicKey || key.rsaPublicKey;
    callback(null, signingKey);
  });
}

// Use getKey in your JWT verify options
app.set('jwtVerifyOptions', {
  algorithms: ['RS256'],
  audience: 'https://api.myproduct.com',
  issuer: 'https://auth.myproduct.com',
  jwtFromRequest: require('@feathersjs/authentication-jwt').extractJwt.fromAuthHeaderAsBearerToken(),
  secretOrKeyProvider: getKey
});

Finally, audit your service configuration and environment variables to remove any hostname placeholders used in authentication flows. Prefer fixed DNS names or configuration maps that are validated in CI/CD. By combining strict claims validation, explicit audience/issuer settings, and deterministic key discovery, you reduce the impact of DNS misconfigurations and limit the attack surface exposed by a dangling DNS setup.

Frequently Asked Questions

What is a Dangling DNS issue in the context of FeathersJS and JWT tokens?
A Dangling DNS issue arises when service endpoints or internal hostnames used in JWT validation (e.g., issuer, audience, or key discovery) resolve unpredictably, potentially allowing token validation to be bypassed or misdirected across services.
How does middleBrick help detect JWT-related DNS and configuration risks?
middleBrick scans unauthenticated attack surfaces and checks Authentication, Input Validation, and Unsafe Consumption among other controls. It can identify ambiguous hostname usage in token flows and provides remediation guidance without fixing or blocking.