Out Of Bounds Write in Feathersjs with Api Keys
Out Of Bounds Write in Feathersjs with Api Keys — how this specific combination creates or exposes the vulnerability
An Out Of Bounds Write in a FeathersJS service occurs when user-supplied data is used to index or size a buffer, array, or structured object without proper validation, enabling writes outside intended memory regions. When API Keys are used for authentication, the combination of per-request key validation and permissive data handling can inadvertently expose or amplify this class of vulnerability.
Consider a FeathersJS service that stores API key metadata (such as key ID, scopes, or usage counters) in a fixed-size lookup table or buffer. If the service accepts an keyId from the request—either as part of the payload or headers—and uses it directly as an index into a JavaScript Array or a Buffer, an attacker can supply an out-of-range numeric key ID. For example, supplying keyId: 999999 when the table has only 10 entries can cause FeathersJS to write beyond allocated bounds. This may corrupt adjacent data, overwrite critical runtime metadata, or destabilize the process.
FeathersJS typically relies on hooks and services defined in src/services. A vulnerable pattern is directly using key-supplied integers for array indexing without sanitization:
// Vulnerable: using keyId as an array index without bounds checks
app.service('keys').hooks({
before: {
create: [context => {
const keyId = context.data.keyId; // attacker-controlled
const table = new Array(10).fill(null);
table[keyId] = { scope: 'admin' }; // Out Of Bounds Write if keyId >= 10
context.result = { ok: true };
}]
}
});
If the API key is also used to derive a buffer offset—such as in a C++ addon or binary protocol handler—supplying a large key ID can shift the write target outside the intended segment. FeathersJS middleware that parses key material and forwards it to native bindings increases the risk if those bindings perform unchecked arithmetic on key-derived values.
The OWASP API Security Top 10 category API1:2023 Broken Object Level Authorization intersects here: an API Key that identifies a resource must not allow attackers to pivot to or corrupt unrelated objects. An Out Of Bounds Write can be chained with weak ownership checks to escalate impact, modifying state that should be immutable.
Additionally, if the API key is used to control rate-limiting windows or quota counters, an out-of-bounds write can corrupt counters, leading to denial-of-service or bypass of limits. For example, writing beyond a fixed-size circular buffer used to track requests per key can overwrite head/tail pointers, causing unpredictable behavior.
To map findings to real-world references, consider CVE-like patterns where unchecked user input leads to memory corruption. While specific CVEs are tied to native modules, the class of flaw is consistent with CWE-787 (Out-of-bounds Write). middleBrick’s 12 security checks—including Input Validation and Property Authorization—would flag such unsafe indexing and highlight the need for strict bounds enforcement.
Api Keys-Specific Remediation in Feathersjs — concrete code fixes
Remediation focuses on validating and sanitizing any data derived from API keys before using it in indexing, sizing, or pointer arithmetic. Apply strict type and range checks, and avoid using raw key-controlled values as memory offsets.
1. Validate keyId against a known set: Ensure the keyId exists in a bounded collection before use.
// Secure: validate keyId against a bounded list
app.service('keys').hooks({
before: {
create: [context => {
const validKeyIds = Array.from({ length: 10 }, (_, i) => i); // [0..9]
const keyId = Number(context.data.keyId);
if (!Number.isInteger(keyId) || !validKeyIds.includes(keyId)) {
throw new Error('Invalid key ID');
}
const table = new Array(10).fill(null);
table[keyId] = { scope: 'admin' };
context.result = { ok: true };
}]
}
});
2. Use Maps or objects instead of arrays for sparse keys: This eliminates out-of-bounds writes by design.
// Secure: use a Map to avoid fixed-size indexing
const keyStore = new Map();
app.service('keys').hooks({
before: {
create: [context => {
const keyId = context.data.keyId;
if (typeof keyId !== 'string' || keyId.length === 0) {
throw new Error('Invalid key ID');
}
keyStore.set(keyId, { scope: 'admin' });
context.result = { ok: true };
}]
}
});
3. Enforce schema validation for API key payloads: Use a validation layer to reject unexpected types or out-of-range values.
// Secure: validate with a schema (e.g., using ajv)
const Ajv = require('ajv');
const ajv = new Ajv();
const validate = ajv.compile({
type: 'object',
properties: {
keyId: { type: 'integer', minimum: 0, maximum: 9 }
},
required: ['keyId'],
additionalProperties: false
});
app.service('keys').hooks({
before: {
create: [context => {
if (!validate(context.data)) {
throw new Error('Invalid payload');
}
// Safe to use context.data.keyId within [0,9]
const table = new Array(10).fill(null);
table[context.data.keyId] = { scope: 'user' };
context.result = { ok: true };
}]
}
});
4. Apply middleBrick’s checks proactively: Use the CLI to scan your FeathersJS endpoints and detect unsafe patterns. The GitHub Action can enforce a minimum security score before merges, and the MCP Server allows you to scan directly from your IDE while writing hooks.
For continuous protection, the Pro plan enables scheduled scans and alerts, ensuring that any regression introducing an out-of-bounds pattern is caught early. The Dashboard helps track security scores over time, linking findings to relevant frameworks like OWASP API Top 10.