Skip to main content

Boteraser | Website and Server Security Solutions

🛡️ CVE-2026-48147 — backend-core

🟡 CVSS 6.5 — Medium ✅ No Known Exploit CWE-185 NVD
6.5
CVSS Score
0 Low4 Medium7 High9 Critical10

Description

Budibase: Unanchored Regex in matchers.ts Allows CSRF Bypass via Query String Injection in Budibase Worker

Summary

The buildMatcherRegex() / matches() functions in packages/backend-core/src/middleware/matchers.ts share the same structural root cause as the recently patched CVE-2026-31816: route patterns are compiled into unanchored regular expressions and tested against ctx.request.url, which includes the full query string. The CSRF middleware in the Budibase Worker uses this matching system to decide whether to skip CSRF token validation. An unauthenticated attacker can forge state-changing cross-origin requests against any Worker API endpoint by injecting a public route pattern into the query string, causing the CSRF middleware to skip token validation entirely. This allows actions such as sending admin invites, modifying global configuration, and managing users without a valid CSRF token.

CVE-2026-31816 fixed the same unanchored-regex-on-full-URL bug in server/middleware/utils.ts but left backend-core/middleware/matchers.ts untouched.

Details

Root cause — packages/backend-core/src/middleware/matchers.ts:

```typescript

export const buildMatcherRegex = (patterns: EndpointMatcher[]): RegexMatcher[] => {

return patterns.map(pattern => {

let route = pattern.route

// replaces :param segments with /.*

const matches = route.match(PARAM_REGEX)

if (matches) {

for (let match of matches) {

const suffix = match.endsWith("/") ? "/" : ""

route = route.replace(match, "/.*" + suffix)

}

}

return { regex: new RegExp(route), method, route }

// ^ no ^ anchor, no $ anchor — matches anywhere in string

})

}

export const matches = (ctx: Ctx, options: RegexMatcher[]) => {

return options.find(({ regex, method }) => {

const urlMatch = regex.test(ctx.request.url) // full URL including query string

const methodMatch = method === "ALL" ? true

: ctx.request.method.toLowerCase() === method.toLowerCase()

return urlMatch && methodMatch

})

}

```

Two compounding bugs identical to the patched CVE:

1. new RegExp(route) — no ^ start anchor, no $ end anchor.

2. ctx.request.url — full URL string including ?query=value, not just the path.

CSRF middleware — packages/backend-core/src/middleware/csrf.ts:

```typescript

export function csrf(

opts: { noCsrfPatterns: EndpointMatcher[] } = { noCsrfPatterns: [] }

) {

const noCsrfOptions = buildMatcherRegex(opts.noCsrfPatterns)

return (async (ctx: Ctx, next: Next) => {

const found = matches(ctx, noCsrfOptions)

if (found) {

return next() // <-- CSRF check entirely skipped when pattern matches

}

// ... CSRF token validation ...

}) as Middleware

}

```

Worker registration — packages/worker/src/api/index.ts:

```typescript

const NO_CSRF_ENDPOINTS = [...PUBLIC_ENDPOINTS]

// PUBLIC_ENDPOINTS includes (among others):

// { route: "/api/global/auth/:tenantId", method: "POST" }

// { route: "/api/global/users/init", method: "POST" }

// { route: "/api/system/restored", method: "POST" }

router

.use(auth.buildCsrfMiddleware({ noCsrfPatterns: NO_CSRF_ENDPOINTS }))

```

buildMatcherRegex compiles "/api/global/auth/:tenantId" into the regex /api/global/auth/.* (via PARAM_REGEX replacing /:tenantId/.*). Since the regex is unanchored, it matches the substring "/api/global/auth/" anywhere in ctx.request.url — including inside a query string parameter on a completely different endpoint.

Triggering condition:

```

POST /api/global/users/invite?x=/api/global/auth/evil

```

  • ctx.request.url = "/api/global/users/invite?x=/api/global/auth/evil"
  • new RegExp("/api/global/auth/.*").test(ctx.request.url)true (substring found in query string)
  • ctx.request.method === "POST"true
  • matches() returns the pattern entry → CSRF skipped
  • The protected user-invite POST proceeds without any CSRF token

Additional affected middleware (same matches() call):

| Middleware | Pattern list | Security effect when bypassed |

|---|---|---|

| csrf() | NO_CSRF_ENDPOINTS | CSRF token validation skipped |

| tenancy() | NO_TENANCY_ENDPOINTS | allowNoTenant = true, bypasses tenant ID requirement |

| authenticated() | PUBLIC_ENDPOINTS | Marks endpoint as publicEndpoint = true |

The NO_TENANCY_ENDPOINTS entry { route: "/api/system", method: "ALL" } compiles to /api/system (no param replacement). Since method: "ALL" matches every HTTP verb and the pattern is unanchored, any request with ?x=/api/system/x in its URL matches, potentially bypassing tenant isolation in multi-tenant deployments.

PoC

Prerequisites: Victim user is logged into a Budibase Worker instance (e.g., https://budibase.target.com) in their browser. Attacker hosts a page at https://evil.com.

Step 1 — Verify CSRF is normally enforced:

```bash

# Without the bypass — CSRF token missing → rejected

cur

How this vulnerability can be exploited

This issue can be reached over the network, attack complexity is low, an attacker needs no privileges on the target. A user must be tricked into taking some action. The scope is unchanged, so the impact stays within the vulnerable component. Rated impact: confidentiality none, integrity high, availability none.

CVSS metrics in full

The score comes from this vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:H/A:N

  • Attack vector: Network — reachable from anywhere that can route to the service.
  • Attack complexity: Low — the attack works reliably, with no preparation.
  • Privileges required: None — an unauthenticated stranger can try it.
  • User interaction: Required — someone has to click, open or visit something.
  • Scope: Unchanged — the damage stays inside the vulnerable component.
  • Confidentiality impact: None.
  • Integrity impact: High — total loss, or loss the attacker controls.
  • Availability impact: None.

Weakness class

CVE-2026-48147 is classified as CWE-185: Incorrect Regular Expression. The product specifies a regular expression in a way that causes data to be improperly matched or compared.

Affected software

CVE-2026-48147 is recorded against 2 packages.

  • @budibase/backend-core
  • unknown

Timeline and source

Published on 12 June 2026. No public exploit is currently recorded for this entry. Record sourced from NVD.

References

github.com (Web)
nvd.nist.gov (Advisory)
github.com (Package)

Other advisories for this package

@budibase/backend-core has other advisories on record. If you are patching this one, these are worth checking on the same host:

Same weakness in other software

These advisories are the same class of weakness (CWE-185: Incorrect Regular Expression) in other software:

Details

Severity Medium
CVSS Score 6.5
CVSS Vector CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:H/A:N
CWE CWE-185
Public Exploit ✅ No
Source NVD
Published 2026-06-12
Updated 2026-08-20
Modified 2026-06-12
Fix URL N/A

Affected Packages

Software From version Fixed in
@budibase/backend-core
unknown

Similar Threats

Vulnerability Monitoring

Track new vulnerabilities in backend-core

CVE-2026-48147 is rated CVSS 6.5 Medium. BotEraser monitors your WordPress installation and notifies you when software you use appears in our vulnerability database.

Set Up Free Alerts →

No credit card required  ·  Results in minutes

ⓘ Data Notice: The information presented above has been compiled from publicly available internet sources. Boteraser aggregates this data solely for informational purposes and does not independently classify, evaluate, or endorse any findings about the vulnerabilities listed. The accuracy and completeness of this information is the sole responsibility of the original publishers. Boteraser and its operators accept no liability for any decisions made based on this data.

Browse related advisories

All advisoriesCVECVE 2026