critical · 10CVE-2026-54350Jun 26, 2026

CVE-2026-54350: @budibase/server Anonymous NoSQL Operator Injection via Query Templates

Rohit Hatagale
AI Security Researcher, SecureLayer7

Any anonymous visitor of a published Budibase app can read or overwrite every document in the backing database by injecting MongoDB operators through an unescaped query parameter, with no login…

Package@budibase/server
Ecosystemnpm
Affected< 3.39.12
Fixed in3.39.12
CVE-2026-54350: @budibase/server Anonymous NoSQL Operator Injection via Query Templates

The problem

Budibase's enrichContext function substitutes user-supplied parameter values directly into the raw JSON body of a query template, then calls JSON.parse on the result. The input validator only blocks Handlebars markers ({{, }}) and ignores JSON metacharacters like ", \, and }.

Any query with its role set to PUBLIC is reachable at POST /api/v2/queries/:queryId with no session and no CSRF check, only a public x-budibase-app-id header. This is the default setup for public-facing Budibase forms. SQL datasources (Postgres, MySQL, MSSQL, Oracle, MariaDB) are not affected because they use bind-parameterized interpolation.

Proof of concept

A working proof-of-concept for CVE-2026-54350 in @budibase/server, with the exact payload below.

http
POST /api/v2/queries/<read-queryId> HTTP/1.1
Host: <budibase-host>
x-budibase-app-id: <published-appId>
Content-Type: application/json

{"parameters":{"name":"x\",\"name\":{\"$exists\":true},\"$comment\":\"audit"}}

The template body is { "name": "{{ name }}" }. After substitution, the string becomes { "name": "x","name":{"$exists":true},"$comment":"audit" }. JSON.parse picks the last duplicate key, so the effective filter is { name: { $exists: true } }, which matches every document.

For updateMany, the same injection widens the filter to the full collection, and the builder's $set body then runs against every matched document with one request. The patch in 3.39.12 adds proper JSON-string escaping of parameter values inside enrichContext before template substitution, and expands validateQueryInputs to reject values containing JSON metacharacters.

Root cause: CWE-943 (Improper Neutralization of Special Elements in Data Query Logic) and CWE-89.

The fix

Upgrade @budibase/server to **3.39.12** or later. After upgrading, rotate any credentials that may have been exposed: user passwords, API tokens, MFA secrets, and database service credentials. As a defense-in-depth measure, avoid setting non-SQL queries to the PUBLIC role unless strictly necessary, and restrict network-layer access to /api/v2/queries/ where possible.

Reported by Jan Kahmen (turingpoint).

References: [1][2]

Related research