Token Leakage in Feathersjs with Cockroachdb
Token Leakage in Feathersjs with Cockroachdb — how this specific combination creates or exposes the vulnerability
Token leakage in a Feathersjs application backed by Cockroachdb can occur when authentication state or session tokens are inadvertently exposed through API responses, logs, or misconfigured service hooks. Feathersjs often uses JWTs or session identifiers for authentication, and if these tokens are included in query results, error messages, or client-side payloads, they may be accessible to unauthorized parties.
With Cockroachdb as the underlying database, the risk surface includes insecure query patterns that return sensitive fields, or improper handling of transactional contexts where tokens are temporarily stored in memory or logs. For example, a Feathers service that fetches a user record and inadvertently includes an authentication token field from the Cockroachdb table can expose that token to API consumers. Similarly, if the Feathers application uses hooks that log request or response data for debugging, tokens stored in headers or payloads may be written to logs that are not adequately protected.
The combination of Feathersjs service logic and Cockroachdb’s distributed SQL behavior can also lead to token leakage through replication or follower reads if queries are not carefully routed to authoritative nodes. An attacker who gains access to read replicas or observes network traffic might capture tokens that are transmitted without sufficient encryption or isolation controls. Misconfigured CORS policies or missing authentication on certain Feathers routes can further widen the exposure, allowing unauthenticated callers to receive responses that include token-bearing resources.
Common real-world patterns that contribute to leakage include returning entire database rows from a Feathers service without filtering out sensitive fields, failing to strip tokens before sending responses to the client, and improperly using global hooks that inject authentication data into contexts where it is not required. These patterns violate the principle of least privilege and increase the likelihood of token compromise through incidental exposure.
Cockroachdb-Specific Remediation in Feathersjs — concrete code fixes
To mitigate token leakage when using Feathersjs with Cockroachdb, apply strict field-level filtering, secure hook design, and explicit data handling in service methods. Avoid returning raw database rows directly from Feathers services, and ensure tokens are never part of the serialized output.
Below are concrete code examples for a Feathersjs service that interacts with a Cockroachdb table named users, where authentication tokens must never be exposed.
// src/services/user/user.service.js const { Service } = require('feathersjs'); const { Pool } = require('pg'); // Cockroachdb compatible Postgres driver const pool = new Pool({ connectionString: process.env.COCKROACHDB_CONNECTION_STRING, ssl: { rejectUnauthorized: true } }); class UserService extends Service { async find(params) { const client = await pool.connect(); try { const result = await client.query( 'SELECT id, email, full_name, created_at FROM users WHERE deleted_at IS NULL' ); // Explicitly exclude token fields from the response return result.rows.map(row => ({ id: row.id, email: row.email, full_name: row.full_name, created_at: row.created_at // Do NOT include auth_token, password_hash, or similar fields })); } finally { client.release(); } } async get(id, params) { const client = await pool.connect(); try { const result = await client.query( 'SELECT id, email, full_name, created_at FROM users WHERE id = $1 AND deleted_at IS NULL', [id] ); const row = result.rows[0]; if (!row) { throw new Error('User not found'); } return { id: row.id, email: row.email, full_name: row.full_name, created_at: row.created_at // Exclude sensitive token fields }; } finally { client.release(); } } } module.exports = function () { const app = this; app.use('/users', new UserService()); // Ensure authentication tokens are not injected into service results app.hooks({ before: { all: [], find: [], get: [], create: [], update: [], patch: [], remove: [] }, after: { all: [], find: [removeTokenFields], get: [removeTokenFields], create: [removeTokenFields], update: [removeTokenFields], patch: [removeTokenFields], remove: [removeTokenFields] }, error: { all: [], find: [], get: [], create: [], update: [], patch: [], remove: [] } }); }; function removeTokenFields(context) { // Ensure no token fields are present in the response if (Array.isArray(context.result)) { context.result = context.result.filter(item => { // Defensive cleanup: remove any unexpected token fields delete item.auth_token; delete item.password_reset_token; delete item.verification_token; return true; }); } else if (context.result && typeof context.result === 'object') { delete context.result.auth_token; delete context.result.password_reset_token; delete context.result.verification_token; } }Additionally, configure your Feathers authentication layer to avoid exposing tokens in error responses. Use explicit authentication strategies that do not return raw tokens to the client, and ensure that any logging or monitoring hooks do not capture sensitive header values. These practices reduce the risk of token leakage across the Feathersjs and Cockroachdb stack.