HIGH ssrffeathersjsapi keys

Ssrf in Feathersjs with Api Keys

Ssrf in Feathersjs with Api Keys — how this specific combination creates or exposes the vulnerability

Server-Side Request Forgery (SSRF) in FeathersJS when API keys are used for authentication can arise from permissive HTTP client configurations combined with insufficient validation of user-supplied URLs. FeathersJS applications often use hooks to perform external HTTP requests on behalf of clients, and if those requests incorporate unchecked values from the request context (e.g., headers, query, body) they can be coerced into directing traffic to internal services.

An API key may be stored in environment variables and injected into outgoing requests via headers. If an attacker can influence the target URL while the API key is automatically attached by the server-side hook, the API key can be smuggled into unintended internal endpoints. For example, a hook that calls an external service based on a user-provided url parameter, while adding an Authorization: Bearer {apiKey} header, may allow an SSRF attack against internal metadata services at 169.254.169.254 or internal Kubernetes endpoints at 10.0.0.1.

In FeathersJS, hooks are the common place where cross-cutting concerns like authentication and external integrations are composed. If a hook uses a generic HTTP client and does not validate or sanitize the target URL, an attacker can supply values such as http://169.254.169.254/latest/meta-data/iam/security-credentials/ to force the server to make internal calls. Because the API key is managed server-side and included automatically, the attacker can indirectly probe internal infrastructure without needing to know or authenticate to those internal services.

OpenAPI/Swagger analysis performed by middleBrick can surface discrepancies between declared request shapes and runtime behavior, such as a url field marked as required in the spec but not validated against a strict allowlist. When such discrepancies are combined with automatic inclusion of outbound headers (like API keys), the unauthenticated attack surface expands, enabling SSRF paths that may not be obvious in code review alone.

Real-world patterns observed in SSRF involve metadata services, cloud instance metadata endpoints, and internal management interfaces. Because FeathersJS does not restrict the protocols or destinations of outgoing HTTP by default, developers must explicitly constrain targets and avoid forwarding user input directly to network calls.

Api Keys-Specific Remediation in Feathersjs — concrete code fixes

Remediation focuses on strict validation of outbound targets and minimizing the exposure of API keys to user-influenced paths. Below are concrete FeathersJS hook examples that demonstrate safe patterns.

1) Validate and restrict target URLs using an allowlist approach. Do not forward user-controlled URL parameters directly to an HTTP client.

// Safe outbound request hook in a FeathersJS service
const axios = require('axios');

const ALLOWED_HOSTS = new Set(['api.example.com', 'data.example.com']);

module.exports = function (options = {}) {
  return async context => {
    const { url, customHeader } = context.data || {};

    // Validate that the URL is from an allowed host
    let targetUrl;
    try {
      targetUrl = new URL(url);
    } catch (err) {
      throw new Error('Invalid URL');
    }
    if (!ALLOWED_HOSTS.has(targetUrl.hostname)) {
      throw new Error('Target host not allowed');
    }

    // Use a server-side API key, not from the client
    const apiKey = process.env.EXTERNAL_API_KEY;
    const response = await axios.get(targetUrl.toString(), {
      headers: {
        Authorization: `Bearer ${apiKey}`,
        'X-Custom-Header': customHeader
      },
      timeout: 5000,
      // Explicitly disable redirects to internal destinations if not needed
      maxRedirects: 0
    });

    context.result = response.data;
    return context;
  };
};

2) Use a proxy configuration that does not forward arbitrary user input. Instead of dynamic URLs, prefer fixed endpoints with parameterized paths, and ensure API keys are injected via environment variables only.

// Fixed endpoint approach in a FeathersJS hook
const axios = require('axios');

module.exports = function (options = {}) {
  return async context => {
    const { paramId } = context.params.query || {};
    const apiKey = process.env.EXTERNAL_API_KEY;
    const fixedBase = 'https://api.example.com/v1/resource';

    const response = await axios.get(fixedBase, {
      params: { id: paramId },
      headers: { Authorization: `Bearer ${apiKey}` },
      timeout: 5000
    });

    context.result = response.data;
    return context;
  };
};

3) Apply global HTTP client defaults to disallow dangerous protocols and internal IP ranges. This is especially useful when multiple services perform outbound calls.

// Global axios instance with safe defaults
const axios = require('axios');

const safeAgent = new (require('http').Agent) {
  // Do not use agent that encourages internal routing
};

const apiClient = axios.create({
  timeout: 5000,
  maxRedirects: 0,
  validateStatus: () => true
});

// In a hook, use the restricted client
module.exports = function (options = {}) {
  return async context => {
    const { externalUrl } = context.data || {};
    const target = new URL(externalUrl);
    // Block private and loopback ranges
    if (['127.0.0.0/8', '10.0.0.0/8', '172.16.0.0/12', '169.254.0.0/16', '192.168.0.0/16'].some(cidr => matchCidr(target.hostname, cidr))) {
      throw new Error('Internal targets not allowed');
    }
    const apiKey = process.env.EXTERNAL_API_KEY;
    const res = await apiClient.get(target.toString(), {
      headers: { Authorization: `Bearer ${apiKey}` }
    });
    context.result = res.data;
    return context;
  };
};

4) Use middleBrick’s CLI to scan your FeathersJS endpoints and surface SSRF risks alongside API key handling issues. The tool can identify mismatches between spec definitions and runtime behavior, helping you detect over-permissive URL fields before they are exploited.

5) Map findings to compliance frameworks such as OWASP API Top 10 (2023) A05:2023 Security Misconfiguration and A01:2027 Broken Object Level Authorization, where unchecked external calls and missing host validation are common contributors.

Related CWEs: ssrf

CWE IDNameSeverity
CWE-918Server-Side Request Forgery (SSRF) CRITICAL
CWE-441Unintended Proxy or Intermediary (Confused Deputy) HIGH

Frequently Asked Questions

Can middleBrick detect SSRF risks in FeathersJS APIs that use API keys?
Yes. middleBrick scans the unauthenticated attack surface and can identify SSRF indicators such as user-influenced URL parameters combined with outbound HTTP calls, even when API keys are used server-side to sign requests.
Does using API keys alone protect a FeathersJS service from SSRF?
No. API keys managed server-side do not prevent an attacker from forcing the server to make internal requests. SSRF mitigation requires strict URL validation, protocol restrictions, and network-level controls regardless of how outbound credentials are managed.