Data Exposure in Feathersjs with Basic Auth
Data Exposure in Feathersjs with Basic Auth — how this specific combination creates or exposes the vulnerability
FeathersJS is a popular framework for building REST and Socket.io APIs with minimal configuration. When Basic Authentication is used, the framework typically relies on an authentication hook that validates credentials passed via the Authorization header. If the implementation does not enforce HTTPS, credentials and potentially sensitive payloads are transmitted in clear text. Even with HTTPS, misconfigured hooks or services can expose data through logging, error messages, or relaxed CORS rules, leading to unintended information disclosure.
Basic Auth encodes credentials using Base64, which is not encryption. Without transport layer protection, credentials can be captured trivially. In a FeathersJS service, if the authentication hook is applied selectively or skipped for certain routes, authenticated requests may still reach endpoints that return sensitive data such as user profiles, internal identifiers, or application state. This combination increases the risk of data exposure through both passive interception and server-side information leakage.
Another vector involves error handling. FeathersJS may return detailed stack traces or internal field names when validation fails. If an authenticated request includes malformed or missing credentials, the framework might disclose which fields are expected or how the authentication layer is structured. An attacker with network visibility or access to logs can correlate these messages with authenticated sessions to infer sensitive business logic or data models.
Additionally, if the application shares domains or subdomains with less secure services, cookies or tokens used for session handling might be exposed through cross-origin requests. FeathersJS hooks that do not explicitly set secure cookie attributes or enforce strict CORS policies can inadvertently allow credential or data exposure to unauthorized origins. The framework’s flexibility in chaining hooks means a misconfigured before hook can bypass intended protections, allowing data to be returned without proper authorization checks.
Using middleBrick’s LLM/AI Security checks alongside standard API scanning helps identify whether authentication mechanisms leak system details or whether outputs expose sensitive data patterns. The scanner tests unauthenticated surfaces and can detect missing protections, misconfigured hooks, and overly verbose error reporting that contributes to data exposure in FeathersJS services using Basic Auth.
Basic Auth-Specific Remediation in Feathersjs — concrete code fixes
To mitigate data exposure when using Basic Auth in FeathersJS, enforce HTTPS across all endpoints and ensure the authentication hook is applied globally or to every service that requires protection. Always validate credentials before processing the request body, and avoid exposing internal errors to clients. The following examples demonstrate secure configuration and implementation patterns.
Example 1: Enabling HTTPS and Global Authentication Hook
Configure the server to require HTTPS and apply the authentication hook universally. This ensures credentials are validated before any service logic executes.
const feathers = require('@feathersjs/feathers');
const express = require('@feathersjs/express');
const auth = require('@feathersjs/authentication');
const local = require('@feathersjs/authentication-local');
const app = express(feathers());
app.configure(auth({
secret: process.env.AUTH_SECRET,
providers: ['local']
}));
app.use(auth.hooks({
disableUnAuthenticated: true
}));
// Enforce HTTPS in production
app.set('https', true);
app.configure(require('./services/users'));
app.configure(require('./services/posts'));
const port = process.env.PORT || 3030;
app.listen(port).on('listening', () => {
console.log(`Server is running on ${app.get('https') ? 'https' : 'http'}://localhost:${port}`);
});
Example 2: Securing a Specific Service with Authentication and Safe Error Handling
Apply authentication at the service level and customize error messages to avoid leaking internal details. This approach limits the scope of authentication and prevents verbose errors from exposing system internals.
const { iff, isProvider } = require('@feathersjs/authentication-hooks');
module.exports = {
before: {
all: [iff(isProvider('external'), auth.hooks())],
find: [],
get: [auth.hooks()],
create: [],
update: [auth.hooks()],
patch: [auth.hooks()],
remove: [auth.hooks()]
},
after: {
all: [],
find: [context => {
// Remove sensitive fields from response
context.result.data = context.result.data.map(item => {
const { password, salt, ...publicData } = item;
return publicData;
});
return context;
}],
get: [context => {
if (context.result) {
delete context.result.salt;
}
return context;
}],
error: [context => {
// Avoid exposing stack traces in production
if (context.error) {
context.error.message = 'An error occurred';
delete context.error.stack;
}
return context;
}]
},
error: []
};
Example 3: Validating Credentials Before Processing
Ensure that authentication is resolved before any business logic runs. This prevents unauthorized data exposure by rejecting requests early if credentials are invalid or missing.
const auth = require('@feathersjs/authentication');
const authentication = auth({
secret: process.env.AUTH_SECRET,
entity: 'user',
service: 'users'
});
app.use('/secure-data', {
async before (context) {
const authResult = await authentication.before(context);
if (!authResult.params.account) {
throw new Error('Unauthorized');
}
context.params.account = authResult.params.account;
return context;
},
// Service logic follows
});
Example 4: Hardened Configuration with Secure Cookies and CORS
When using cookie-based sessions or tokens, enforce secure attributes and restrict CORS to known origins to prevent data exposure through cross-origin requests.
const cors = require('@feathersjs/configuration-cors');
app.configure(cors({
origin: 'https://trusted-domain.com',
credentials: true
}));
app.configure(express.rest());
// Set secure cookie attributes if using cookie sessions
app.set('trust proxy', 1);
app.use(require('cookie-parser')());
Related CWEs: dataExposure
| CWE ID | Name | Severity |
|---|---|---|
| CWE-200 | Exposure of Sensitive Information | HIGH |
| CWE-209 | Error Information Disclosure | MEDIUM |
| CWE-213 | Exposure of Sensitive Information Due to Incompatible Policies | HIGH |
| CWE-215 | Insertion of Sensitive Information Into Debugging Code | MEDIUM |
| CWE-312 | Cleartext Storage of Sensitive Information | HIGH |
| CWE-359 | Exposure of Private Personal Information (PII) | HIGH |
| CWE-522 | Insufficiently Protected Credentials | CRITICAL |
| CWE-532 | Insertion of Sensitive Information into Log File | MEDIUM |
| CWE-538 | Insertion of Sensitive Information into Externally-Accessible File | HIGH |
| CWE-540 | Inclusion of Sensitive Information in Source Code | HIGH |