Skip to content

Budibase: Webhook schema endpoint authorization bypass allows unauthenticated mutation of webhook and automation schema

High severity GitHub Reviewed Published May 21, 2026 in Budibase/budibase • Updated Jun 12, 2026

Package

npm @budibase/server (npm)

Affected versions

< 3.39.0

Patched versions

3.39.0

Description

The webhook schema-building endpoint is registered under builderRoutes, but the generic authorization middleware skips authorization for all paths matching /api/webhooks/schema. As a result, an unauthenticated caller can update the body schema for a known webhook and mutate the corresponding automation trigger output schema.

Details

The route appears to be builder-only:

  • packages/server/src/api/routes/webhook.ts:5-9
5:builderRoutes
6:  .get("/api/webhooks", controller.fetch)
7:  .put("/api/webhooks", webhookValidator(), controller.save)
8:  .delete("/api/webhooks/:id/:rev", controller.destroy)
9:  .post("/api/webhooks/schema/:instance/:id", controller.buildSchema)

However, webhook endpoint detection explicitly includes schema:

  • packages/server/src/middleware/utils.ts:3-9
3:const WEBHOOK_ENDPOINTS = new RegExp(
4:  "^/api/webhooks/(trigger|schema|discord|ms-teams|slack)(/|$)"
5:)
6:
7:export function isWebhookEndpoint(ctx: UserCtx): boolean {
8:  const path = ctx.path || ctx.request.url.split("?")[0]
9:  return WEBHOOK_ENDPOINTS.test(path)

The authorization middleware bypasses all webhook endpoints before checking ctx.user or permissions:

  • packages/server/src/middleware/authorized.ts:90-99
90:  ) =>
91:  async (ctx: UserCtx, next: any) => {
92:    // webhooks don't need authentication, each webhook unique
93:    // also internal requests (between services) don't need authorized
94:    if (isWebhookEndpoint(ctx) || ctx.internal) {
95:      return next()
96:    }
97:
98:    if (!ctx.user) {
99:      return ctx.throw(401, "No user info found")

The bypassed controller writes attacker-derived schema data to the webhook and automation trigger outputs:

  • packages/server/src/api/controllers/webhook.ts:56-83
56:export async function buildSchema(
57:  ctx: Ctx<BuildWebhookSchemaRequest, BuildWebhookSchemaResponse>
58:) {
59:  await context.doInWorkspaceContext(ctx.params.instance, async () => {
60:    const db = context.getWorkspaceDB()
61:    const webhook = await db.get<Webhook>(ctx.params.id)
62:    webhook.bodySchema = toJsonSchema(ctx.request.body)
63:    // update the automation outputs
64:    if (webhook.action.type === WebhookActionType.AUTOMATION) {
65:      let automation = await db.get<Automation>(webhook.action.target)
66:      const autoOutputs = automation.definition.trigger.schema.outputs
67:      let properties = webhook.bodySchema?.properties
68:      // reset webhook outputs
69:      autoOutputs.properties = {
70:        body: autoOutputs.properties.body,
71:      }
72:      for (let prop of Object.keys(properties || {})) {
73:        if (properties?.[prop] == null) {
74:          continue
75:        }
76:        const def = properties[prop]
77:        if (typeof def === "boolean") {
78:          continue
79:        }
80:        autoOutputs.properties[prop] = {
81:          type: def.type as AutomationIOType,
82:          description: AUTOMATION_DESCRIPTION,
83:        }

The route grouping suggests builder authorization was intended, but the global webhook bypass removes it.

PoC

Non-destructive validation approach:

  1. Create a webhook-backed automation as a builder.
  2. Record the workspace ID and webhook ID.
  3. Log out or send no auth headers.
  4. Send:
POST /api/webhooks/schema/<workspaceId>/<webhookId> HTTP/1.1
content-type: application/json

{"unauth_schema_probe":"test"}
  1. Fetch the webhook as a builder and observe that bodySchema has changed.
  2. For automation-backed webhooks, inspect the automation trigger schema outputs and observe that properties were reset/updated.

Impact

An unauthenticated attacker can modify webhook schema metadata and automation trigger output schema for known webhook IDs. This can corrupt builder-visible automation definitions, alter downstream binding behavior, and disrupt webhook-backed automation workflows.

References

@mjashanks mjashanks published to Budibase/budibase May 21, 2026
Published by the National Vulnerability Database May 27, 2026
Published to the GitHub Advisory Database Jun 12, 2026
Reviewed Jun 12, 2026
Last updated Jun 12, 2026

Severity

High

CVSS overall score

This score calculates overall vulnerability severity from 0 to 10 and is based on the Common Vulnerability Scoring System (CVSS).
/ 10

CVSS v3 base metrics

Attack vector
Network
Attack complexity
Low
Privileges required
None
User interaction
None
Scope
Unchanged
Confidentiality
None
Integrity
High
Availability
None

CVSS v3 base metrics

Attack vector: More severe the more the remote (logically and physically) an attacker can be in order to exploit the vulnerability.
Attack complexity: More severe for the least complex attacks.
Privileges required: More severe if no privileges are required.
User interaction: More severe when no user interaction is required.
Scope: More severe when a scope change occurs, e.g. one vulnerable component impacts resources in components beyond its security scope.
Confidentiality: More severe when loss of data confidentiality is highest, measuring the level of data access available to an unauthorized user.
Integrity: More severe when loss of data integrity is the highest, measuring the consequence of data modification possible by an unauthorized user.
Availability: More severe when the loss of impacted component availability is highest.
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:N

EPSS score

Exploit Prediction Scoring System (EPSS)

This score estimates the probability of this vulnerability being exploited within the next 30 days. Data provided by FIRST.
(11th percentile)

Weaknesses

Missing Authorization

The product does not perform an authorization check when an actor attempts to access a resource or perform an action. Learn more on MITRE.

CVE ID

CVE-2026-48151

GHSA ID

GHSA-qhv3-wjg8-6fx6

Source code

Credits

Loading Checking history
See something to contribute? Suggest improvements for this vulnerability.