Dns Cache Poisoning in Feathersjs with Api Keys
Dns Cache Poisoning in Feathersjs with Api Keys — how this specific combination creates or exposes the vulnerability
DNS cache poisoning (also known as DNS spoofing) occurs when an attacker injects a malicious DNS record into a resolver’s cache, causing clients to be redirected to an attacker-controlled host. In a FeathersJS application that uses API keys for authentication, the interaction between service discovery, HTTP client calls, and key transmission can inadvertently rely on hostnames that may be resolved at runtime. If FeathersJS or its underlying transport (e.g., HTTP or socket clients) resolves hostnames dynamically and those resolutions are not pinned or validated, poisoned DNS responses can redirect traffic to a malicious endpoint.
Consider a FeathersJS service that calls an external API using a hostname (e.g., api.external.example.com) and includes an API key in headers. If the DNS record for api.external.example.com is poisoned to point to an attacker server, subsequent HTTP requests from the FeathersJS service will send API keys and potentially sensitive data to the attacker. This is especially relevant when API keys are passed in headers and the application does not enforce strict transport-layer validation. The risk is compounded when the FeathersJS app runs in environments where DNS resolution is shared or mutable (e.g., containers, Kubernetes, or serverless platforms with shared resolvers).
Moreover, if the FeathersJS client uses an HTTP adapter that performs hostname resolution on each request (or caches DNS entries with a long TTL), poisoned entries can persist across requests, enabling prolonged redirection. Because API keys are static credentials, once leaked via a redirected request to a malicious server, attackers can impersonate the service until the keys are rotated. Therefore, DNS cache poisoning in this context is not merely a network issue; it becomes an authentication bypass vector when API keys are used without additional safeguards such as certificate pinning or strict hostname verification.
Api Keys-Specific Remediation in Feathersjs — concrete code fixes
To mitigate DNS cache poisoning risks when using API keys in FeathersJS, focus on ensuring that outbound HTTP calls validate endpoints and protect credentials. Use pinned hostnames via static IPs or service discovery mechanisms that do not rely on mutable DNS, and ensure API keys are transmitted only over verified channels.
Example 1: Using a fixed IP with HTTPS and API keys in FeathersJS client
Instead of relying on a hostname that could be poisoned, resolve the target IP once and use it directly in requests while still validating the server’s certificate. This approach reduces reliance on DNS for each call.
const axios = require('axios');
const httpsAgent = new (require('https')).Agent({
rejectUnauthorized: true
});
const apiClient = axios.create({
httpsAgent,
headers: {
'Authorization': 'Bearer YOUR_API_KEY_HERE'
},
// Use a fixed IP and explicit port to avoid DNS lookups
baseURL: 'https://93.184.216.34:443' // example IP for a trusted endpoint
});
// Example service call
async function fetchSecureData() {
try {
const response = await apiClient.get('/v1/resource');
console.log(response.data);
} catch (error) {
console.error('Request failed:', error.message);
}
}
fetchSecureData();
Example 2: FeathersJS client with strict hostname verification and API keys
If you must use hostnames, ensure your HTTP client enforces strict hostname verification and avoid caching poisoned entries. Below is a FeathersJS service configuration that uses a custom HTTP transport with strict checks.
const feathers = require('@feathersjs/feathers');
const rest = require('@feathersjs/rest-client');
const https = require('https');
const api = feathers();
const request = rest('https://api.trusted.example.com');
// Configure the HTTP agent to reject unauthorized certificates and use default DNS but with short TTL
const agent = new https.Agent({
rejectUnauthorized: true,
maxCachedSessions: 0
});
request.configure(httpClient => {
httpClient.defaults.agent = agent;
httpClient.defaults.headers.common['Authorization'] = 'ApiKey YOUR_API_KEY_HERE';
});
api.use('items', request.service('items'));
// Example call — ensures each request uses the configured, verified client
app => {
app.use('/external-items', api);
};
General remediation practices
- Use HTTPS with valid certificates and enable strict certificate validation.
- Consider using IP addresses or service mesh endpoints where DNS is not involved.
- Rotate API keys regularly and monitor for unauthorized usage.
- Employ network-level protections such as DNSSEC-aware resolvers where possible, though this is an infrastructure control outside FeathersJS scope.