Prototype Pollution in Chi with Cockroachdb
Prototype Pollution in Chi with Cockroachdb — how this specific combination creates or exposes the vulnerability
Prototype pollution in Chi applications that use Cockroachdb can arise when user-controlled input is merged into objects that later influence database operations, such as constructing dynamic query filters or building JSON payloads for SQL generation. In JavaScript/TypeScript, objects inherit properties from their prototypes, and if an attacker can inject keys like __proto__, constructor, or prototype, they can alter behavior for all objects sharing that prototype. When these polluted objects are used to build SQL conditions or to map request parameters to database column names, the pollution can affect how queries are constructed or interpreted.
Chi is a lightweight routing library for Deno and Node.js that does not sanitize incoming request parameters. If a route handler merges req.params or req.query into an object used to build a Cockroachdb query, prototype pollution can cause unintended property assignments. For example, consider a handler that builds a WHERE clause from a JSON payload:
const filter = { status: 'active' };
Object.assign(filter, req.query); // Vulnerable if req.query contains __proto__
const query = buildCockroachQuery(filter);
An attacker sending ?__proto__.isAdmin=true could affect object equality checks or downstream logic that relies on prototype chain resolution. While Cockroachdb itself does not execute JavaScript, the polluted object may cause unsafe query construction, such as generating column names or values that bypass intended constraints. Additionally, if the polluted object is serialized to JSON and sent to Cockroachdb via an INSERT or UPDATE, unexpected keys may map to columns, leading to schema violations or data misinterpretation.
The risk is compounded when using ORM layers or query builders that rely on object property enumeration. Prototype properties are enumerable in some legacy patterns, which may cause them to be included in query conditions inadvertently. For instance, a dynamic query builder that iterates over object keys to build WHERE key = $1 clauses could include polluted keys, resulting in queries like WHERE "__proto__" = $1, which may not match intended rows but can expose structural assumptions or error messages that aid reconnaissance.
Because middleBrick scans unauthenticated attack surfaces and tests input validation among 12 parallel checks, it can detect patterns where user input directly influences object construction before reaching Cockroachdb. Findings will highlight insecure object merging and lack of prototype pollution safeguards, providing remediation guidance to harden Chi handlers and ensure database interactions remain predictable.
Cockroachdb-Specific Remediation in Chi — concrete code fixes
To prevent prototype pollution in Chi when interacting with Cockroachdb, sanitize inputs before merging them into objects used for query construction. Use Object.create(null) to create dictionaries without a prototype, or explicitly copy only safe, known keys.
import { createRouter, type Router } from 'https://deno.land/x/chi@v1.0.0/mod.ts';
const router = createRouter();
router.get('/users', (req, res) => {
// Safe: start with a null prototype object
const filter = Object.create(null);
const allowedKeys = ['status', 'role', 'limit'];
const params = req.query;
for (const key of allowedKeys) {
if (params[key] !== undefined) {
filter[key] = params[key];
}
}
// Use filter to build Cockroachdb query safely
const query = buildCockroachQuery(filter);
res.json(query);
});
function buildCockroachQuery(filter: Record) {
const conditions = Object.entries(filter).map(([key, value]) => {
return `${key} = $${value}`;
});
return `SELECT * FROM users ${conditions.length ? 'WHERE ' + conditions.join(' AND ') : ''}`;
}
Alternatively, use a library-safe merge that excludes prototype keys:
function safeMerge(target: Record, source: Record) {
for (const key of Object.keys(source)) {
if (Object.prototype.hasOwnProperty.call(source, key)) {
target[key] = source[key];
}
}
return target;
}
const filter = safeMerge({ status: 'active' }, req.query);
When using an ORM or query builder, validate and whitelist column names to ensure that user input cannot map to internal properties. For dynamic SQL, prefer parameterized queries and explicit column selection rather than constructing identifiers from user input.
middleBrick’s OpenAPI/Swagger spec analysis can help identify endpoints that accept arbitrary objects and flag missing input validation. By combining Chi-specific hardening with continuous scanning via the Pro plan’s monitoring or CI/CD integration through the GitHub Action, teams can detect regressions before deployment.