Dns Rebinding with Api Keys
How Dns Rebinding Manifests in Api Keys
Dns Rebinding attacks exploit the trust relationship between a client and a server by manipulating DNS resolution to bypass same-origin policies. When API keys are involved, this attack becomes particularly dangerous because keys often grant broad access to backend services.
The attack works by registering a domain that resolves to different IP addresses over time. Initially, it resolves to the attacker's server (IP_A), then quickly switches to the target's internal server (IP_B). The victim's browser, having already established a trust relationship with the domain, sends requests to the internal server with any stored credentials or API keys.
For API keys, this manifests in several critical ways:
- Internal API endpoints that trust requests from authenticated users can be accessed via the rebinding technique
- API keys stored in browser localStorage or cookies can be exfiltrated through internal network requests
- Services that validate API keys without proper origin checks become vulnerable to internal network scanning
- Internal microservices that trust requests from other internal services can be compromised
Consider this vulnerable pattern in API key validation:
app.post('/api/secure-endpoint', async (req, res) => {
const apiKey = req.headers['x-api-key'];
const isValid = await validateApiKey(apiKey);
// No origin validation - vulnerable to DNS rebinding
if (isValid) {
const internalData = await fetchInternalResource();
res.json(internalData);
}
});An attacker can register a domain that resolves to their server, then quickly rebinds to internal IPs like 192.168.1.100 or 10.0.0.5. The browser, having already established a session with the domain, will send the API key to these internal addresses, allowing the attacker to scan internal networks and exfiltrate data.
Another common manifestation occurs with API keys used for internal service-to-service communication. Services often validate API keys without checking the source IP or origin, assuming internal network security. DNS rebinding breaks this assumption by allowing external attackers to impersonate internal services.
The attack is particularly effective against development environments where developers might use API keys that have elevated privileges on local development servers or staging environments.
Api Keys-Specific Detection
Detecting DNS rebinding vulnerabilities in API key implementations requires both static analysis and dynamic testing. Here's how to identify these issues in your codebase:
Static Code Analysis
Look for these vulnerable patterns in your API key validation code:
# Search for missing origin validation
grep -r "validateApiKey" . --include="*.js" --include="*.ts"
grep -r "x-api-key" . --include="*.js" --include="*.ts" | grep -v "origin" | grep -v "ip" | grep -v "source"
Vulnerable patterns include:
- API endpoints that validate keys but don't verify request origin
- Services that trust API keys without IP whitelisting
- Internal APIs accessible via the same domain as external services
- API keys used for cross-origin requests without proper validation
Dynamic Testing with middleBrick
middleBrick's black-box scanning approach is particularly effective for detecting DNS rebinding vulnerabilities. The scanner tests unauthenticated attack surfaces and can identify endpoints that improperly trust API keys without origin validation.
When scanning with middleBrick, pay attention to:
- Authentication bypass findings that indicate weak API key validation
- Property Authorization issues where API keys grant excessive permissions
- Inventory Management findings that reveal internal service exposure
Manual Testing Methodology
Configure a test domain with short TTL (Time To Live) values:
# Set up DNS records with low TTL
example.test. 60 IN A 93.184.216.34
example.test. 60 IN A 192.168.1.100
Test your API endpoints by:
- Making initial requests to your API with valid API keys
- Changing DNS records to point to internal IPs
- Observing if requests with the same API keys succeed against internal services
- Checking if internal data is accessible without proper origin validation
Network-Level Detection
Monitor for unusual request patterns:
- Requests from unexpected IP ranges using valid API keys
- API key usage patterns that correlate with DNS changes
- Internal service requests originating from external domains
Implement logging that tracks both API key usage and request origins to identify potential rebinding attempts.
Api Keys-Specific Remediation
Securing API keys against DNS rebinding requires a multi-layered approach. Here are specific remediation strategies using API keys' native features and libraries:
Origin Validation
Always validate the request origin when processing API keys:
const validateApiKeyWithOrigin = async (apiKey, origin) => {
const keyData = await getApiKeyData(apiKey);
// Validate both key and origin
if (!keyData || keyData.origin !== origin) {
return false;
}
return true;
};
app.post('/api/secure-endpoint', async (req, res) => {
const apiKey = req.headers['x-api-key'];
const origin = req.get('origin') || req.get('host');
const isValid = await validateApiKeyWithOrigin(apiKey, origin);
if (isValid) {
const internalData = await fetchInternalResource();
res.json(internalData);
} else {
res.status(401).json({ error: 'Invalid API key or origin' });
}
});IP Whitelisting
Restrict API key usage to specific IP ranges:
const validateApiKeyWithIP = async (apiKey, clientIP) => {
const keyData = await getApiKeyData(apiKey);
// Check if client IP is within allowed ranges
const isAllowedIP = await checkIPWhitelist(clientIP, keyData.allowedIPs);
return keyData && isAllowedIP;
};
function checkIPWhitelist(clientIP, allowedIPs) {
const ip = require('ip');
return allowedIPs.some(range => ip.cidrSubnet(range).contains(clientIP));
}
Short-Lived API Keys
Implement time-limited API keys to reduce attack window:
const generateShortLivedKey = async (userId, ttlMinutes = 10) => {
const key = crypto.randomBytes(32).toString('hex');
const expiresAt = Date.now() + ttlMinutes * 60 * 1000;
await db.apiKeys.insert({
key,
userId,
expiresAt,
origin: '*', // Or specific origins
allowedIPs: ['127.0.0.1/8', '::1/128']
});
return key;
};
// Middleware to check expiration
const checkKeyExpiration = async (req, res, next) => {
const apiKey = req.headers['x-api-key'];
const keyData = await getApiKeyData(apiKey);
if (keyData.expiresAt < Date.now()) {
return res.status(401).json({ error: 'API key expired' });
}
next();
};
Secure Key Storage
Store API keys securely and avoid browser storage:
// Never store API keys in localStorage or cookies
// Use secure, HTTP-only cookies instead
app.post('/login', async (req, res) => {
const { username, password } = req.body;
const user = await authenticateUser(username, password);
if (user) {
const apiKey = await generateShortLivedKey(user.id);
// Set as HTTP-only cookie
res.cookie('api_key', apiKey, {
httpOnly: true,
secure: true,
sameSite: 'strict',
maxAge: 10 * 60 * 1000 // 10 minutes
});
res.json({ success: true });
} else {
res.status(401).json({ error: 'Invalid credentials' });
}
});
Rate Limiting and Monitoring
Implement rate limiting and anomaly detection:
const rateLimit = require('express-rate-limit');
const apiLimiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 100,
keyGenerator: (req) => req.headers['x-api-key'] || req.ip,
message: 'Too many requests from this API key',
standardHeaders: true,
legacyHeaders: false
});
app.use('/api/', apiLimiter);
// Monitor for unusual patterns
const monitorApiKeyUsage = async (apiKey, endpoint, success) => {
const usage = await db.usage.find({ apiKey, timestamp: { $gte: Date.now() - 60000 } });
// Flag if multiple origins in short time
const origins = [...new Set(usage.map(u => u.origin))];
if (origins.length > 1) {
console.warn(`Suspicious API key usage: ${apiKey} from multiple origins`);
}
};
middleBrick Integration
Integrate middleBrick into your security testing workflow to continuously validate your API key protections:
# GitHub Action example
name: Security Scan
on: [push, pull_request]
jobs:
security:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Run middleBrick Scan
run: |
npx middlebrick scan https://api.yourservice.com
continue-on-error: true
- name: Fail on High Risk
if: failure()
run: |
echo "Security scan failed - check middleBrick report for DNS rebinding vulnerabilities"
exit 1
By implementing these remediation strategies, you create multiple layers of defense against DNS rebinding attacks targeting your API keys. The combination of origin validation, IP whitelisting, short-lived keys, secure storage, and continuous monitoring provides comprehensive protection.