Budibase Unrestricted Server-Side Request Forgery (SSRF) via REST Datasource Query Preview
Date: 2026-03
Affected: npm/budibase
Attack vector: ssrf
Category: vulnerability-disclosure
Severity: High
CVE: CVE-2026-33226
CWE: CWE-918
CVSS: 8.7 (CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:C/C:H/I:H/A:N)

### Summary The REST datasource query preview endpoint (`POST /api/queries/preview`) makes server-side HTTP requests to any URL supplied by the user in `fields.path` with no validation. An authenticated admin can reach internal services that are not exposed to the internet — including cloud metadata endpoints (AWS/GCP/Azure), internal databases, Kubernetes APIs, and other pods on the internal network. On GCP this leads to OAuth2 token theft with `cloud-platform` scope (full GCP access). On any deployment it enables full internal network enumeration. ### Details The vulnerable handler is in `packages/server/src/api/controllers/query.ts` (`preview()`). It reads `fields.path` from the request body and passes it directly to the REST HTTP client without any IP or hostname validation: ``` fields.path → RestClient.read({ path }) → node-fetch(path) ``` No blocklist exists for: - Loopback (`127.0.0.1`, `::1`) - RFC 1918 ranges (`10.x.x.x`, `172.16-31.x.x`, `192.168.x.x`) - Link-local / cloud metadata (`169.254.x.x`) - Internal Kubernetes DNS (`.svc.cluster.local`) The `datasourceId` field must reference an existing REST-type datasource. This is trivially obtained via `GET /api/datasources` (lists all datasources with their IDs) or created on-demand with a single POST — no base URL is required and `fields.path` overrides it entirely. ### PoC **Step 1 — Get session token** ```http POST /api/global/auth/default/login HTTP/1.1 Host: budibase.dev.com Content-Type: application/js


Mitigations:

Architectural layers (MAESTRO):