Budibase's outbound fetch flow resolves hostnames twice — once during blacklist validation and again when node-fetch creates the actual socket — allowing any authenticated user with automation permissions to reach internal services by returning a public IP during validation and a private IP during the real connection. With a CVSS of 8.5, a changed scope, and a non-blind primitive (automation output includes the full upstream response body), this is directly weaponizable against cloud metadata endpoints at 169.254.169.254 to exfiltrate temporary IAM credentials on deployments without IMDSv2 enforcement. The affected surface spans all outbound automation steps including webhooks, Slack/Discord integrations, and Budibase's own AI extract feature, making any self-hosted or cloud Budibase deployment with broad automation access a high-priority remediation target. Patch to @budibase/backend-core ≥ 3.39.9 immediately; if patching is delayed, restrict automation permissions to fully trusted accounts and enforce IMDSv2 on all cloud hosts running Budibase.
What is the risk?
HIGH risk for self-hosted Budibase deployments on cloud infrastructure without IMDSv2 enforcement. The CVSS 8.5 score reflects network-accessible exploitation with low privilege requirements and a changed scope — any authenticated automation user can pivot to internal infrastructure. With 107 prior CVEs in the same package and an OpenSSF score of 6.6/10, the security posture of this package warrants elevated scrutiny. EPSS data is not yet available given the recent publication date, but the existence of a working PoC using publicly available DNS rebinding infrastructure (rbndr.us) lowers the exploitation bar significantly — this is reproducible by any attacker who understands the DNS rebinding concept, with no custom tooling required.
How does the attack unfold?
What systems are affected?
| Package | Ecosystem | Vulnerable Range | Patched |
|---|---|---|---|
| n8n | npm | < 3.39.9 | 3.39.9 |
Do you use n8n? You're affected.
How severe is it?
What is the attack surface?
What should I do?
6 steps-
Patch: Upgrade @budibase/backend-core to ≥ 3.39.9 immediately.
-
Cloud hardening: Enforce IMDSv2 on all cloud instances running Budibase to prevent credential extraction from 169.254.169.254.
-
Least privilege: Treat 'automation permissions' as an admin-equivalent role until patched — restrict to fully trusted personnel.
-
Network segmentation: Ensure the Budibase host process cannot reach RFC1918 ranges, loopback, or VPC-internal services at the network layer, regardless of application-layer controls.
-
Detection: Alert on outbound connections from the Budibase host to 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, 127.0.0.0/8, and 169.254.0.0/16 ranges; monitor DNS queries for known rebinding services (*.rbndr.us and equivalents).
-
Architectural fix reference: The upstream fix pins the resolved IPs from validation to the subsequent socket connection, preventing the second independent lookup — verify this pattern is applied if backporting.
How is it classified?
Which compliance frameworks are affected?
This CVE is relevant to:
Frequently Asked Questions
What is CVE-2026-54353?
Budibase's outbound fetch flow resolves hostnames twice — once during blacklist validation and again when node-fetch creates the actual socket — allowing any authenticated user with automation permissions to reach internal services by returning a public IP during validation and a private IP during the real connection. With a CVSS of 8.5, a changed scope, and a non-blind primitive (automation output includes the full upstream response body), this is directly weaponizable against cloud metadata endpoints at 169.254.169.254 to exfiltrate temporary IAM credentials on deployments without IMDSv2 enforcement. The affected surface spans all outbound automation steps including webhooks, Slack/Discord integrations, and Budibase's own AI extract feature, making any self-hosted or cloud Budibase deployment with broad automation access a high-priority remediation target. Patch to @budibase/backend-core ≥ 3.39.9 immediately; if patching is delayed, restrict automation permissions to fully trusted accounts and enforce IMDSv2 on all cloud hosts running Budibase.
Is CVE-2026-54353 actively exploited?
No confirmed active exploitation of CVE-2026-54353 has been reported, but organizations should still patch proactively.
How to fix CVE-2026-54353?
1. Patch: Upgrade @budibase/backend-core to ≥ 3.39.9 immediately. 2. Cloud hardening: Enforce IMDSv2 on all cloud instances running Budibase to prevent credential extraction from 169.254.169.254. 3. Least privilege: Treat 'automation permissions' as an admin-equivalent role until patched — restrict to fully trusted personnel. 4. Network segmentation: Ensure the Budibase host process cannot reach RFC1918 ranges, loopback, or VPC-internal services at the network layer, regardless of application-layer controls. 5. Detection: Alert on outbound connections from the Budibase host to 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, 127.0.0.0/8, and 169.254.0.0/16 ranges; monitor DNS queries for known rebinding services (*.rbndr.us and equivalents). 6. Architectural fix reference: The upstream fix pins the resolved IPs from validation to the subsequent socket connection, preventing the second independent lookup — verify this pattern is applied if backporting.
What systems are affected by CVE-2026-54353?
This vulnerability affects the following AI/ML architecture patterns: AI agent automation frameworks using Budibase as orchestration layer, low-code AI orchestration platforms with outbound webhook steps, cloud-deployed AI tool stacks without IMDSv2 enforcement, multi-tenant AI SaaS deployments with shared internal infrastructure.
What is the CVSS score for CVE-2026-54353?
CVE-2026-54353 has a CVSS v3.1 base score of 8.5 (HIGH).
What is the AI security impact?
Affected AI Architectures
MITRE ATLAS Techniques
AML.T0049 Exploit Public-Facing Application AML.T0053 AI Agent Tool Invocation AML.T0055 Unsecured Credentials AML.T0075 Cloud Service Discovery AML.T0107 Exploitation for Defense Evasion Compliance Controls Affected
What are the technical details?
Original Advisory
Summary Authenticated users with automation permissions can bypass Budibase's SSRF blacklist through DNS rebinding. The outbound fetch flow validates a hostname against the blacklist before the request is sent, but the actual socket connection later performs a separate DNS lookup through node-fetch. Since the validated IPs are never pinned to the connection, an attacker-controlled hostname can return a public IP during validation and a private/internal IP during the real connection. This results in a non-blind SSRF primitive against internal services reachable from the Budibase host, including loopback, RFC1918 ranges, and cloud metadata endpoints. Details The issue comes from the outbound fetch validation flow resolving DNS twice: During blacklist validation Again during the real socket connection The first lookup result is discarded after validation, so the second lookup is free to resolve to a different IP. This creates a classic TOCTOU DNS rebinding issue. Affected flow in: packages/backend-core/src/utils/outboundFetch.ts ``` async function throwIfUnsafe(url: string): Promise<void> { const parsed = parseUrl(url) if (await isBlacklisted(parsed.hostname)) { throw new Error("URL is blocked or could not be resolved safely.") } } for (let redirects = 0; redirects <= MAX_REDIRECTS; redirects++) { await throwIfUnsafe(nextUrl) const response = await fetchFn(nextUrl, nextRequest) // ... } ``` fetchFn uses plain node-fetch with no custom http.Agent / https.Agent, so the underlying socket performs its own independent dns.lookup after validation completes. The same pattern also exists in: packages/server/src/automations/steps/utils.ts ``` await throwIfBlacklisted(nextUrl) const response = await fetch(nextUrl, nextRequest) ``` The blacklist implementation resolves hostnames but only returns a boolean: packages/backend-core/src/blacklist/blacklist.ts ``` async function lookup(address: string): Promise<string[]> { address = parseAddress(address) const addresses = await performLookup(address, { all: true }) return addresses.map(addr => addr.address) } export async function isBlacklisted(address: string): Promise<boolean> { // ... if (!net.isIP(address)) { try { ips = await lookup(address) } catch (e) { /* ... */ } } else { ips = [address] } return ips.some(ip => blackList!.check(ip, getIpVersion(ip))) } ``` The resolved IPs are discarded, so callers cannot pin the later socket connection to the validated addresses. An attacker controlling authoritative DNS for a hostname can therefore return: a public IP during validation a private/internal IP during the actual connection Anything routing through these helpers inherits the issue, including: outgoing webhook Slack Discord Make Zapier n8n AI extract object-store fetches Several of these steps return upstream response content directly into automation output, which makes the SSRF non-blind. PoC Tested locally against a self-hosted build from master. No Budibase-operated infrastructure was touched. Run Budibase locally. Start a harmless local HTTP listener: python3 -m http.server 8080 --bind 127.0.0.1 Use a rebinding hostname such as: 7f000001.cb007264.rbndr.us which rotates between: 127.0.0.1 203.0.113.100 Steps to reproduce: Log into Budibase with automation permissions. Create an automation using the Outgoing Webhook step. Set the URL to: http://<rebinding-host>:8080/ Trigger the automation. Observed result: The blacklist validation resolves the hostname to the public IP and allows the request. node-fetch performs a second DNS lookup during socket creation. The second lookup resolves to 127.0.0.1. The TCP connection lands on the local service. The local server response body appears directly in the automation output. Impact This produces a non-blind read-SSRF primitive against anything reachable from the Budibase host process, including: loopback services (127.0.0.1) RFC1918 ranges internal Kubernetes/VPC services cloud metadata endpoints (169.254.169.254) On cloud deployments without IMDSv2 enforcement, this may expose temporary IAM credentials via: /latest/meta-data/iam/security-credentials/<role> On multi-tenant hosted deployments, this may also create potential cross-tenant access paths through shared internal infrastructure.
Exploitation Scenario
An attacker with a standard Budibase account holding automation permissions registers a domain and configures its authoritative DNS to alternate between a public IP (e.g., 203.0.113.100) and the target internal IP (e.g., 169.254.169.254 for cloud metadata). They create a Budibase automation with an Outgoing Webhook step targeting their rebinding domain on port 80. When triggered, throwIfUnsafe() resolves the hostname — DNS returns the public IP, the blacklist check passes, and the resolved addresses are discarded. Milliseconds later, node-fetch performs its own independent DNS lookup during socket creation; the attacker's DNS now returns 169.254.169.254. The TCP connection lands on the AWS metadata service, and the response body — including IAM role credentials at /latest/meta-data/iam/security-credentials/<role> — appears directly in the automation output and is visible to the attacker, enabling lateral movement via stolen temporary credentials.
Weaknesses (CWE)
CWE-367 Time-of-check Time-of-use (TOCTOU) Race Condition
Primary
CWE-918 Server-Side Request Forgery (SSRF)
Primary
CWE-367 — Time-of-check Time-of-use (TOCTOU) Race Condition: The product checks the state of a resource before using that resource, but the resource's state can change between the check and the use in a way that invalidates the results of the check.
- [Implementation] The most basic advice for TOCTOU vulnerabilities is to not perform a check before the use. This does not resolve the underlying issue of the execution of a function on a resource whose state and identity cannot be assured, but it does help to limit the false sense of security given by the check.
- [Implementation] When the file being altered is owned by the current user and group, set the effective gid and uid to that of the current user and group when executing this statement.
Source: MITRE CWE corpus.
CVSS Vector
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:L/A:N References
Timeline
Related Vulnerabilities
CVE-2026-33663 10.0 n8n: member role steals plaintext HTTP credentials
Same package: n8n CVE-2026-54309 10.0 n8n: MCP browser auth bypass allows full browser takeover
Same package: n8n CVE-2026-21858 10.0 n8n: Input Validation flaw enables exploitation
Same package: n8n CVE-2026-33660 10.0 TensorFlow: type confusion NPD in tensor conversion
Same package: n8n CVE-2025-68668 9.9 n8n: Protection Bypass circumvents security controls
Same package: n8n