Ssrf Server Side in Feathersjs with Api Keys
Ssrf Server Side in Feathersjs with Api Keys — how this specific combination creates or exposes the vulnerability
Server Side Request Forgery (SSRF) in a FeathersJS service becomes higher risk when the service relies on API keys for authorization but does not validate or restrict the destinations of outbound HTTP requests. FeathersJS applications often use hooks to perform external calls, such as calling a third-party REST API on behalf of a client. If the user can influence the target URL and the request is executed server-side with an API key, an attacker can coerce the service into making arbitrary internal or external requests. Common patterns include a hook that reads a URL from the request payload or query parameters and then uses an API key stored in environment variables or a configuration file to authenticate to another service.
For example, consider a FeathersJS hook that fetches user details from a partner API by accepting a host parameter from the client and attaching an API key header:
// ❌ Vulnerable: user-supplied URL and API key usage without validation
const axios = require('axios');
class UserService {
async get(request) {
const { host } = request.query; // attacker-controlled
const response = await axios.get(`https://${host}/api/user`, {
headers: { 'x-api-key': process.env.PARTNER_API_KEY }
});
return response.data;
}
}
In this setup, the API key is automatically attached by the server, which means the request is authenticated on the target side. An attacker providing a host like internal.metadata.service can make the server probe internal metadata endpoints (e.g., http://169.254.169.254 on cloud environments), leading to credential leakage or SSRF pivots. Because the call is authenticated via API key, the attacker may gain indirect access to data or functionality that would otherwise be restricted. Additionally, if the service later uses the same API key to call other internal services, the blast radius increases. The vulnerability is not in the API key storage, but in the lack of URL allowlisting and SSRF-aware request validation in the FeathersJS hook layer.
SSRF can also manifest when a developer uses an API key to call an OAuth-protected third party and inadvertently allows open redirect or parameter pollution in the URL construction. The combination of server-side request execution, API key usage, and insufficient input validation creates a chain where SSRF becomes a viable path to overprivileged actions or data exfiltration.
Api Keys-Specific Remediation in Feathersjs — concrete code fixes
To mitigate SSRF when using API keys in FeathersJS, ensure that any user-influenced URLs are strictly validated and that outbound requests are constrained to known, safe endpoints. Below are concrete, safe patterns that you can adopt.
1. Use a strict allowlist of hosts
Instead of forwarding arbitrary host values, maintain a small allowlist of domains and perform exact or prefix-based matching:
const axios = require('axios');
const ALLOWED_HOSTS = new Set([
'api.partner.com',
'data.partner.com'
]);
class UserService {
async get(request) {
const { host } = request.query;
if (!host || !ALLOWED_HOSTS.has(host)) {
throw new Error('Invalid target host');
}
const response = await axios.get(`https://${host}/api/user`, {
headers: { 'x-api-key': process.env.PARTNER_API_KEY }
});
return response.data;
}
}
This prevents the server from initiating connections to internal or unexpected domains while still allowing controlled use of the API key.
2. Avoid user-controlled paths for authenticated calls
If you only need a specific resource, encode the identifier server-side instead of accepting a full path or URL:
const axios = require('axios');
class UserService {
async get(request) {
const { userId } = request.query;
// Server-side constructs the URL; no user input in the path
const response = await axios.get(`https://api.partner.com/users/${encodeURIComponent(userId)}`, {
headers: { 'x-api-key': process.env.PARTNER_API_KEY }
});
return response.data;
}
}
This approach removes the ability for an attacker to redirect the request to a different host or inject extra path segments that could lead to SSRF.
3. Centralize HTTP client behavior with instance defaults
Create an axios instance with baseURL and default headers so that any mistake in host resolution is caught early and API keys are not accidentally sent to wrong origins:
const axios = require('axios');
const partnerClient = axios.create({
baseURL: 'https://api.partner.com',
headers: { 'x-api-key': process.env.PARTNER_API_KEY }
});
class UserService {
async get(request) {
const { userId } = request.query;
// Only the path is appended; baseURL prevents host override
const response = await partnerClient.get(`/users/${encodeURIComponent(userId)}`);
return response.data;
}
}
Using a dedicated client reduces the risk of misconfiguration and makes it easier to apply timeouts, retries, and network-level restrictions.
In all cases, combine these practices with runtime scanning. middleBrick can detect SSRF and API-key exposure patterns during development and in CI/CD by adding API security checks to your pipelines; the GitHub Action can fail builds if risk scores drop below your threshold, while the Web Dashboard and MCP Server help you track findings and scan APIs directly from your AI coding assistant.