Ssrf in Feathersjs with Cockroachdb
Ssrf in Feathersjs with Cockroachdb — how this specific combination creates or exposes the vulnerability
Server-Side Request Forgery (SSRF) in a FeathersJS application that uses CockroachDB as a backend can occur when the server-side code dynamically builds URLs for database or external-service calls based on unchecked user input. In FeathersJS, services are often implemented as custom code where developers may pass parameters such as host, port, or database identifiers into HTTP or database clients. If these parameters are derived from request query strings or payloads without strict validation, an attacker can force the server to make arbitrary internal or external requests.
When CockroachDB is involved, the risk can be amplified in specific deployment patterns. For example, a FeathersJS service might construct a connection string or a proxy URL that includes a hostname or path controlled by the user to route queries across CockroachDB clusters. An attacker could supply an internal IP address (e.g., 169.254.169.254, the AWS metadata service) or a sensitive internal service endpoint, causing the server to leak metadata or interact with internal resources. Because FeathersJS is framework-agnostic about the transport layer, developers might use generic HTTP clients or database drivers that do not enforce network boundaries, enabling SSRF via crafted requests.
Another scenario involves OpenAPI/Swagger spec parsing in FeathersJS. If the application loads an external spec at runtime to generate clients or validate requests, and the spec URL is user-supplied, SSRF can occur as the server fetches the provided URL. CockroachDB-related schemas might be referenced in those specs, and an attacker could redirect the fetch to an internal service that only resolves within the cluster, leading to unintended data exposure or reconnaissance. Because middleBrick tests SSRF as part of its 12 parallel security checks, it can identify such patterns in unauthenticated scans by analyzing endpoint definitions and runtime behavior.
In a typical FeathersJS service file, you might see code like this where a user-provided parameter is concatenated into a database or HTTP request:
// Risky: using user input to form a request URL or DB route
app.service('query').hooks({
before: {
create: async context => {
const { host, port } = context.data;
// Potentially dangerous: host/port from user input
const url = `http://${host}:${port}/sql`;
const response = await fetch(url, {
method: 'POST',
body: JSON.stringify({ query: context.data.sql })
});
context.result = await response.json();
return context;
}
}
});
If this endpoint is exposed without input validation and the FeathersJS app connects to CockroachDB through such a proxy, SSRF becomes viable. An attacker could supply host=localhost and port=26257 (CockroachDB default) to interact with the database directly, or supply internal metadata URLs to probe the environment. middleBrick’s LLM/AI Security and SSRF checks help surface these patterns by correlating spec definitions with runtime behavior, ensuring that untrusted input never reaches network clients.
Cockroachdb-Specific Remediation in Feathersjs — concrete code fixes
To mitigate SSRF in FeathersJS with CockroachDB, enforce strict allowlisting and avoid dynamic URL construction from user input. Validate and sanitize all parameters that influence network destinations. Prefer configuration-based endpoints over runtime assembly, and use environment variables for cluster addresses. When interacting with CockroachDB, use the official client with fixed connection parameters and enable secure TLS settings.
Below are concrete code examples demonstrating safe practices.
1. Fixed endpoint with validated parameters
Define allowed hosts and ports explicitly. Reject any input that does not match a known pattern.
const allowedHosts = new Set(['cockroachdb-cluster.example.com', '10.0.1.100']);
const allowedPorts = new Set([26257, 26258]);
app.service('query').hooks({
before: {
create: async context => {
const { host, port } = context.data;
if (!allowedHosts.has(host) || !allowedPorts.has(port)) {
throw new Error('Invalid endpoint');
}
const url = `https://${host}:${port}/sql`;
const response = await fetch(url, {
method: 'POST',
headers: { 'Authorization': `Bearer ${process.env.COCKRACK_TOKEN}` },
body: JSON.stringify({ query: context.data.sql })
});
context.result = await response.json();
return context;
}
}
});
2. Use CockroachDB client with static configuration
Instead of building proxy URLs, connect directly using the CockroachDB Node.js client with a fixed connection string stored in environment variables.
const { Client } = require('cockroachdb');
const client = new Client({
connectionString: process.env.COCKROACH_CONNECTION_STRING,
ssl: { rejectUnauthorized: true }
});
app.service('data').hooks({
before: {
create: async context => {
await client.connect();
const result = await client.query(context.data.sql);
context.result = result.rows;
await client.end();
return context;
}
}
});
3. Reject SSRF-prone patterns in hooks
Add a global hook to sanitize or remove dangerous fields before they reach services.
app.hooks({
before: {
all: [context => {
if (context.data && typeof context.data === 'object') {
delete context.data.host;
delete context.data.port;
delete context.data.url;
}
return context;
}]
}
});
These measures ensure that FeathersJS services remain resilient against SSRF while interacting with CockroachDB. middleBrick’s dashboard and CLI can scan your endpoints to verify that such protections are in place and that no unsafe dynamic requests are present.
Related CWEs: ssrf
| CWE ID | Name | Severity |
|---|---|---|
| CWE-918 | Server-Side Request Forgery (SSRF) | CRITICAL |
| CWE-441 | Unintended Proxy or Intermediary (Confused Deputy) | HIGH |