HIGH ssrf server sidefeathersjsjavascript

Ssrf Server Side in Feathersjs (Javascript)

Ssrf Server Side in Feathersjs with Javascript — how this specific combination creates or exposes the vulnerability

Server-Side Request Forgery (SSRF) in a FeathersJS application written in JavaScript occurs when an attacker can coerce the server into making arbitrary HTTP requests from the host environment. FeathersJS services are typically backed by transport adapters like REST or Socket.io, and if a service accepts user-supplied URLs, hostnames, or ports and passes them directly to an HTTP client, the application can be exploited to reach internal metadata services, cloud instance metadata endpoints, or internal networks that are not publicly routable.

In JavaScript Feathers services, common patterns that introduce SSRF include dynamic configuration of HTTP clients based on user input, use of libraries such as node-fetch or axios with unvalidated URLs, and misconfigured proxy or webhook endpoints. Because FeathersJS is framework-agnostic with respect to the underlying HTTP client, the risk depends on how the developer wires requests. An attacker may supply a URL like http://169.254.169.254/latest/meta-data/iam/security-credentials/ to extract cloud credentials, or target internal services such as Redis or management APIs on 127.0.0.1 or internal Kubernetes endpoints.

The vulnerability is often rooted in insufficient input validation and lack of network-level controls. For example, if a Feathers service method accepts a url field from the request payload and uses it without hostname allowlisting or port restrictions, an attacker can pivot from the compromised service to the local container metadata endpoint or to internal TCP ports that should never be exposed. SSRF can also be chained with other issues such as unrestricted file uploads or template injection to increase impact.

To detect this using middleBrick, which specializes in black-box scanning for unauthenticated attack surfaces, you would submit the API endpoint URL. The scan runs 12 security checks in parallel, including Input Validation and SSRF. Given that FeathersJS APIs often expose dynamic endpoints, the scanner validates whether user-controlled data influences network calls and whether responses reveal sensitive internal information. The results provide severity-ranked findings and remediation guidance, helping you understand whether your service is reachable from unexpected network destinations without requiring authentication.

Because FeathersJS encourages modular service files, SSRF can be distributed across multiple services if each repeats the same unsafe pattern. The framework does not enforce any built-in network safety; therefore, developers must explicitly validate and restrict outbound destinations. middleBrick’s OpenAPI/Swagger analysis resolves $ref definitions across 2.0, 3.0, and 3.1 specs and cross-references definitions with runtime findings, which is useful for identifying indirect injection paths through generated or composed schemas.

Javascript-Specific Remediation in Feathersjs — concrete code fixes

Remediation focuses on strict input validation, allowlisting, and avoiding direct use of user-controlled values in network requests. In JavaScript Feathers services, prefer using a hardened HTTP client with a strict allowlist of permitted hosts and ports, and avoid concatenating or interpolating user input into URLs. Below are concrete code examples demonstrating safe patterns.

Unsafe Example (Vulnerable)

// services/metadata/metadata.service.js
const { Service } = require('feathersjs');
const fetch = require('node-fetch');

class MetadataService {
  async find(params) {
    const { url } = params.query; // user-controlled
    const response = await fetch(url); // SSRF risk
    const data = await response.text();
    return { result: data };
  }
}

module.exports = function () {
  const app = this;
  app.use('/metadata', new MetadataService());
};

Safe Example with Host Allowlist and Port Restrictions

// services/safe-proxy/safe-proxy.service.js
const { Service } = require('feathersjs');
const fetch = require('node-fetch');

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

function parseUrl(input) {
  let url;
  try {
    url = new URL(input);
  } catch (err) {
    throw new Error('Invalid URL');
  }
  if (!ALLOWED_HOSTS.has(url.hostname)) {
    throw new Error('Hostname not allowed');
  }
  if (!ALLOWED_PORTS.has(url.port)) {
    throw new Error('Port not allowed');
  }
  return url.toString();
}

class SafeProxyService {
  async find(params) {
    const { url } = params.query;
    const safeUrl = parseUrl(url);
    const response = await fetch(safeUrl, {
      headers: { 'User-Agent': 'middleBrick-safe-proxy/1.0' },
      timeout: 5000,
    });
    const data = await response.text();
    return { result: data };
  }
}

module.exports = function () {
  const app = this;
  app.use('/safe-proxy', new SafeProxyService());
};

Safe Example with Explicit Outbound Proxy and No Dynamic Host

// services/internal-call/internal-call.service.js
const { Service } = require('feathersjs');
const axios = require('axios');

class InternalCallService {
  async create(data, params) {
    // No user-controlled host; call a fixed internal endpoint
    const response = await axios.get('http://internal-service.local/health', {
      timeout: 3000,
      headers: { 'X-Internal-Token': process.env.INTERNAL_TOKEN },
      // If you must use a proxy, configure it explicitly in code or env
      proxy: false,
    });
    return { status: response.status };
  }
}

module.exports = function () {
  const app = this;
  app.use('/internal-call', new InternalCallService());
};

Additional Hardening Recommendations

  • Validate and normalize all user input before use.
  • Use environment variables for internal service credentials rather than dynamic URLs.
  • Prefer DNS-based allowlists and reject IP addresses to prevent bypass via URL encoding.
  • Set reasonable timeouts and disable redirect following unless explicitly required.
  • Audit dependencies for known vulnerabilities and keep HTTP client libraries up to date.

middleBrick’s CLI tool can be used to scan endpoints from the terminal with middlebrick scan <url>, while the GitHub Action adds API security checks to your CI/CD pipeline, failing builds if risk scores drop below your chosen threshold. For continuous monitoring, the Pro plan supports scheduled scans and alerts, and the MCP Server enables scanning APIs directly from AI coding assistants within your development environment.

Frequently Asked Questions

How can I test if my FeathersJS API is vulnerable to SSRF?
Submit your API endpoint to middleBrick’s black-box scan. The tool will check whether user-controlled input influences outbound HTTP requests and report any indications of SSRF in the findings.
Does middleBrick fix SSRF vulnerabilities automatically?
No. middleBrick detects and reports findings with remediation guidance, but it does not modify code or block requests. You must apply the recommended input validation and allowlisting fixes in your FeathersJS service implementations.