Injection Flaws in Feathersjs (Javascript)
Injection Flaws in Feathersjs with Javascript
FeathersJS is a framework for real-time APIs that typically sits above a service layer and a database. When developers compose services using FeathersJS hooks and pass raw user input directly to database adapters or downstream services, injection flaws can occur. Injection happens when data is interpreted as code, query language, or command syntax rather than as plain data. In a FeathersJS + JavaScript stack, common sources include query parameters, payload fields used in $where-like clauses, dynamic model scopes, or custom adapters that concatenate strings to build commands or filter objects.
For example, a service that builds a MongoDB filter by string interpolation can be tricked into executing unintended operators. If a hook does query: { $where: 'this.' + userField + ' == ' + userValue }, an attacker can manipulate field names or values to change logic or escalate access. Similarly, SQL adapters or ORMs invoked from FeathersJS hooks can be abused when raw strings are embedded into raw queries, enabling SQL injection. A crafted payload might set a parameter to ' OR 1=1; -- to bypass intended filters. Even NoSQL contexts can suffer injection-like behavior when object prototypes are tampered via payloads that inject hidden properties or override inherited methods, leading to privilege confusion or prototype pollution.
The LLM/AI Security checks available in middleBrick are particularly valuable here because they detect prompt injection patterns that could abuse AI features exposed through FeathersJS endpoints. These probes include system prompt extraction, instruction override, DAN jailbreak, data exfiltration, and cost exploitation. middleBrick also scans for output leakage of API keys or PII in LLM responses and flags excessive agency patterns such as unchecked tool_calls or function_call usage. These checks run in parallel with standard API security tests, providing coverage for AI-specific risks that commonly accompany modern JavaScript services.
Other relevant attack patterns in FeathersJS include unsafe consumption of untrusted schemas, where nested objects or arrays are accepted without strict validation, enabling deeply nested injection or property manipulation. Improperly configured rate limiting and authentication checks can further allow unauthenticated attackers to probe injection surfaces at scale. Because FeathersJS often exposes a rich real-time interface, event names and payload structures must be validated to prevent injection via event data or channel parameters.
middleBrick’s OpenAPI/Swagger spec analysis helps surface these risks by resolving $ref chains across 2.0, 3.0, and 3.1 specs and cross-referencing definitions with runtime findings. This ensures that operations relying on dynamic query construction or custom hooks are reviewed against expected schemas. The scanner runs in 5–15 seconds in black-box mode, testing the unauthenticated attack surface and producing per-category breakdowns aligned with frameworks such as OWASP API Top 10, including entries relevant to injection and object injection (S01, S02).
Javascript-Specific Remediation in Feathersjs
Remediation focuses on strict input validation, avoiding string concatenation for queries, and using parameterized interfaces. Always validate and sanitize payloads against a JSON schema before they reach service logic. Prefer query builders and ORM methods that accept structured objects rather than raw strings. For hooks, enforce a schema for incoming data and reject unexpected fields.
Below are concrete JavaScript examples for FeathersJS that illustrate insecure patterns and their secure alternatives.
Example 1: Unsafe $where injection
Insecure:
app.service('items').hooks({
before: {
find: (context) => {
const userField = context.query.fieldName;
const userValue = context.query.fieldValue;
// Unsafe string concatenation in $where
context.params.query = {
$where: 'this.' + userField + ' == ' + userValue
};
return context;
}
}
});
Secure:
const Ajv = require('ajv');
const ajv = new Ajv();
const validate = ajv.compile({
type: 'object',
properties: {
field: { enum: ['name', 'email'] },
value: { type: 'string' }
},
required: ['field', 'value'],
additionalProperties: false
});
app.service('items').hooks({
before: {
find: (context) => {
if (!validate(context.query)) {
throw new Error('Invalid query');
}
const { field, value } = context.query;
// Safe: field is restricted to known values, value is passed as a parameter
context.params.query = {
$where: 'this.' + field + ' === $value',
$params: { value }
};
return context;
}
}
});
Example 2: SQL injection via raw query string
Insecure:
const knex = require('knex')({ client: 'pg' });
app.service('users').hooks({
before: {
find: (context) => {
const search = context.query.search || '';
// Unsafe raw query concatenation
context.params.knex = knex('users').whereRaw('name = \'' + search + '\'');
return context;
}
}
});
Secure:
app.service('users').hooks({
before: {
find: (context) => {
const search = context.query.search || '';
// Safe: parameterized query
context.params.knex = knex('users').where('name', search);
return context;
}
}
});
Example 3: Prototype pollution via payload
Insecure:
app.service('config').hooks({
before: {
create: [context => {
// Unsafe merge can lead to prototype pollution
Object.assign(app.get('settings'), context.data);
return context;
}]
}
});
Secure:
const deepmerge = require('deepmerge');
app.service('config').hooks({
before: {
create: [context => {
// Safe: restrict keys and avoid direct assignment
const allowed = { theme: 'string', timeout: 'number' };
const next = {};
for (const key of Object.keys(context.data || {})) {
if (allowed[key]) {
next[key] = context.data[key];
}
}
context.app.set('settings', deepmerge(app.get('settings'), next));
return context;
}]
}
});
General recommendations
- Use JSON schema validation (e.g., Ajv) on all incoming query and payload objects.
- Avoid dynamic code or query construction; prefer parameterized APIs and prepared statements.
- Sanitize and encode outputs to prevent injection into logs, responses, or downstream systems.
- Apply strict CORS and content-type rules to reduce injection surfaces in real-time transports.
- Leverage middleBrick’s CLI (
middlebrick scan <url>) and GitHub Action to integrate scans into CI/CD pipelines, failing builds if risk thresholds are exceeded.