Sandbox Escape in Feathersjs with Cockroachdb
Sandbox Escape in Feathersjs with Cockroachdb — how this specific combination creates or exposes the vulnerability
A sandbox escape in a Feathersjs service that uses Cockroachdb can occur when application-level isolation is insufficient to prevent an attacker from leveraging database features or misconfigured service hooks to break out of intended execution boundaries. Feathersjs services often expose CRUD-like behavior through hooks and custom code, and if input validation and authorization are not rigorously enforced, an attacker may manipulate parameters to invoke unexpected database operations.
Cockroachdb, as a distributed SQL database, supports advanced SQL features such as temporary objects, procedural language extensions, and external network access via built-in functions. When Feathersjs passes unchecked user input into SQL queries—especially through dynamic find, update, or custom hooks—an attacker may attempt to inject payloads that exploit these capabilities. For example, an attacker might use crafted parameters to execute administrative commands, access system tables, or interact with external network endpoints from within the database process.
Consider a Feathersjs service that dynamically builds queries using user-supplied fields without proper sanitization. If the service uses knex or a similar query builder with raw SQL fragments, an attacker could supply values that alter query structure to access or modify data outside their scope. In a Cockroachdb environment, this may enable reading from system tables such as crdb_internal.node_statements or attempting to create temporary network listeners via built-in extensions. Because Feathersjs often runs with elevated database permissions for simplicity, the impact of such an escape can include data exfiltration, unauthorized configuration changes, or lateral movement within the cluster.
The risk is compounded when the service exposes custom hooks or uses global before/after hooks that modify query conditions without strict schema enforcement. An attacker may submit specially crafted JSON payloads that exploit prototype pollution or type coercion in JavaScript, leading to unintended SQL execution paths. Since Cockroachdb supports procedural languages, an attacker might attempt to invoke crdb_internal procedures or execute external functions if the database user has broad privileges and input validation is weak.
Real-world attack patterns include injection through $in or $like operators, misuse of raw query methods, or exploitation of reflection endpoints that expose database metadata. These vectors align with common OWASP API Top 10 risks such as Broken Object Level Authorization (BOLA) and Injection, and may map to compliance frameworks like PCI-DSS and SOC2 when sensitive data is involved. middleBrick scans detect such patterns by correlating OpenAPI specifications with runtime behavior, identifying places where parameter validation is insufficient or where database-specific features are exposed without restriction.
Without proper isolation, logging, and input sanitization, a Feathersjs application using Cockroachdb can unintentionally provide a pathway for attackers to pivot from application logic into the database environment. This underscores the importance of strict schema validation, least-privilege database accounts, and continuous scanning to detect misconfigurations before they can be exploited.
Cockroachdb-Specific Remediation in Feathersjs — concrete code fixes
Remediation focuses on strict input validation, parameterized queries, and limiting database permissions. Avoid dynamic SQL construction and raw query usage unless absolutely necessary, and ensure all user-supplied data is validated against a strict schema before being used in database operations.
Use parameterized queries with Knex.js to ensure that user input is never directly interpolated into SQL strings. For example, instead of concatenating values into a raw query, use named bindings and query builders safely:
const knex = require('knex')({ client: 'pg', connection: process.env.DATABASE_URL });
app.service('users').hooks({
before: {
async find(context) {
const { email } = context.params.query;
if (email) {
context.params.query = {
email: email
};
// Use parameterized filtering via Feathersjs query validation
context.params.sequelize = {
where: {
email: email
}
};
}
return context;
}
}
});
// Safe Knex usage with parameterized conditions
async function getUserByEmail(email) {
const result = await knex('users')
.where('email', '=', knex.raw('?', [email]))
.limit(1);
return result[0];
}
Enforce strict schema validation in Feathersjs hooks to prevent injection through query operators. Use libraries such as ajv or Feathersjs hooks validation to ensure that operators like $in or $like receive only expected types and values:
const { iff, isProvider } = require('feathers-hooks-common');
const { disallowed } = require('feathers-query-filters');
function validateQuery() {
return (context) => {
const query = context.params.query || {};
if (query.$in) {
throw new Error('Invalid query operator');
}
if (query.$like && typeof query.$like !== 'string') {
throw new Error('Invalid $like value');
}
return context;
};
}
app.service('todos').hooks({
before: {
all: [iff(isProvider('external'), validateQuery())]
}
});
Restrict Cockroachdb user permissions to the minimum required for the application. Create a dedicated database role with read/write access only to necessary tables and explicitly deny access to system catalogs and procedural extensions unless required:
-- Cockroachdb SQL example for least-privilege setup
CREATE ROLE feathers_app WITH LOGIN PASSWORD 'secure_password';
GRANT SELECT, INSERT, UPDATE, DELETE ON TABLE users, orders TO feathers_app;
REVOKE ALL ON SCHEMA crdb_internal FROM feathers_app;
REVOKE EXECUTE ON ALL FUNCTIONS IN SCHEMA crdb_internal FROM feathers_app;
Disable unused extensions and external network capabilities within the Cockroachdb cluster configuration. Avoid enabling features such as crdb_internal or external network functions unless explicitly required and properly isolated:
-- Example to disable external access (administrative operation)
ALTER DATABASE app_db SET CLUSTER SETTING kv.experimental_enable_unstructured_data = false;
Leverage middleBrick scans to continuously monitor your API endpoints and detect risky patterns in query construction or exposed metadata. With the Pro plan, you can enable continuous monitoring and CI/CD integration to fail builds if insecure database interaction patterns are detected in your OpenAPI specifications.