Dangling Dns in Hapi (Javascript)
Dangling DNS in Hapi with JavaScript — How This Combination Exposes the Vulnerability
Dangling DNS occurs when a subdomain's DNS record (such as a CNAME) points to a domain or service that no longer exists or is deprovisioned, but the application still accepts traffic for that hostname. In a Hapi.js server, this can lead to serious security risks if the server does not validate the Host header against a strict allowlist of expected domains. An attacker can exploit a dangling DNS pointer to point a subdomain to an IP they control, then send requests with a forged Host header matching the dangling subdomain. If the Hapi server routes based on the Host without validation, it may process the request as if it originated from a trusted domain, potentially bypassing authentication, enabling SSRF, or facilitating cache poisoning attacks.
For example, consider a Hapi.js API that uses subdomain routing for tenant isolation: tenant1.api.example.com, tenant2.api.example.com. If the DNS record for tenant1.api.example.com is a CNAME pointing to a deprecated service (e.g., an old Azure App Service) that has been deleted, an attacker can claim that Azure subdomain and configure it to point to their own server. When they send a request to the Hapi server with Host: tenant1.api.example.com, the server may process it as tenant1’s traffic, especially if routing relies solely on the Host header. This could allow unauthorized access to tenant-specific data or execution of privileged operations.
Hapi.js does not automatically validate the Host header by default. While it uses the header for virtual hosting and routing, developers must explicitly enforce hostname validation. Failure to do so means the server trusts any Host header value that matches a route, regardless of DNS legitimacy. This is particularly dangerous in cloud environments where DNS records are frequently created and destroyed, increasing the likelihood of dangling pointers going unnoticed.
JavaScript-Specific Remediation in Hapi — Concrete Code Fixes
To mitigate dangling DNS risks in a Hapi.js application, implement strict Host header validation at the server level. This ensures the server only processes requests for domains you explicitly control and expect. The validation should occur early in the request lifecycle, ideally in a server extension point, so invalid hosts are rejected before routing or authentication logic runs.
Use Hapi’s ext('onPreAuth') extension point to validate the Host header against an allowlist of approved hostnames. This approach is framework-appropriate, leverages Hapi’s plugin system, and avoids modifying route logic. The allowlist should include all legitimate domains and subdomains your API serves, excluding any that rely on third-party or ephemeral services prone to deprovisioning.
const Hapi = require('@hapi/hapi');
const init = async () => {
const server = Hapi.server({
port: 3000,
host: 'localhost'
});
// Define allowlist of expected hostnames
const allowedHosts = [
'api.example.com',
'tenant1.api.example.com',
'tenant2.api.example.com',
'api.staging.example.com'
];
// Validate Host header early in request lifecycle
server.ext('onPreAuth', (request, h) => {
const host = request.headers.host;
if (!host || !allowedHosts.includes(host)) {
return h.response({ error: 'Invalid host header' }).code(400);
}
return h.continue;
});
// Example route
server.route({
method: 'GET',
path: '/',
handler: (request, h) => {
return { status: 'ok', tenant: request.headers.host };
}
});
await server.start();
console.log('Server running on %s', server.info.uri);
};
init().catch(err => {
console.error(err);
process.exit(1);
});
This code rejects any request with a Host header not in the allowedHosts array, returning a 400 Bad Request. It prevents attackers from exploiting dangling DNS by ensuring the server only responds to hostnames you explicitly authorize. For dynamic environments, consider updating the allowlist via automated DNS checks or infrastructure-as-code synchronization, but never rely on DNS alone for trust decisions.
Additionally, disable Hapi’s automatic virtual hosting based on Host header if not needed, though explicit validation as shown above is sufficient and clearer in intent. Always combine this with other defenses: enforce strict TLS validation, use CDN or WAF policies to restrict hostnames at the edge, and monitor DNS records for dangling pointers using external tools. However, remember that middleBrick does not fix or block vulnerabilities — it detects and reports them. The remediation above is the developer’s responsibility to implement in their Hapi.js application.