# Budibase: SSRF via OAuth2 token endpoint URL reaches internal hosts and cloud metadata

Budibase OAuth2 fetchToken skips the SSRF blacklist, letting a builder reach CouchDB and cloud metadata and leak response bytes via validation errors.

- Payout: Research
- Severity: high
- Program: Budibase
- Found by: adrgs, aisafe-bot
- Disclosed: 2026-06-22
- CVE: CVE-2026-48153
- Write-up quality: 7/10
- Original: https://github.com/advisories/GHSA-4q6h-8p4v-67vq
- Library page: https://bugbountylibrary.com/r/ghsa%3AGHSA-4q6h-8p4v-67vq
- Tags: area:web domain:web impact:data-leak impact:internal-access impact:pii-leak kind:research platform:ghsa sev:high tech:nodejs technique:chained technique:source-review vuln:ssrf

**Target:** OAuth2 token endpoint fetch in @budibase/server (/api/oauth2/validate)
**Root cause:** fetchToken in the OAuth2 SDK POSTs to a builder-supplied URL with plain node-fetch and redirect:follow, never calling blacklist.isBlacklisted, and the Joi schema only requires a string with no scheme/host restriction.
**Steps:**
1. Authenticate as a builder and obtain a builder session cookie.
2. POST to `/api/oauth2/validate` with body `{"url":"http://127.0.0.1:5984/","clientId":"t","clientSecret":"t","method":"BODY","grantType":"client_credentials"}`; response `{"valid":false,"message":"Method Not Allowed"}` confirms CouchDB was reached.
3. POST with `"url":"http://169.254.169.254/latest/meta-data/"`; error message leaks upstream body bytes (`"Not Found" is not valid JSON`).
4. Use a public URL returning 302 to an internal target to reach paths requiring GET, e.g. `http://127.0.0.1:5984/_all_dbs`.
**How found:** Code review comparing outbound fetch paths: noticed every other fetch (rest.ts, outboundFetch.ts, outgoingWebhook.ts) consults blacklist.isBlacklisted or uses fetchWithBlacklist, while oauth2/utils.ts fetchToken uses raw fetch with redirect:follow and a permissive Joi.string() URL schema.
**Exploitation:** A builder points the OAuth2 config URL at internal services; the server fetches it and reflects upstream response fragments in the validation error. On Budibase Cloud, a 302 redirector enables GET to shared CouchDB on 127.0.0.1:5984 to enumerate other tenants' databases and read _users/app definitions/datasource credentials; on AWS, targeting the metadata IAM credentials path exfiltrates instance role credentials.
**Escalation:** Chaining the SSRF with an attacker-controlled 302 redirector converts the POST-only primitive into arbitrary GET against internal hosts, enabling cross-tenant CouchDB reads and IAM credential theft.
**Insight:** When auditing SSRF defenses, diff every outbound fetch call site against the canonical safe wrapper; secondary SDK/integration paths (OAuth token exchange, webhook testers, validation endpoints) frequently bypass the central blacklist, and validation-error reflection gives a blind-SSRF read primitive.

## Proof of concept (copied exactly from the original report)

**curl POST to /api/oauth2/validate targeting CouchDB**

```
curl -sS -b "$BUILDER_COOKIE" -X POST "$BASE/api/oauth2/validate" \
  -H "Content-Type: application/json" \
  -d '{"url":"http://127.0.0.1:5984/","clientId":"t","clientSecret":"t",
       "method":"BODY","grantType":"client_credentials"}'
```

