MEDIUM dangling dnskoamutual tls

Dangling Dns in Koa with Mutual Tls

Dangling Dns in Koa with Mutual Tls — how this specific combination creates or exposes the vulnerability

A dangling DNS record occurs when a hostname (e.g., legacy.internal.example.com) still resolves to an IP address but is no longer actively used or intentionally configured by the application. In a Koa server that uses mutual TLS (mTLS), this combination can expose a mismatch between transport-layer identity and application-layer routing, increasing the risk of unintended routing or data exposure.

With mTLS, the client presents a certificate that the server validates against a trusted CA; the server may also use the client certificate fields (such as Common Name or Subject Alternative Name) to make authorization decisions. If the Koa application resolves a hostname like legacy.internal.example.com—which has a dangling DNS record—to an IP that hosts a different service or an outdated Koa instance, a client with a valid certificate for that hostname might be routed to an unintended endpoint. Because mTLS is enforced at the TLS layer before the HTTP layer is inspected, the server may accept the connection based on certificate validity while the application logic does not expect traffic for that dangling hostname.

This scenario can lead to several issues:

  • Routing to an unintended Koa service that may have weaker configuration or different trust assumptions.
  • Authorization bypass if the dangling hostname is associated with an older policy where broader access was allowed.
  • Information leakage if the dangling DNS record points to a service that returns debug or error details, aiding further reconnaissance.

For example, a DNS entry for legacy-payments.internal.example.com may point to an IP that now runs a generic Koa health-check service. A client with a certificate issued for legacy-payments.internal.example.com can establish an mTLS connection, but the Koa app may not correctly validate the intended service identity, inadvertently exposing health or debug endpoints.

To detect such conditions during a scan, middleBrick checks for unresolved or ambiguous hostname-to-route mappings and validates that TLS-level identities align with application-level routing. This helps identify scenarios where dangling DNS records intersect with mTLS configurations, reducing the attack surface associated with misdirected traffic.

Mutual Tls-Specific Remediation in Koa — concrete code fixes

Remediation focuses on ensuring strict hostname verification, precise certificate validation, and explicit routing checks in Koa when using mutual TLS. Below are concrete, working examples using the https module and koa with koa-ssl-compat or native TLS options.

1. Enforce mTLS with hostname verification in Koa

Configure the HTTPS server to require client certificates and verify the hostname against the certificate’s Subject Alternative Names (SAN) or Common Name. Use Node.js’s built-in checkServerIdentity to enforce hostname checks even when the TLS library might skip them.

const https = require('https');
const fs = require('fs');
const Koa = require('koa');
const app = new Koa();

const serverOptions = {
  key: fs.readFileSync('server-key.pem'),
  cert: fs.readFileSync('server-cert.pem'),
  ca: fs.readFileSync('ca-cert.pem'),
  requestCert: true,
  rejectUnauthorized: true,
  checkServerIdentity: (host, cert) => {
    // Enforce hostname verification against SAN or Common Name
    const allowedHost = 'api.example.com';
    if (cert.subjectaltname && cert.subjectaltname.includes(host)) {
      return undefined; // verification passes
    }
    if (cert.subject && cert.subject.match(/CN=([\w\-\.]+)/)) {
      const commonName = RegExp.$1;
      if (commonName === host) {
        return undefined;
      }
    }
    return new Error(`Hostname mismatch: ${host} not found in certificate`);
  }
};

https.createServer(serverOptions, app.callback()).listen(8443, () => {
  console.log('mTLS Koa server listening on port 8443');
});

2. Validate client certificates against a CRL or OCSP

Ensure that client certificates are not revoked. While Node.js does not natively support CRL/OCSP in https.Server, you can perform additional checks in the TLS handshake by inspecting the client certificate and querying revocation status via an OCSP responder before accepting the request.

const tls = require('tls');
const fs = require('fs');
const Koa = require('koa');
const app = new Koa();

const serverOptions = {
  key: fs.readFileSync('server-key.pem'),
  cert: fs.readFileSync('server-cert.pem'),
  ca: fs.readFileSync('ca-cert.pem'),
  requestCert: true,
  rejectUnauthorized: true,
  // Additional verification can be implemented via secure context options
  // and by inspecting the client certificate in a TLS session event.
};

const server = tls.createServer(serverOptions, (tlsSocket) => {
  // Example: inspect client certificate after TLS handshake
  const cert = tlsSocket.getPeerCertificate();
  if (!cert || Object.keys(cert).length === 0) {
    tlsSocket.destroy();
    return;
  }
  // Perform revocation checks here (e.g., OCSP request)
  // If revoked, destroy the connection
  // tlsSocket.destroy();
  // Otherwise, proceed to Koa
  // This is a simplified illustration; integrate with your app routing.
});

server.listen(8443, () => {
  console.log('mTLS Koa server with revocation checks on port 8443');
});

3. Explicit routing validation to avoid dangling DNS effects

Ensure that the hostname used in the TLS layer is explicitly mapped to the intended route or service within your Koa app. Reject requests where the hostname does not match an allowed service endpoint.

const https = require('https');
const fs = require('fs');
const Koa = require('koa');
const app = new Koa();

const allowedHosts = new Set(['api.example.com', 'service.example.com']);

const serverOptions = {
  key: fs.readFileSync('server-key.pem'),
  cert: fs.readFileSync('server-cert.pem'),
  ca: fs.readFileSync('ca-cert.pem'),
  requestCert: true,
  rejectUnauthorized: true,
  checkServerIdentity: (host) => {
    if (!allowedHosts.has(host)) {
      return new Error(`Unauthorized host: ${host}`);
    }
    return undefined;
  }
};

https.createServer(serverOptions, (req, res) => {
  const host = req.headers.host.split(':')[0];
  if (!allowedHosts.has(host)) {
    res.statusCode = 403;
    res.end('Forbidden host');
    return;
  }
  // Proceed with Koa request handling
  app.callback()(req, res);
}).listen(8443, () => {
  console.log('Strict mTLS Koa server with host validation');
});

4. Use environment-driven configuration for DNS and routes

Avoid hardcoding hostnames; instead, use environment variables and validate them at startup to ensure DNS entries are intentional and monitored. Combine this with health checks to detect stale DNS records early.

// Example: Load allowed hosts from environment
const allowedHosts = (process.env.ALLOWED_HOSTS || 'api.example.com').split(',').map(s => s.trim());

const serverOptions = {
  key: fs.readFileSync('server-key.pem'),
  cert: fs.readFileSync('server-cert.pem'),
  ca: fs.readFileSync('ca-cert.pem'),
  requestCert: true,
  rejectUnauthorized: true,
  checkServerIdentity: (host) => {
    if (!allowedHosts.includes(host)) {
      return new Error(`Host not permitted: ${host}`);
    }
    return undefined;
  }
};

By combining strict mTLS settings with explicit hostname validation and revocation awareness, you reduce the risk that dangling DNS records can lead to unauthorized access or misrouted traffic in a Koa service.

Frequently Asked Questions

How does middleBrick detect issues related to dangling DNS records in a Koa mTLS setup?
middleBrick scans runtime behavior and maps hostname resolutions against configured routes and TLS identity checks. It flags mismatches where a hostname with a dangling DNS record can establish an mTLS connection but is not explicitly handled by the application, highlighting potential routing or authorization anomalies.
Can middleBrick’s findings map to compliance requirements when mTLS and DNS misconfigurations are found?
Yes. Findings related to mTLS and DNS misconfigurations map to controls in frameworks such as OWASP API Security Top 10, PCI-DSS, SOC2, HIPAA, and GDPR, supporting audit and compliance reporting.