Dangling Dns in Express
How Dangling DNS Manifests in Express
Dangling DNS in Express applications occurs when DNS records point to infrastructure that no longer hosts your API, creating a security blind spot that attackers can exploit. Unlike generic web servers, Express applications have unique characteristics that make dangling DNS particularly dangerous.
The most common scenario involves Express apps deployed on cloud platforms like AWS, Azure, or GCP. When you migrate your Express API from one service to another—say, moving from AWS Elastic Beanstalk to Azure App Service—the old DNS records often remain active. Attackers can discover these abandoned endpoints and probe them for sensitive data, since Express apps frequently contain hardcoded secrets, API keys, or database credentials.
Express's middleware architecture creates additional attack surfaces. Consider an Express app using helmet, cors, and authentication middleware. When deployed to a new environment, the old DNS endpoint still exposes these middleware configurations. An attacker might discover that the abandoned endpoint accepts CORS requests from arbitrary origins or has overly permissive helmet configurations, revealing implementation details about your security posture.
Another Express-specific manifestation occurs with environment-specific configurations. Many Express apps use process.env variables for database connections, JWT secrets, or third-party API keys. When DNS records point to decommissioned infrastructure, these environment variables might still be accessible through error messages or debug endpoints that developers forgot to remove. Express's error handling middleware can inadvertently leak stack traces containing sensitive configuration data.
Subdomain takeover is particularly relevant for Express apps using wildcard DNS records. If you have a wildcard CNAME pointing to a cloud service that you've discontinued, an attacker can provision their own service under that domain and intercept requests meant for your Express API. Since Express apps often handle authentication tokens and session data, this creates a perfect scenario for credential harvesting.
API versioning in Express creates another vulnerability vector. Developers often maintain multiple API versions (v1, v2, v3) with different DNS endpoints. When you deprecate v1 but forget to remove its DNS record, attackers can target older, potentially less secure Express endpoints that might lack modern security middleware or input validation.
Express-Specific Detection
Detecting dangling DNS for Express applications requires a multi-layered approach that combines DNS reconnaissance with application fingerprinting. Start by enumerating all DNS records associated with your domain using tools like dig, nslookup, or specialized reconnaissance platforms. Look for A, AAAA, CNAME, and TXT records that might point to your Express infrastructure.
Once you've identified potential endpoints, use HTTP fingerprinting to determine if they're running Express. Express applications have distinctive characteristics in their HTTP responses. The X-Powered-By header often reveals "Express" (though this should be disabled in production). More reliably, Express's default error pages and middleware behavior create unique response patterns.
Here's a practical detection script using Node.js that probes suspected endpoints for Express characteristics:
const axios = require('axios');
async function isExpressEndpoint(url) {
try {
const response = await axios.get(url, {
timeout: 5000,
headers: {
'User-Agent': 'Mozilla/5.0 (compatible; ExpressDetector/1.0)'
}
});
// Check for Express-specific headers
const poweredBy = response.headers['x-powered-by'];
const expressDetected = poweredBy?.toLowerCase().includes('express');
// Check for Express error page characteristics
const isErrorPage = response.data.includes('Cannot GET') ||
response.data.includes('404 Not Found') ||
response.data.includes('express');
// Check middleware patterns
const hasCors = response.headers['access-control-allow-origin'];
const hasHelmet = response.headers['x-content-type-options'];
return {
url,
expressDetected: expressDetected || isErrorPage,
corsEnabled: !!hasCors,
helmetDetected: !!hasHelmet,
statusCode: response.status
};
} catch (error) {
return { url, reachable: false, error: error.message };
}
}
// Scan multiple endpoints
const endpoints = [
'http://api.old-domain.com',
'http://staging.old-domain.com',
'http://v1.old-domain.com'
];
endpoints.forEach(endpoint => {
isExpressEndpoint(endpoint).then(result => {
console.log(JSON.stringify(result, null, 2));
});
});
For automated detection, middleBrick's scanner can identify dangling DNS issues affecting Express applications. The scanner tests endpoints without requiring credentials, making it perfect for discovering abandoned Express APIs. It checks for Express-specific characteristics while also testing for the 12 security categories mentioned earlier.
middleBrick's approach is particularly effective because it combines black-box scanning with OpenAPI spec analysis. If you have an old OpenAPI specification for a deprecated Express API, middleBrick can cross-reference the spec with live endpoints to identify mismatches between documented and actual infrastructure.
Enterprise teams should integrate dangling DNS detection into their DevSecOps pipelines. Using middleBrick's CLI or GitHub Action, you can automatically scan all DNS records associated with your organization whenever DNS changes are made. This catches dangling endpoints before attackers can exploit them.
Express-Specific Remediation
Remediating dangling DNS for Express applications requires both immediate action and long-term process improvements. The first step is identifying all active DNS records through your DNS provider's dashboard (Cloudflare, Route53, Azure DNS, etc.). Look for records pointing to services you no longer control or maintain.
For Express applications, implement proper deprecation procedures. When sunsetting an Express API version or migrating to new infrastructure, follow this process:
// Example Express middleware for graceful deprecation
const express = require('express');
const app = express();
// Deprecation warning middleware
function deprecationMiddleware(req, res, next) {
const deprecatedVersions = ['/v1', '/api/v1'];
if (deprecatedVersions.some(path => req.path.startsWith(path))) {
res.set('Deprecation', 'true');
res.set('Deprecation-Date', '2024-01-15');
res.set('Deprecation-Info', 'https://yourcompany.com/api-deprecation');
// Log the request for monitoring
console.warn(`Deprecated endpoint accessed: ${req.path}`);
}
next();
}
app.use(deprecationMiddleware);
// Graceful shutdown endpoint
app.get('/shutdown', (req, res) => {
if (process.env.NODE_ENV === 'production' &&
req.headers['x-internal-shutdown'] === process.env.SHUTDOWN_TOKEN) {
res.json({ message: 'Shutting down gracefully' });
setTimeout(() => process.exit(0), 5000);
} else {
res.status(403).json({ error: 'Unauthorized shutdown' });
}
});
Implement comprehensive monitoring for your Express applications. Use middleware that tracks request origins and flags connections from unexpected DNS records:
function originMonitoringMiddleware(req, res, next) {
const expectedDomains = [
'api.yourcompany.com',
'api.staging.yourcompany.com'
];
const host = req.headers['host']?.split(':')[0];
const isExpected = expectedDomains.includes(host);
if (!isExpected) {
console.warn(`Unexpected host: ${host} from IP: ${req.ip}`);
// Optionally block or rate limit
}
next();
}
app.use(originMonitoringMiddleware);
Configure proper CORS policies in your Express apps to prevent unauthorized cross-origin requests, even from dangling DNS endpoints:
const corsOptions = {
origin: function (origin, callback) {
const whitelist = [
'https://yourcompany.com',
'https://app.yourcompany.com'
];
if (whitelist.indexOf(origin) !== -1 || !origin) {
callback(null, true);
} else {
callback(new Error('Not allowed by CORS'));
}
},
credentials: true
};
app.use(cors(corsOptions));
Implement automated cleanup procedures using infrastructure-as-code tools. With Terraform or similar tools, define your DNS records and Express infrastructure together, ensuring that when you destroy one, you destroy the other:
resource