Bola Idor in Feathersjs with Basic Auth
Bola Idor in Feathersjs with Basic Auth — how this specific combination creates or exposes the vulnerability
BOLA (Broken Level of Authorization) / IDOR occurs when an API exposes user-specific resources without verifying that the requesting user owns or is authorized to access those resources. In FeathersJS, this commonly arises when a service route returns records based on a user identifier taken from the authentication payload (e.g., the decoded JWT or Basic Auth credentials) but does not enforce that ownership on every query.
When Basic Auth is used in FeathersJS, the credentials are typically validated via an authentication strategy (such as @feathersjs/authentication-local), and the authenticated user’s identity is attached to the request object as params.user. If a developer writes a service handler that queries data using something like app.service('messages').find({ query: { userId: params.user.id } }) but the underlying database or query layer does not enforce row-level ownership, other users can manipulate the request—by changing numeric IDs, UUIDs, or other resource keys in the URL or query parameters—to access other users’ data. This is BOLA/IDOR: the API trusts user-supplied identifiers instead of ensuring that every read, update, or delete operates within the scope of the authenticated subject.
FeathersJS itself is framework-agnostic about data storage; the framework does not automatically scope queries to the authenticated user. If the service does not explicitly apply scope rules, an attacker can probe endpoints with predictable resource identifiers. For example, an endpoint like /messages/42 might return a message record if the handler only checks authentication (via Basic Auth headers) but does not confirm that message 42 belongs to the authenticated user. Because the scan tests unauthenticated attack surfaces and can detect IDOR-like patterns through response analysis, such misconfigurations are observable when proper ownership checks are absent.
Basic Auth in this context sends credentials on each request; if those credentials are leaked in logs, error messages, or insecure transport, or if the application reuses the authenticated identity without scoping, the attack surface expands. An SSRF or insecure deserialization issue could further expose internal mappings between user identifiers and resources. The LLM/AI security checks do not directly test IDOR, but the broader scan can surface data exposure and missing authorization findings that correlate with BOLA risks.
Basic Auth-Specific Remediation in Feathersjs — concrete code fixes
To remediate BOLA/IDOR when using Basic Auth in FeathersJS, consistently scope data access to the authenticated subject and avoid trusting client-supplied identifiers for authorization decisions. Below are concrete patterns and code examples.
1. Enforce ownership in service hooks
Use a before hook to inject the authenticated user’s ID into the query, and ensure the service only ever queries records belonging to that user. Do not rely on client-supplied userId or similar parameters for scoping.
// src/hooks/restrict-user.js
module.exports = context => {
const { user } = context.params;
if (user && user.id) {
// Force query to only return records for this user
context.params.query = context.params.query || {};
context.params.query.userId = user.id;
}
return context;
};
// In your service setup (e.g., src/services/messages/messages.hooks.js)
const restrictUser = require('./hooks/restrict-user');
app.use('messages', service());
app.service('messages').hooks({
before: {
all: [restrictUser]
}
});
2. Basic Auth setup with feathers-authentication-local and scoping
Configure Local authentication with Basic Auth–style credentials and ensure the authenticated user is attached to params.user. Then use hook-based scoping as shown above.
// src/authentication.js
const { AuthenticationService } = require('@feathersjs/authentication');
const local = require('@feathersjs/authentication-local');
module.exports = function (app) {
const authentication = new AuthenticationService(app);
app.set('authentication', {
secret: process.env.SECRET,
strategies: ['local']
});
app.use('/authentication', authentication);
app.configure(local({
usernameField: 'email',
passwordField: 'password',
entity: 'user',
service: 'users'
}));
};
Example login using Basic Auth–style credentials (email and password sent via Basic Auth header or body):
// Example login request (conceptual)
// POST /authentication
// Headers: Authorization: Basic base64(email:password)
// Body: email=user%40example.com&password=secret
// Response contains an access token; subsequent requests can also send Basic Auth if your client adapter is configured to do so.
3. Avoid unsafe find/update/remove patterns
Never allow raw user input to directly specify the resource identifier in CRUD operations without scoping. Instead of:
// UNSAFE: relies on client-supplied id without ownership check
app.service('messages').get(id, { query: { userId: params.user.id } });
Use the hook to enforce scope and then call the service method safely:
// SAFE: hook ensures query.userId = params.user.id
app.service('messages').get(id);
Similarly, for updates and patches, apply the same scoping in before hooks so that PATCH/PUT requests cannot be redirected to another user’s record.
4. Validate and normalize identifiers
Ensure IDs are validated (type checks, UUID format checks) and that any mapping between external keys and internal records is verified against the authenticated user. This reduces the risk of ID manipulation via tampered query parameters or URL paths.
Related CWEs: bolaAuthorization
| CWE ID | Name | Severity |
|---|---|---|
| CWE-250 | Execution with Unnecessary Privileges | HIGH |
| CWE-639 | Insecure Direct Object Reference | CRITICAL |
| CWE-732 | Incorrect Permission Assignment | HIGH |
Frequently Asked Questions
Does middleBrick detect BOLA/IDOR in API scans?
Can I combine Basic Auth with other authentication methods in FeathersJS?
params.user consistently and that all service hooks scope data access to the authenticated subject to avoid authorization bypasses.