
SonicWall Capture Labs threat research team became aware of the threat CVE-2026-27702, assessed its impact, and developed mitigation measures for this vulnerability. CVE-2026-27702, also known as Budibase Cloud View Filter Map Function RCE, is a critical remote code execution vulnerability affecting Budibase in versions prior to 3.30.4. The vulnerability allows authenticated attackers to execute arbitrary JavaScript code on the server by injecting malicious payloads through view filter values, which are passed unsanitized to eval() via the in-memory view subsystem. Classified under CWE-94 (Improper Control of Generation of Code) and CWE-95 (Improper Neutralization of Directives in Dynamically Evaluated Code) and rated CVSS 9.9 (Critical), the flaw was reported via GitHub Security Advisory GHSA-rvhr-26g4-p2r8 and independently identified by PT Security (PT-2026-21923). Affected products include Budibase versions prior to 3.30.4 running in cloud mode (where the SELF_HOSTED environment variable is empty or unset). Fixes are available in version 3.30.4. Users should upgrade immediately.
Budibase is a popular open-source low-code platform for building AI agents and internal tools with over 27,000 GitHub stars. The platform allows users to create database-backed applications with custom views that filter and aggregate table data. These views are stored as CouchDB documents containing generated JavaScript map functions that are executed server-side when the view is queried.
The root cause of CVE-2026-27702 lies in the runView function within inMemoryView.ts (Line 25). This function is responsible for executing view queries against an in-memory PouchDB instance when the application is running in cloud mode. Instead of safely processing the stored view definition, it passes the view.map string “which contains user-supplied filter values” directly to JavaScript's eval() function. The expression eval("fn = " + view.map.replace(...)) compiles and executes the stored map function string as arbitrary JavaScript code with full Node.js runtime privileges.

The vulnerable code path begins when an attacker creates a view via POST /api/views with a crafted filter value. The viewBuilder.ts module (Figure 3) constructs a map function string by interpolating user-supplied filter values directly into a JavaScript function template. The filter value is wrapped in double quotes but without escaping, allowing an attacker to break out of the string literal and inject arbitrary JavaScript expressions. When the view is subsequently queried via GET /api/views/:viewName, the server retrieves the stored map function and passes it to eval() in inMemoryView.ts:25.

The injection mechanism exploits the parseFilterExpression() function in viewBuilder.ts, which builds CouchDB map function expressions from view filter definitions. For string-typed filter values, the code wraps them in double quotes: "${filter.value}". An attacker can escape the double-quote boundary with a payload such as x" || (require("child_process").execSync("COMMAND"), true) || ", which breaks out of the comparison, executes an arbitrary Node.js child_process command, and then re-opens a string literal to maintain valid syntax.

A critical architectural detail is that the vulnerable eval() code path is only active when Budibase runs in cloud mode, when the SELF_HOSTED environment variable is empty or unset. Self-hosted instances use CouchDB's native design document views, which do not eval user data and are therefore not vulnerable to this injection. This means the vulnerability primarily affects Budibase Cloud deployments and self-hosted instances that are misconfigured to run without the SELF_HOSTED flag.

The security fix in version 3.30.4 modifies inMemoryView.ts to rebuild the map function from view.meta (the structured filter metadata) using the viewBuilder() function, rather than directly eval()'ing the stored view.map string. This eliminates the injection vector because viewBuilder() constructs the map function from controlled template literals using the structured metadata, ignoring any injected content in the stored map string.

The following conditions must be met for successful exploitation of CVE-2026-27702:
Critical Note: While this vulnerability requires authenticated access, any user with builder permissions “including free-tier accounts on Budibase Cloud” can create views and trigger the exploit. The attack complexity is low, requiring only two HTTP requests (create view + query view) to achieve full remote code execution.
The exploitation of CVE-2026-27702 involves a two-step attack chain: first creating a malicious view with an injected filter value, then querying that view to trigger the eval() execution. The payload leverages JavaScript string literal breakout to inject arbitrary Node.js code into the generated map function.
The attacker constructs a view creation request containing a filter whose value field breaks out of the double-quote string boundary in the generated map function. The injected code uses Node.js require("child_process") to execute arbitrary operating system commands. When the view is subsequently queried, inMemoryView.ts:25 passes the entire map function to eval(), executing the injected payload with full server-side privileges.

| Component | Value | Purpose |
|---|---|---|
| Create Endpoint | POST /api/views | REST API route for creating views with filter definitions |
| Trigger Endpoint | GET /api/views/:viewName | REST API route that queries the view and triggers eval() |
| Auth Header | x-budibase-api-key | Authentication via internal API key or session cookie |
| Filter Value | x" || (require(...), true) || " | String literal breakout payload injecting arbitrary JavaScript |
| require("child_process") | execSync / exec | Node.js built-in module for operating system command execution |
Step 1 — Create Malicious View: The attacker sends a POST /api/views request with a filter containing the injection payload. The server stores the view with the generated map function (containing the injected code) in the CouchDB database.
Step 2 — Trigger eval(): The attacker sends a GET /api/views/:viewName request. The server retrieves the stored view, passes the map function string to eval() in inMemoryView.ts:25, and the injected child_process.execSync() call executes the attacker's command.
Step 3 — Cleanup: The attacker optionally deletes the malicious view via DELETE /api/views/:viewName to remove forensic evidence.
The following demonstrates a live exploitation of CVE-2026-27702. The exploit creates a view with a malicious filter value that breaks out of the string literal in the generated map function. When the view is queried, the injected require("child_process").execSync() call executes arbitrary commands on the server, achieving full remote code execution with the privileges of the Node.js process.
| Activity | Description |
|---|---|
| Reconnaissance | Execution of id, whoami, hostname, uname -a to profile the target system |
| Reverse Shell | Establishing persistent shell access via netcat or bash TCP redirect |
| Credential Harvesting | Reading environment variables containing database passwords, API keys, and JWT secrets |
| Data Exfiltration | Accessing CouchDB data stores containing application data and user records |
| Lateral Movement | Leveraging stolen credentials for MinIO, Redis, and connected cloud services |
To ensure SonicWall customers are prepared for any exploitation that may occur due to this vulnerability, the following signatures have been released:
| Signature ID | Signature Name |
|---|---|
| IPS: 22007 | Budibase Cloud View Filter Map Function RCE |
The risks posed by CVE-2026-27702 can be mitigated or eliminated by:
Vulnerability reported via GitHub Security Advisory GHSA-rvhr-26g4-p2r8 and independently identified by PT Security (PT-2026-21923).
Share This Article

An Article By
An Article By
Security News
Security News