Prototype Pollution in Feathersjs with Basic Auth
Prototype Pollution in Feathersjs with Basic Auth — how this specific combination creates or exposes the vulnerability
Prototype pollution in a FeathersJS application that uses Basic Authentication can occur when user-supplied input is merged into objects used to build dynamic queries or configuration, and the endpoint is protected only by Basic Auth without additional validation. In FeathersJS, services often accept query parameters and payload fields that are passed to Mongoose models or other data mappers. If an attacker can inject properties such as __proto__, constructor.prototype, or other inherited properties into these inputs, they may modify the behavior of object creation or queries across the application.
Basic Authentication in FeathersJS typically involves checking a username and password on each request before allowing access to a service. While this protects the endpoint from unauthenticated users, it does not inherently prevent prototype pollution if the authenticated request body or query contains malicious fields. For example, an authenticated user (or a compromised account) can send a PATCH or POST request with a payload like { "__proto__": { "isAdmin": true } }. If the FeathersJS service merges this payload directly into a database update or uses Object.assign or the spread operator on plain JavaScript objects, the polluted property can affect other objects via the prototype chain.
Common patterns that increase risk include using libraries or helper functions that perform deep merges without filtering dangerous keys, and dynamically constructing query objects from user input. In FeathersJS, if a before hook modifies the data object by spreading user input into a target object, and that object participates in a Mongoose update (e.g., Model.findByIdAndUpdate(id, data)), prototype properties can affect the update behavior in subtle ways, depending on Mongoose version and schema configuration. This can lead to privilege escalation (e.g., modifying an admin flag), unauthorized data updates across records, or unexpected behavior in validators and getters that rely on prototype methods.
The OpenAPI/Swagger spec analysis feature of middleBrick helps identify endpoints that accept user input and highlights missing validation rules that could allow injection of prototype fields. When scanning a FeathersJS service protected by Basic Auth, the scanner tests unauthenticated attack surface and authenticated-style probes, checking whether inputs can reach data-modifying paths. Findings will indicate which operations are susceptible to prototype pollution and reference related attack patterns such as those cataloged in OWASP API Top 10, including excessive data exposure and unsafe consumption of user-controlled data.
Remediation guidance focuses on strict input validation, filtering dangerous keys, and avoiding unsafe object merging. Developers should explicitly whitelist allowed fields, use libraries that do not merge prototypes, and ensure that before hooks in FeathersJS do not propagate prototype pollution into query objects. These practices reduce the risk even when Basic Auth is the sole authentication mechanism.
Basic Auth-Specific Remediation in Feathersjs — concrete code fixes
To secure a FeathersJS service that uses Basic Authentication, apply input validation and avoid unsafe object merging. Below is a concrete, working example of a FeathersJS service hook that validates and sanitizes payloads before they reach the data layer.
const { Forbidden } = require('@feathersjs/errors');
const Ajv = require('ajv');
const ajv = new Ajv({ allErrors: true });
// Define an explicit schema for allowed fields
const userSchema = {
type: 'object',
properties: {
email: { type: 'string', format: 'email' },
password: { type: 'string', minLength: 8 },
name: { type: 'string' },
role: { enum: ['user', 'admin'] }
},
additionalProperties: false
};
const validate = ajv.compile(userSchema);
function validateInput(context) {
const data = context.data || {};
const valid = validate(data);
if (!valid) {
throw new Forbidden('Invalid input: ' + validate.errors.map(e => e.message).join('; '));
}
// Remove any unexpected keys that may have been added by merging helpers
context.data = Object.keys(data).reduce((acc, key) => {
if (validate.schema.properties[key] !== undefined) {
acc[key] = data[key];
}
return acc;
}, {});
return context;
}
// Apply as a before hook
app.service('users').hooks({
before: {
create: [validateInput],
update: [validateInput],
patch: [validateInput]
},
after: {
// Keep after hooks clean and avoid mutating sensitive fields
}
});
This hook uses Ajv to enforce a strict schema with additionalProperties: false, which prevents prototype pollution fields such as __proto__ or constructor from being accepted. The hook is applied to create, update, and patch methods, ensuring that both authentication via Basic Auth and input validation are enforced consistently.
Additionally, avoid using object spread or merge utilities that do not protect against prototype pollution. Prefer explicit assignment for known-safe fields:
function safeSanitizeUser(input) {
const safe = {};
if (typeof input.email === 'string') safe.email = input.email.trim().toLowerCase();
if (typeof input.name === 'string') safe.name = input.name.trim();
if (input.role === 'user' || input.role === 'admin') safe.role = input.role;
return safe;
}
In a FeathersJS before hook, you can call safeSanitizeUser to ensure only expected fields proceed to the service method. middleBrick’s CLI tool (middlebrick scan <url>) can be used in CI/CD to verify that endpoints remain protected after changes, and the GitHub Action can enforce a minimum security score before allowing deployments.
For teams using the Pro plan, continuous monitoring and Slack/Teams alerts can notify maintainers when a scan detects regression risks such as missing input validation on authenticated endpoints. The MCP Server allows developers to run scans directly from their IDE while writing hooks, supporting rapid feedback during development.
Frequently Asked Questions
Does Basic Authentication alone prevent prototype pollution in FeathersJS?
How can I test my FeathersJS service for prototype pollution using middleBrick?
middlebrick scan <your-service-url> to perform an unauthenticated scan. If your service requires Basic Auth, provide a valid credential via environment variables as supported by the scanner. Review findings in the generated report, which will highlight endpoints where user-controlled input reaches data operations without strict schema validation.