Mar 12, 2026·7 min read·15 visits
An unanchored regular expression matching against full request URLs allows unauthenticated attackers to bypass Budibase middleware and access protected APIs by injecting webhook paths into query parameters.
Budibase versions 3.31.4 and earlier contain a critical authentication bypass vulnerability due to improper URL parsing in the server's authorized middleware. Attackers can bypass all authentication, authorization, and CSRF checks by appending a webhook routing pattern to the query string of any API request.
Budibase is a low-code application platform utilized for developing internal workflows and tools. The platform relies on a centralized middleware component named authorized() to enforce authentication and authorization across its server-side API endpoints. This middleware acts as the primary security boundary, verifying session tokens, validating roles, and enforcing cross-site request forgery (CSRF) protections for incoming requests.
A critical vulnerability, designated CVE-2026-31816, exists within the routing logic of this middleware. The implementation contains a flawed exclusion mechanism intended to permit unauthenticated access to webhook endpoints. The routing logic uses an unanchored regular expression to identify these webhooks, testing the pattern against the full request URL rather than the specific URL path.
Attackers can exploit this parsing discrepancy to bypass the authorized() middleware entirely. By appending a string that matches the webhook regular expression to the query parameter of any API request, an attacker forces the middleware to misclassify the request as a legitimate webhook. This misclassification results in the complete bypass of all authentication, role validation, and CSRF checks.
The root cause of CVE-2026-31816 is a case of CWE-74, specifically improper neutralization of special elements leading to an injection flaw within the routing logic. Budibase utilizes the Koa web framework for Node.js to handle HTTP requests. In Koa, the ctx.request.url property contains the full requested URL, including the path and any appended query string parameters. Conversely, the ctx.request.path property strictly contains the URL path component without the query string.
The vulnerable implementation relies on a helper function, isWebhookEndpoint(), to determine if an incoming request targets a webhook route. This function applies an unanchored regular expression, explicitly searching for the pattern /webhooks/trigger within the provided string. Crucially, the function evaluates ctx.request.url instead of ctx.request.path.
Because the regular expression lacks start-of-string (^) or end-of-string ($) anchors, it returns a positive match if the target pattern appears anywhere within the evaluated string. When a client requests a protected endpoint such as /api/v1/apps/secrets and appends ?/webhooks/trigger, the ctx.request.url variable populates with the full string /api/v1/apps/secrets?/webhooks/trigger.
The isWebhookEndpoint() function processes this combined string and successfully matches the /webhooks/trigger segment located in the query parameters. The function returns a boolean true to the authorized() middleware. The middleware then immediately invokes the next() function in the execution chain, terminating its security checks and granting access to the protected endpoint.
Analyzing the conceptual code demonstrates the exact failure point in the authorized() middleware. The middleware intercepts incoming API traffic and evaluates the request URL against the webhook exclusion function. If the function returns true, the application bypasses the standard authenticateUser() routine and proceeds to the requested route handler.
The following code snippet illustrates the vulnerable implementation of the webhook evaluation logic. The isWebhookEndpoint() function uses the standard JavaScript RegExp.test() method against the full Koa URL object.
// Vulnerable implementation
async function authorized(ctx, next) {
// Evaluates the full URL including query parameters
if (isWebhookEndpoint(ctx.request.url)) {
return next();
}
await authenticateUser(ctx);
return next();
}
function isWebhookEndpoint(url) {
// Unanchored regex match against the entire URL string
const webhookRegex = /\/webhooks\/trigger/;
return webhookRegex.test(url);
}The Budibase maintainers implemented a definitive fix in version 3.31.5 by addressing both the target variable and the regular expression structure. The patch modifies the isWebhookEndpoint() function to evaluate ctx.request.path, ensuring that query parameters are excluded from the authorization decision entirely.
Additionally, the regular expression was updated to include the start-of-string anchor (^). This guarantees that the request path must explicitly begin with the webhook route to trigger the exclusion logic, preventing trailing path injection or query parameter manipulation.
// Patched implementation
async function authorized(ctx, next) {
// Evaluates strictly the URL path, ignoring query parameters
if (isWebhookEndpoint(ctx.request.path)) {
return next();
}
await authenticateUser(ctx);
return next();
}
function isWebhookEndpoint(path) {
// Anchored regex ensures the path strictly starts with the target
const webhookRegex = /^\/api\/v1\/webhooks\/trigger/;
return webhookRegex.test(path);
}Exploiting CVE-2026-31816 requires no prior authentication, specific network positioning, or complex prerequisites. An attacker only needs network access to the Budibase API service and knowledge of the internal API routing structure. The exploitation process consists of sending a single crafted HTTP GET or POST request to the target server.
The attacker identifies a target administrative endpoint, such as /api/v1/admin/settings or /api/v1/tables/data. Under normal operating conditions, accessing these endpoints without a valid session token results in an HTTP 401 Unauthorized or 403 Forbidden response.
To bypass the middleware, the attacker modifies the request URI by appending the webhook trigger path as a query parameter. The resulting payload takes the form of GET /api/v1/admin/settings?/webhooks/trigger. Upon receiving this request, the server misinterprets the routing logic and executes the administrative function, returning the sensitive data in the HTTP response body.
The following YAML definition demonstrates a functional Nuclei detection template for identifying vulnerable Budibase instances. The template attempts to retrieve user authentication data by exploiting the routing bypass.
id: CVE-2026-31816-Detection
info:
name: Budibase Auth Bypass via Webhook Injection
severity: critical
requests:
- method: GET
path:
- "{{BaseURL}}/api/v1/auth/user?/webhooks/trigger"
matchers:
- type: status
status:
- 200The successful exploitation of CVE-2026-31816 results in a complete compromise of the Budibase platform's confidentiality and integrity controls. Attackers achieve full unauthenticated access to the underlying application data, including user records, internal application configurations, and connected database secrets. The vulnerability exposes the entirety of the internal API surface to external threat actors.
Because the bypass negates role-based access controls and CSRF protections, attackers can manipulate platform data. Threat actors can create administrative accounts, alter existing application logic, or modify database entries managed by the Budibase instance. This level of access corresponds directly to the High Confidentiality and High Integrity metrics in the CVSS v3.1 vector string.
The vulnerability requires low attack complexity and no user interaction, resulting in a base CVSS score of 9.1 (Critical). Furthermore, the flaw functions as a secondary bypass to a previously addressed vulnerability (CVE-2026-29183). This context indicates that threat actors analyzing the prior patch are highly likely to discover and exploit this related parsing error.
Given the nature of low-code platforms, Budibase instances often maintain privileged connections to production databases, internal APIs, and third-party services. Consequently, compromising the Budibase server frequently provides a pivot point for attackers to traverse deeper into the organizational network and access adjacent infrastructure.
The primary and only definitive remediation for CVE-2026-31816 is upgrading the Budibase application to version 3.31.5 or later. Administrators must pull the latest container images or update the associated npm packages, depending on the specific deployment architecture in use. Following the upgrade, a complete restart of the application cluster is necessary to ensure the patched middleware loads into memory.
In environments where immediate patching is administratively blocked, security teams can implement temporary mitigation using a Web Application Firewall (WAF) or an edge routing proxy. The WAF rule must inspect the HTTP request URI and block any traffic containing the string /webhooks/trigger within the query parameter segment.
The WAF configuration must be precise to avoid interrupting legitimate webhook traffic. Legitimate webhooks will contain /webhooks/trigger within the URL path, not the query string. Therefore, the detection logic must explicitly parse the query string parameters and drop requests that match the injected payload pattern.
Security teams should also review application access logs for indicators of compromise prior to the patch application. Specifically, log analysis should focus on unexpected requests to sensitive endpoints (such as /api/v1/users or /api/v1/secrets) that contain the string /webhooks/trigger in their request URL. Successful exploitation will register as HTTP 200 OK responses to these malformed requests.
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N| Product | Affected Versions | Fixed Version |
|---|---|---|
Budibase Budibase | <= 3.31.4 | 3.31.5 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-74 |
| CVSS Score | 9.1 |
| Attack Vector | Network |
| EPSS Score | 0.10% |
| Exploit Status | Proof of Concept Available |
| Authentication Required | None |
Improper Neutralization of Special Elements in Output Used by a Downstream Component ('Injection')