HIGH type confusionfeathersjscockroachdb

Type Confusion in Feathersjs with Cockroachdb

Type Confusion in Feathersjs with Cockroachdb — how this specific combination creates or exposes the vulnerability

Type confusion in a Feathersjs service that uses Cockroachdb typically arises when application code or an ORM layer does not enforce strict schema validation before constructing SQL queries. Feathersjs is framework-agnostic about data sources, so if a service handler trusts client-supplied type indicators (e.g., a type or kind field) to decide how to build a Cockroachdb query, an attacker can change that value to alter query behavior.

Consider a Feathersjs service that accepts a payload to create or lookup records. If the handler uses a conditional based on a field like recordType to decide which SQL expression to build, and that value is passed directly into query building without validation, an attacker can change recordType from normal to something that causes unintended table joins or column selections. In Cockroachdb, which uses PostgreSQL wire protocol and supports complex types and schemas, confusion between composite types, table names, or even JSON fields can lead to data leakage or unauthorized modification when the ORM or raw query misinterprets the intended structure.

For example, an attacker may supply a type value that references a system table or a view with broader privileges, causing the query to read or write data it should not. Because Cockroachdb enforces SQL semantics strictly, a malformed or unexpected type reference can either result in an error that leaks schema information or, worse, allow an attacker to pivot by exploiting weak type checks in the application layer. This is not a Cockroachdb bug; it is a consequence of insufficient validation in the Feathersjs service logic combined with Cockroachdb’s strict typing and schema awareness.

Real-world relevance includes misconfigurations where dynamic query building uses string concatenation or naive template interpolation. If a Feathersjs hook or service method builds a WHERE clause like WHERE type = '${userInput}' without sanitization, an input such as '; DROP TABLE IF EXISTS users; -- is less likely to succeed due to Cockroachdb’s parameterization expectations, but type confusion can still lead to privilege escalation via crafted composite type names or schema-qualified identifiers that bypass intended row-level restrictions.

To detect this during a scan, middleBrick runs checks that submit unauthenticated probes designed to observe how the API reacts to unexpected type indicators, observing whether the endpoint executes unintended logic or exposes data. Findings include insecure direct object references or missing property authorization when type-based conditions fail to constrain access appropriately.

Cockroachdb-Specific Remediation in Feathersjs — concrete code fixes

Remediation centers on strict validation, parameterized queries, and avoiding dynamic type-based routing in Feathersjs services. Below are concrete, realistic code examples for a Feathersjs service using a Cockroachdb data source via an ORM or direct client.

1. Use an enum-like constant map instead of raw user input

Define allowed types in your service and map user input to known safe values. This prevents type confusion by rejecting unexpected values early.

// src/services/records/records.class.js
const ALLOWED_RECORD_TYPES = new Set(['account', 'transaction', 'audit']);

class RecordsService {
  constructor(client) {
    this.client = client; // Cockroachdb client
  }

  async create(data) {
    const { type, payload } = data;
    if (!ALLOWED_RECORD_TYPES.has(type)) {
      throw new Error('Invalid record type');
    }
    // Use parameterized query to avoid injection and type confusion
    const result = await this.client.query(
      'INSERT INTO records (record_type, data, created_at) VALUES ($1, $2, NOW()) RETURNING id',
      [type, JSON.stringify(payload)]
    );
    return result.rows[0];
  }
}

module.exports = function (app) {
  const client = app.get('cockroachClient');
  app.use('/records', new RecordsService(client));
};

2. Enforce schema and type checks in hooks

Feathersjs hooks can validate and sanitize before a query reaches Cockroachdb. This ensures that even if the client sends a malicious type, it is corrected or rejected before execution.

// src/hooks/validate-type.hook.js
module.exports = function validateTypeHook(options) {
  return async context => {
    const validTypes = ['account', 'transaction', 'audit'];
    if (context.data && context.data.type && !validTypes.includes(context.data.type)) {
      throw new Error('Invalid type supplied');
    }
    // Ensure type is explicitly set to a safe default if missing
    if (context.data && !context.data.type) {
      context.data.type = 'account';
    }
    return context;
  };
};

// In your service configuration
app.use('/records', new RecordsService(client), {
  hooks: {
    before: {
      all: [validateTypeHook()]
    }
  }
});

3. Parameterized queries with explicit schema qualification

When using raw SQL, always use placeholders and qualify table names with explicit schemas. Do not allow user input to dictate schema or table names.

const { Client } = require('pg'); // Cockroachdb compatible driver
const client = new Client({ connectionString: process.env.DATABASE_URL });

async function getRecordsByType(userSuppliedType) {
  // Map to a known safe schema.table
  const allowedTableMap = {
    account: 'public.accounts',
    transaction: 'public.transactions',
    audit: 'public.audit_logs'
  };
  const table = allowedTableMap[userSuppliedType];
  if (!table) {
    throw new Error('Invalid type for table lookup');
  }
  const res = await client.query(
    `SELECT id, data FROM ${table} WHERE owner_id = $1 AND archived = $2`,
    [context.params.account.id, false]
  );
  return res.rows;
}

4. Avoid dynamic type-based routing in service methods

Do not write service methods that switch behavior based on a field value to decide which query to run. Instead, use explicit branches that are verified at compile time or via strict validation.

// Bad — prone to type confusion
async get(data) {
  if (data.type === 'admin') {
    return this.client.query('SELECT * FROM admin_records WHERE id = $1', [data.id]);
  } else {
    return this.client.query('SELECT * FROM user_records WHERE id = $1', [data.id]);
  }
}

// Good — explicit and safe
async getById(id, requesterRole) {
  const table = requesterRole === 'admin' ? 'admin_records' : 'user_records';
  const result = await this.client.query(
    `SELECT * FROM ${table} WHERE id = $1`,
    [id]
  );
  return result.rows[0];
}

By combining these practices — strict enumerated types, hook-level validation, parameterized queries with schema-qualified table names, and avoiding dynamic type routing — you eliminate type confusion risks while maintaining compatibility with Cockroachdb’s SQL semantics. middleBrick can validate these protections by scanning your endpoints and confirming that type-based conditions do not lead to unintended data exposure or behavior.

Related CWEs: inputValidation

CWE IDNameSeverity
CWE-20Improper Input Validation HIGH
CWE-22Path Traversal HIGH
CWE-74Injection CRITICAL
CWE-77Command Injection CRITICAL
CWE-78OS Command Injection CRITICAL
CWE-79Cross-site Scripting (XSS) HIGH
CWE-89SQL Injection CRITICAL
CWE-90LDAP Injection HIGH
CWE-91XML Injection HIGH
CWE-94Code Injection CRITICAL

Frequently Asked Questions

Can middleBrick detect type confusion vulnerabilities in Feathersjs services using Cockroachdb?
Yes. middleBrick runs unauthenticated checks that observe how your API reacts to unexpected type indicators and malformed schema references. Findings include missing property authorization and insecure direct object references that can indicate type confusion.
Does using an ORM eliminate type confusion risks with Cockroachdb in Feathersjs?
Not automatically. ORMs can still produce unsafe queries if they dynamically build SQL based on unchecked user input. You must validate inputs, use parameterized queries, and avoid type-based routing logic regardless of the ORM.