HIGH ssrf server sidefeathersjsmongodb

Ssrf Server Side in Feathersjs with Mongodb

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

Server-side SSRF occurs when a Feathersjs service accepts attacker-controlled input that influences an outbound HTTP request. In a typical Feathersjs + Mongodb stack, a service might fetch external data (e.g., avatars, webhooks, or metadata) based on user-supplied URLs or hostnames and then store or use results in MongoDB. Because Feathersjs is framework-agnostic about the transport layer, if input validation and network controls are missing, an attacker can induce the server to make requests to internal endpoints (e.g., http://169.254.169.254 for cloud metadata, internal Kubernetes services, or admin panels), leading to data exfiltration or further pivoting. The risk is not in MongoDB itself but in how Feathersjs code composes requests and passes data into MongoDB documents.

Concrete scenario: a users service accepts a pictureUrl field, downloads the image via a helper, and stores metadata in MongoDB. If the URL is user-controlled and the download helper does not validate or restrict destinations, an attacker can supply an internal address. A vulnerable Feathersjs service might look like:

const axios = require('axios');
const { MongoClient } = require('mongodb');

app.use('/users', {
  async create(data) {
    const { name, pictureUrl } = data;
    let metadata = {};
    if (pictureUrl) {
      const res = await axios.get(pictureUrl, { timeout: 3000 });
      metadata = { size: res.headers['content-length'], type: res.headers['content-type'] };
    }
    const client = new MongoClient(process.env.MONGO_URI);
    await client.connect();
    const db = client.db('app');
    const result = await db.collection('users').insertOne({ name, metadata });
    await client.close();
    return { id: result.insertedId, name, metadata };
  }
});

In this example, pictureUrl is directly used in axios.get. An attacker can set pictureUrl to http://169.254.169.254/latest/meta-data/iam/security-credentials/ to retrieve IAM credentials, or to internal services that are not exposed externally. Because the scan tests unauthenticated attack surfaces, middleBrick would flag the absence of URL allowlisting, missing egress controls, and direct use of user input in outbound requests as high-severity findings. No credentials are required to trigger SSRF if the endpoint is reachable from the scanning environment.

Additionally, if the service uses dynamic route parameters (e.g., /files/:id) and uses the parameter to construct HTTP requests to third-party APIs without strict validation, SSRF can be combined with BOLA/IDOR to reach sensitive resources. The interplay of Feathersjs services, MongoDB persistence, and external HTTP calls increases the impact of SSRF because sensitive data can be exfiltrated into the database.

Mongodb-Specific Remediation in Feathersjs — concrete code fixes

Remediation focuses on input validation, egress filtering, and avoiding direct use of user input in outbound HTTP calls. Do not rely on MongoDB operations to mitigate SSRF; fix the request logic. Use allowlists for URLs and enforce strict schema validation in Feathersjs hooks.

  • Validate and restrict URLs: allow only specific schemes and hosts, and reject private IP ranges.
  • Use a proxy or controlled fetch mechanism that does not follow redirects to internal destinations.
  • Ensure MongoDB documents do not store raw user-supplied URLs used for fetching unless they have been sanitized and verified.

Corrected example with URL allowlist and schema validation in a Feathersjs hook:

const axios = require('axios');
const { MongoClient } = require('mongodb');

function isSameOrigin(url, allowedHosts) {
  try {
    const u = new URL(url);
    return allowedHosts.includes(u.hostname);
  } catch {
    return false;
  }
}

function isPrivateAddress(hostname) {
  // Basic check; in production use a robust IP resolution + private range check
  return hostname === 'localhost' || hostname === '127.0.0.1' || hostname === '169.254.169.254';
}

app.use('/users', {
  async create(data, { params }) {
    const { name, pictureUrl } = data;
    const allowedHosts = ['cdn.example.com', 'images.example.com'];
    if (pictureUrl) {
      if (!isSameOrigin(pictureUrl, allowedHosts) || isPrivateAddress(new URL(pictureUrl).hostname)) {
        throw new Error('Invalid pictureUrl');
      }
      const res = await axios.get(pictureUrl, { timeout: 3000, maxRedirects: 0 });
      // Basic content-type guard
      if (!res.headers['content-type']?.startsWith('image/')) {
        throw new Error('Invalid image');
      }
      const metadata = { size: res.headers['content-length'], type: res.headers['content-type'] };
      const client = new MongoClient(process.env.MONGO_URI);
      await client.connect();
      const db = client.db('app');
      const result = await db.collection('users').insertOne({ name, metadata });
      await client.close();
      return { id: result.insertedId, name, metadata };
    }
    const client = new MongoClient(process.env.MONGO_URI);
    await client.connect();
    const db = client.db('app');
    const result = await db.collection('users').insertOne({ name, metadata: {} });
    await client.close();
    return { id: result.insertedId, name, metadata: {} };
  }
});

For broader protection, add an egress firewall policy that blocks outbound connections to private IP ranges (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16) and to known cloud metadata endpoints unless explicitly required. MiddleBrick can help identify missing egress controls and improper input validation as part of its security checks, providing prioritized findings with remediation guidance.

When integrating with external APIs, prefer storing only safe metadata and avoid storing raw response bodies or headers that may contain sensitive information. If you use the middleBrick CLI (middlebrick scan <url>) or GitHub Action, you can automatically detect SSRF-related misconfigurations before deployment.

Frequently Asked Questions

Can middleBrick detect SSRF in a Feathersjs service that uses Mongodb?
Yes, middleBrick scans the unauthenticated attack surface and can identify missing URL validation, missing egress controls, and unsafe use of user input in outbound requests that could lead to SSRF when combined with MongoDB-backed services.
Does middleBrick fix SSRF findings in MongoDB-backed Feathersjs apps?
middleBrick detects and reports findings with remediation guidance; it does not fix, patch, or block. Developers should apply input validation, URL allowlists, and egress filtering as outlined in the remediation section.