Jwt Misconfiguration in Feathersjs with Cockroachdb
Jwt Misconfiguration in Feathersjs with Cockroachdb — how this specific combination creates or exposes the vulnerability
JWT misconfiguration in a FeathersJS application that uses CockroachDB as its data store can expose authentication bypass, privilege escalation, and data exposure risks. FeathersJS is a framework that typically relies on JWT strategies for authentication, and if JWT settings are not tightly controlled, an attacker can exploit weaknesses in token validation, secret management, or payload handling.
When integrated with CockroachDB, which provides a PostgreSQL-compatible SQL interface, the vulnerability surface includes not only the JWT handling in FeathersJS but also how tokens are stored, verified, and scoped to database rows. For example, if the JWT secret is weak or the algorithm is not explicitly enforced, an attacker can craft tokens with elevated roles. FeathersJS services then query CockroachDB using these compromised identities, potentially bypassing row-level security if authorization checks are not enforced at the service or hook layer.
Common misconfigurations include omitting the audience and issuer claims, which allows tokens issued by other services to be accepted; failing to set short expiration times (expiresIn), increasing the window for token replay; and not validating the scope or custom claims within application logic. In CockroachDB, if tokens are stored in a table (for introspection or revocation) without proper access controls, unauthorized API consumers might read or delete entries, enabling token theft or denial-of-service.
An attack chain might involve an attacker obtaining a valid JWT from a misconfigured endpoint, then using it to call a FeathersJS service that directly queries CockroachDB. If the service does not re-validate ownership or permissions based on the token’s payload, the attacker could access or modify records belonging to other users. This is particularly dangerous when combined with BOLA/IDOR vulnerabilities, where predictable identifiers are used in database queries without proper authorization checks.
Because middleBrick tests unauthenticated attack surfaces and includes checks on Authentication, Authorization, and Unsafe Consumption, it can detect JWT misconfigurations in FeathersJS services backed by CockroachDB. Findings typically highlight missing algorithm constraints, weak signing secrets, missing claim validation, and inconsistent authorization between the API layer and database access patterns.
Cockroachdb-Specific Remediation in Feathersjs — concrete code fixes
Remediation focuses on strict JWT validation, secure secret management, and proper authorization in FeathersJS hooks and services when using CockroachDB. Always explicitly define accepted algorithms and validate standard claims.
// src/hooks/authentication.js
const { AuthenticationError } = require('@feathersjs/errors');
const jwt = require('@feathersjs/authentication-jwt');
module.exports = {
secret: process.env.JWT_SECRET,
entity: 'user',
header: {
alg: 'HS256' // explicitly restrict algorithm
},
audience: 'https://api.yourapp.com',
issuer: 'feathersjs-auth',
jwtOptions: {
expiresIn: '15m' // short-lived tokens
},
handlers: {
jwt: jwt(),
local: app.service('authentication').createAuthenticationLocalStrategy()
}
};
In your service, enforce ownership and scope checks within hooks before querying CockroachDB.
// src/services/records/hooks.js
const { iff, isProvider } = require('feathers-hooks-common');
exports.ensureOwnership = () => async context => {
const { user } = context.params;
const recordId = context.id;
// Assuming user.id and record.userId exist
if (user.role !== 'admin' && String(user.id) !== String(recordId)) {
throw new NotAuthenticated('Access denied');
}
// Optionally validate against CockroachDB for additional checks
const dbRecord = await context.app.service('records').get(recordId, {
providers: [], // avoid recursion
paginate: false
});
if (!dbRecord || String(dbRecord.user_id) !== String(user.id)) {
throw new NotAuthenticated('Record not found or access denied');
}
return context;
};
Configure your CockroachDB connection securely and avoid embedding credentials in the service definition.
// src/app.js
const { Sequelize } = require('sequelize');
const sequelize = new Sequelize({
dialect: 'postgres',
host: process.env.COCKROACH_HOST,
port: 26257,
database: process.env.COCKROACH_DB,
username: process.env.COCKROACH_USER,
password: process.env.COCKROACH_PASSWORD,
protocol: 'tcp',
ssl: {
require: true,
rejectUnauthorized: true
},
logging: false
});
module.exports = sequelize;
Use middleware hooks to validate JWT claims against database-stored permissions when needed, ensuring that even with a valid token, operations respect tenant or user boundaries in CockroachDB.
// src/hooks/authorize.js
module.exports = function authorize(allowedScopes) {
return async context => {
const { scope } = context.params.user;
if (!allowedScopes.includes(scope)) {
throw new NotAuthenticated('Insufficient scope');
}
// Example: enforce row-level security manually if not enforced in DB
if (context.method === 'find' && scope === 'tenant:read') {
context.params.sequelize = { where: { tenant_id: context.params.user.tenant_id } };
}
return context;
};
};
These steps reduce the risk of JWT-related authorization issues when FeathersJS interacts with CockroachDB.
Related CWEs: authentication
| CWE ID | Name | Severity |
|---|---|---|
| CWE-287 | Improper Authentication | CRITICAL |
| CWE-306 | Missing Authentication for Critical Function | CRITICAL |
| CWE-307 | Brute Force | HIGH |
| CWE-308 | Single-Factor Authentication | MEDIUM |
| CWE-309 | Use of Password System for Primary Authentication | MEDIUM |
| CWE-347 | Improper Verification of Cryptographic Signature | HIGH |
| CWE-384 | Session Fixation | HIGH |
| CWE-521 | Weak Password Requirements | MEDIUM |
| CWE-613 | Insufficient Session Expiration | MEDIUM |
| CWE-640 | Weak Password Recovery | HIGH |