Common Weakness Enumeration

CWE-918

Allowed

Server-Side Request Forgery (SSRF)

Abstraction: Base · Status: Incomplete

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.

6217 vulnerabilities reference this CWE, most recent first.

GHSA-4Q39-2JHR-7QX8

Vulnerability from github – Published: 2026-09-02 22:14 – Updated: 2026-09-02 22:14
VLAI
Summary
Plate: SSRF with response disclosure in DOCX image embedding
Details

Summary

@platejs/docx-io can fetch remote image URLs while converting HTML to DOCX. When an application converts attacker-controlled HTML in a server-side or privileged environment, this can cause the application environment to make unintended outbound requests and include fetched image data in the generated DOCX.

Impact

Applications are affected when they use @platejs/docx-io to convert untrusted HTML that may contain remote image references, especially in server-side conversion workflows or environments with access to internal network resources.

Affected package:

  • @platejs/docx-io versions < 53.3.2

Patched versions

Upgrade to @platejs/docx-io version 53.3.2 or later.

Workarounds

If you cannot upgrade immediately, do not pass untrusted HTML with remote image URLs to DOCX export. Sanitize untrusted HTML to remove remote image references, convert trusted images to data URIs before conversion, or run conversion in an environment with restricted outbound network access.

Credits

Thanks to EQSTLab for reporting this issue.

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "npm",
        "name": "@platejs/docx-io"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "53.3.2"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-65842"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-918"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-09-02T22:14:54Z",
    "nvd_published_at": "2026-08-20T17:19:23Z",
    "severity": "HIGH"
  },
  "details": "## Summary\n\n`@platejs/docx-io` can fetch remote image URLs while converting HTML to DOCX. When an application converts attacker-controlled HTML in a server-side or privileged environment, this can cause the application environment to make unintended outbound requests and include fetched image data in the generated DOCX.\n\n## Impact\n\nApplications are affected when they use `@platejs/docx-io` to convert untrusted HTML that may contain remote image references, especially in server-side conversion workflows or environments with access to internal network resources.\n\nAffected package:\n\n- `@platejs/docx-io` versions `\u003c 53.3.2`\n\n## Patched versions\n\nUpgrade to `@platejs/docx-io` version `53.3.2` or later.\n\n## Workarounds\n\nIf you cannot upgrade immediately, do not pass untrusted HTML with remote image URLs to DOCX export. Sanitize untrusted HTML to remove remote image references, convert trusted images to data URIs before conversion, or run conversion in an environment with restricted outbound network access.\n\n## Credits\n\nThanks to EQSTLab for reporting this issue.",
  "id": "GHSA-4q39-2jhr-7qx8",
  "modified": "2026-09-02T22:14:54Z",
  "published": "2026-09-02T22:14:54Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/udecode/plate/security/advisories/GHSA-4q39-2jhr-7qx8"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-65842"
    },
    {
      "type": "WEB",
      "url": "https://github.com/udecode/plate/pull/5053"
    },
    {
      "type": "WEB",
      "url": "https://github.com/udecode/plate/commit/21aa59926f4bbd421027354823cca09c6700ed73"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/udecode/plate"
    },
    {
      "type": "WEB",
      "url": "https://github.com/udecode/plate/releases/tag/v53.3.2"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:L",
      "type": "CVSS_V3"
    }
  ],
  "summary": "Plate: SSRF with response disclosure in DOCX image embedding"
}

GHSA-4Q6H-8P4V-67VQ

Vulnerability from github – Published: 2026-06-22 22:45 – Updated: 2026-06-22 22:45
VLAI
Summary
Budibase: SSRF via OAuth2 token endpoint URL reaches internal hosts and cloud metadata
Details

Summary

fetchToken in the OAuth2 SDK makes a POST to a builder-supplied URL with plain node-fetch, skipping the blacklist.isBlacklisted check that every other outbound fetch path in the codebase uses. The Joi schema for the OAuth2 URL has no scheme or host restriction. Alice, a builder, points an OAuth2 config at http://169.254.169.254/... or http://127.0.0.1:5984/; the server connects and returns response-body fragments in the validation result.

Details

packages/server/src/sdk/workspace/oauth2/utils.ts:17-65 defines fetchToken. Near the end:

const resp = await fetch(config.url, fetchConfig)

config.url is whatever the builder stored. fetchConfig has redirect: "follow" (the default), so a public URL that returns 302 to an internal target is also reachable.

The route validation at packages/server/src/api/routes/oauth2.ts:9 accepts any string:

url: Joi.string().required(),

The controller passes the URL into fetchToken through crud.ts. The /api/oauth2/validate endpoint (builder role) is the most direct attack path: it lives on builderRoutes, takes the URL from the body, fires the fetch, and returns a validation envelope that includes the upstream error string.

Compare with every other outbound fetch in the codebase:

  • packages/server/src/integrations/rest.ts:754 calls blacklist.isBlacklisted(url) before its fetch (though it does not re-check redirects; see companion advisory for REST-redirect SSRF).
  • packages/backend-core/src/utils/outboundFetch.ts:98-100 sets redirect: "manual" and re-validates each hop.
  • packages/server/src/automations/steps/outgoingWebhook.ts routes through fetchWithBlacklist.

The default blacklist blocks 127.0.0.0/8, 169.254.0.0/16, 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16 (packages/backend-core/src/blacklist/blacklist.ts:6-16). The OAuth2 path never consults it.

Proof of Concept

Tested against Budibase 3.35.8 (built from master at f960e361).

Step 1: Alice, a builder, POSTs an OAuth2 config pointed at CouchDB on the same host as Budibase:

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"}'

Server response:

{"valid":false,"message":"Method Not Allowed"}

Budibase reached CouchDB (which rejects POST at / with 405). Without the blacklist bypass this request would be blocked at the IP check.

Step 2: Probe the cloud metadata range:

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

Server response:

{"valid":false,"message":"invalid json response body at http://169.254.169.254/latest/meta-data/ reason: Unexpected token 'N', \"Not Found\" is not valid JSON"}

The "Not Found" substring is the upstream body; the server reached the link-local metadata endpoint and leaked the first bytes of the response into the validation error.

Impact

Two concrete paths, both reachable from any builder account (free-tier signup on Budibase Cloud is enough):

  1. Cross-tenant data read on Cloud. Budibase Cloud multi-tenants on a shared CouchDB; each tenant gets its own <tenantId>_global-db and app_<id> databases on the same port 5984. The blacklist is what keeps a builder from talking to CouchDB directly. With that bypassed, Alice can GET http://127.0.0.1:5984/_all_dbs via a 302 redirector and enumerate every other tenant's databases, then read their _users, app definitions, and datasource configs (which include third-party credentials). None of this traffic goes through Budibase's tenant isolation layer, so standard app-level access controls do not apply.
  2. IAM credential exfiltration. Alice points the URL at http://169.254.169.254/latest/meta-data/iam/security-credentials/<role>/ and receives the instance role credentials in the validation error path. Those credentials carry whatever AWS permissions the Budibase instance role holds.

Self-hosted deployments face the same CouchDB/Redis/MinIO access plus any other service reachable on the host or pod network. The blacklist was explicitly added to prevent exactly this, and every other outbound fetch path uses it.

Recommended Fix

Call blacklist.isBlacklisted before the fetch and set redirect: "manual" on fetchConfig, matching the pattern in outboundFetch.ts:

import { blacklist } from "@budibase/backend-core"

async function fetchToken(config: { url: string; /* ... */ }) {
  config = await processEnvironmentVariable(config)
  if (await blacklist.isBlacklisted(config.url)) {
    throw new Error("OAuth2 token URL is blocked.")
  }
  const fetchConfig: RequestInit = {
    method: "POST",
    headers: { "Content-Type": "application/x-www-form-urlencoded" },
    body: new URLSearchParams({ grant_type: "client_credentials" }),
    redirect: "manual",
  }
  // ...
}

Alternatively, replace the fetch call with fetchWithBlacklist, which handles both checks and re-validates redirect targets.


Found by aisafe.io

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "npm",
        "name": "@budibase/server"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "3.39.0"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-48153"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-918"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-06-22T22:45:35Z",
    "nvd_published_at": "2026-05-27T18:16:27Z",
    "severity": "HIGH"
  },
  "details": "## Summary\n\n`fetchToken` in the OAuth2 SDK makes a POST to a builder-supplied URL with plain node-fetch, skipping the `blacklist.isBlacklisted` check that every other outbound fetch path in the codebase uses. The Joi schema for the OAuth2 URL has no scheme or host restriction. Alice, a builder, points an OAuth2 config at `http://169.254.169.254/...` or `http://127.0.0.1:5984/`; the server connects and returns response-body fragments in the validation result.\n\n## Details\n\n`packages/server/src/sdk/workspace/oauth2/utils.ts:17-65` defines `fetchToken`. Near the end:\n\n```typescript\nconst resp = await fetch(config.url, fetchConfig)\n```\n\n`config.url` is whatever the builder stored. `fetchConfig` has `redirect: \"follow\"` (the default), so a public URL that returns 302 to an internal target is also reachable.\n\nThe route validation at `packages/server/src/api/routes/oauth2.ts:9` accepts any string:\n\n```typescript\nurl: Joi.string().required(),\n```\n\nThe controller passes the URL into `fetchToken` through `crud.ts`. The `/api/oauth2/validate` endpoint (builder role) is the most direct attack path: it lives on `builderRoutes`, takes the URL from the body, fires the fetch, and returns a validation envelope that includes the upstream error string.\n\nCompare with every other outbound fetch in the codebase:\n\n- `packages/server/src/integrations/rest.ts:754` calls `blacklist.isBlacklisted(url)` before its fetch (though it does not re-check redirects; see companion advisory for REST-redirect SSRF).\n- `packages/backend-core/src/utils/outboundFetch.ts:98-100` sets `redirect: \"manual\"` and re-validates each hop.\n- `packages/server/src/automations/steps/outgoingWebhook.ts` routes through `fetchWithBlacklist`.\n\nThe default blacklist blocks `127.0.0.0/8`, `169.254.0.0/16`, `10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16` (`packages/backend-core/src/blacklist/blacklist.ts:6-16`). The OAuth2 path never consults it.\n\n## Proof of Concept\n\nTested against Budibase 3.35.8 (built from master at f960e361).\n\nStep 1: Alice, a builder, POSTs an OAuth2 config pointed at CouchDB on the same host as Budibase:\n\n```bash\ncurl -sS -b \"$BUILDER_COOKIE\" -X POST \"$BASE/api/oauth2/validate\" \\\n  -H \"Content-Type: application/json\" \\\n  -d \u0027{\"url\":\"http://127.0.0.1:5984/\",\"clientId\":\"t\",\"clientSecret\":\"t\",\n       \"method\":\"BODY\",\"grantType\":\"client_credentials\"}\u0027\n```\n\nServer response:\n\n```json\n{\"valid\":false,\"message\":\"Method Not Allowed\"}\n```\n\nBudibase reached CouchDB (which rejects POST at `/` with 405). Without the blacklist bypass this request would be blocked at the IP check.\n\nStep 2: Probe the cloud metadata range:\n\n```bash\ncurl -sS -b \"$BUILDER_COOKIE\" -X POST \"$BASE/api/oauth2/validate\" \\\n  -H \"Content-Type: application/json\" \\\n  -d \u0027{\"url\":\"http://169.254.169.254/latest/meta-data/\",\"clientId\":\"t\",\"clientSecret\":\"t\",\"method\":\"BODY\",\"grantType\":\"client_credentials\"}\u0027\n```\n\nServer response:\n\n```json\n{\"valid\":false,\"message\":\"invalid json response body at http://169.254.169.254/latest/meta-data/ reason: Unexpected token \u0027N\u0027, \\\"Not Found\\\" is not valid JSON\"}\n```\n\nThe `\"Not Found\"` substring is the upstream body; the server reached the link-local metadata endpoint and leaked the first bytes of the response into the validation error.\n\n## Impact\n\nTwo concrete paths, both reachable from any builder account (free-tier signup on Budibase Cloud is enough):\n\n1. **Cross-tenant data read on Cloud.** Budibase Cloud multi-tenants on a shared CouchDB; each tenant gets its own `\u003ctenantId\u003e_global-db` and `app_\u003cid\u003e` databases on the same port 5984. The blacklist is what keeps a builder from talking to CouchDB directly. With that bypassed, Alice can `GET http://127.0.0.1:5984/_all_dbs` via a 302 redirector and enumerate every other tenant\u0027s databases, then read their `_users`, app definitions, and datasource configs (which include third-party credentials). None of this traffic goes through Budibase\u0027s tenant isolation layer, so standard app-level access controls do not apply.\n2. **IAM credential exfiltration.** Alice points the URL at `http://169.254.169.254/latest/meta-data/iam/security-credentials/\u003crole\u003e/` and receives the instance role credentials in the validation error path. Those credentials carry whatever AWS permissions the Budibase instance role holds.\n\nSelf-hosted deployments face the same CouchDB/Redis/MinIO access plus any other service reachable on the host or pod network. The blacklist was explicitly added to prevent exactly this, and every other outbound fetch path uses it.\n\n## Recommended Fix\n\nCall `blacklist.isBlacklisted` before the fetch and set `redirect: \"manual\"` on `fetchConfig`, matching the pattern in `outboundFetch.ts`:\n\n```typescript\nimport { blacklist } from \"@budibase/backend-core\"\n\nasync function fetchToken(config: { url: string; /* ... */ }) {\n  config = await processEnvironmentVariable(config)\n  if (await blacklist.isBlacklisted(config.url)) {\n    throw new Error(\"OAuth2 token URL is blocked.\")\n  }\n  const fetchConfig: RequestInit = {\n    method: \"POST\",\n    headers: { \"Content-Type\": \"application/x-www-form-urlencoded\" },\n    body: new URLSearchParams({ grant_type: \"client_credentials\" }),\n    redirect: \"manual\",\n  }\n  // ...\n}\n```\n\nAlternatively, replace the `fetch` call with `fetchWithBlacklist`, which handles both checks and re-validates redirect targets.\n\n---\n*Found by [aisafe.io](https://aisafe.io)*",
  "id": "GHSA-4q6h-8p4v-67vq",
  "modified": "2026-06-22T22:45:35Z",
  "published": "2026-06-22T22:45:35Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/Budibase/budibase/security/advisories/GHSA-4q6h-8p4v-67vq"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-48153"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/Budibase/budibase"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:L/A:N",
      "type": "CVSS_V3"
    }
  ],
  "summary": "Budibase: SSRF via OAuth2 token endpoint URL reaches internal hosts and cloud metadata"
}

GHSA-4QQR-VV2Q-CMR5

Vulnerability from github – Published: 2026-06-16 21:00 – Updated: 2026-07-20 21:12
VLAI
Summary
Crawl4AI: SSRF filter bypass in Docker server via IPv6 transition forms (NAT64 / 6to4 / unspecified / v4-mapped)
Details

Summary

The Docker API server's SSRF protection (validate_webhook_url / validate_url_destination in deploy/docker/utils.py) used an explicit IPv4/IPv6 CIDR blocklist that missed several address families. An attacker could reach internal services and cloud metadata endpoints (e.g. 169.254.169.254) despite the filter by encoding an internal IPv4 address inside an IPv6 transition form, or by using the IPv6 unspecified address.

Because the Docker API is unauthenticated by default (jwt_enabled: false), no credentials are required.

Affected paths

The blocklist was applied to crawl URLs (POST /crawl, /md, /html, /screenshot, /pdf, /execute_js) and webhook URLs (/crawl/job, /llm/job). All shared the same incomplete check.

Bypasses

The following all resolve to (or route to) blocked internal addresses but were NOT caught: - IPv6 unspecified :: - NAT64 64:ff9b::a9fe:a9fe (embeds 169.254.169.254) - 6to4 2002:a9fe:a9fe:: (embeds 169.254.169.254) - IPv4-mapped ::ffff:169.254.169.254 - IPv4-compatible ::a9fe:a9fe

The error message also echoed the resolved internal IP, acting as a minor DNS/oracle leak.

Impact

Server-Side Request Forgery: an unauthenticated attacker can make the server fetch internal-network URLs and cloud instance-metadata endpoints, potentially exposing internal services and cloud credentials.

Fix

The blocklist is replaced by a single rule: reject any resolved IP where not ip.is_global, evaluated on the address AND every embedded IPv4 transition form (v4-mapped, NAT64 64:ff9b::/96, 6to4 2002::/16, v4-compat ::/96). Error messages are now opaque and no longer echo the resolved IP.

Workarounds

  • Upgrade to the patched version.
  • Enable authentication (CRAWL4AI_API_TOKEN).
  • Restrict the container's outbound network access (egress firewall / no metadata route).

Credits

Internal security audit (Crawl4AI maintainers).

Show details on source website

{
  "affected": [
    {
      "database_specific": {
        "last_known_affected_version_range": "\u003c= 0.8.7"
      },
      "package": {
        "ecosystem": "PyPI",
        "name": "crawl4ai"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "0.8.8"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-53754"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-918"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-06-16T21:00:04Z",
    "nvd_published_at": "2026-06-23T19:17:07Z",
    "severity": "HIGH"
  },
  "details": "### Summary\n\nThe Docker API server\u0027s SSRF protection (`validate_webhook_url` / `validate_url_destination` in `deploy/docker/utils.py`) used an explicit IPv4/IPv6 CIDR blocklist that missed several address families. An attacker could reach internal services and cloud metadata endpoints (e.g. `169.254.169.254`) despite the filter by encoding an internal IPv4 address inside an IPv6 transition form, or by using the IPv6 unspecified address.\n\nBecause the Docker API is unauthenticated by default (`jwt_enabled: false`), no credentials are required.\n\n### Affected paths\n\nThe blocklist was applied to crawl URLs (`POST /crawl`, `/md`, `/html`, `/screenshot`, `/pdf`, `/execute_js`) and webhook URLs (`/crawl/job`, `/llm/job`). All shared the same incomplete check.\n\n### Bypasses\n\nThe following all resolve to (or route to) blocked internal addresses but were NOT caught:\n- IPv6 unspecified `::`\n- NAT64 `64:ff9b::a9fe:a9fe` (embeds `169.254.169.254`)\n- 6to4 `2002:a9fe:a9fe::` (embeds `169.254.169.254`)\n- IPv4-mapped `::ffff:169.254.169.254`\n- IPv4-compatible `::a9fe:a9fe`\n\nThe error message also echoed the resolved internal IP, acting as a minor DNS/oracle leak.\n\n### Impact\n\nServer-Side Request Forgery: an unauthenticated attacker can make the server fetch internal-network URLs and cloud instance-metadata endpoints, potentially exposing internal services and cloud credentials.\n\n### Fix\n\nThe blocklist is replaced by a single rule: reject any resolved IP where `not ip.is_global`, evaluated on the address AND every embedded IPv4 transition form (v4-mapped, NAT64 `64:ff9b::/96`, 6to4 `2002::/16`, v4-compat `::/96`). Error messages are now opaque and no longer echo the resolved IP.\n\n### Workarounds\n\n- Upgrade to the patched version.\n- Enable authentication (`CRAWL4AI_API_TOKEN`).\n- Restrict the container\u0027s outbound network access (egress firewall / no metadata route).\n\n### Credits\n\nInternal security audit (Crawl4AI maintainers).",
  "id": "GHSA-4qqr-vv2q-cmr5",
  "modified": "2026-07-20T21:12:00Z",
  "published": "2026-06-16T21:00:04Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/unclecode/crawl4ai/security/advisories/GHSA-4qqr-vv2q-cmr5"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-53754"
    },
    {
      "type": "WEB",
      "url": "https://github.com/pypa/advisory-database/tree/main/vulns/crawl4ai/PYSEC-2026-587.yaml"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/unclecode/crawl4ai"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N",
      "type": "CVSS_V3"
    }
  ],
  "summary": "Crawl4AI: SSRF filter bypass in Docker server via IPv6 transition forms (NAT64 / 6to4 / unspecified / v4-mapped)"
}

GHSA-4R5R-P2HF-QWWW

Vulnerability from github – Published: 2026-01-22 18:30 – Updated: 2026-01-27 00:31
VLAI
Details

Server-Side Request Forgery (SSRF) vulnerability in SmartDataSoft Pool Services pool-services allows Server Side Request Forgery.This issue affects Pool Services: from n/a through <= 3.3.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2025-62741"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-918"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2026-01-22T17:15:59Z",
    "severity": "CRITICAL"
  },
  "details": "Server-Side Request Forgery (SSRF) vulnerability in SmartDataSoft Pool Services pool-services allows Server Side Request Forgery.This issue affects Pool Services: from n/a through \u003c= 3.3.",
  "id": "GHSA-4r5r-p2hf-qwww",
  "modified": "2026-01-27T00:31:10Z",
  "published": "2026-01-22T18:30:33Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2025-62741"
    },
    {
      "type": "WEB",
      "url": "https://patchstack.com/database/Wordpress/Theme/pool-services/vulnerability/wordpress-pool-services-theme-3-3-server-side-request-forgery-ssrf-vulnerability?_s_id=cve"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-4R8V-7F5Q-9MR7

Vulnerability from github – Published: 2026-09-15 21:31 – Updated: 2026-09-15 21:31
VLAI
Details

Vulnerabilities in the API of EdgeConnect SD-WAN Orchestrator could allow a remote attacker authenticated with low privileges to conduct server-side request forgery (SSRF) attacks. A successful exploit allows an attacker to enumerate information about the internal structure of the EdgeConnect SD-WAN Orchestrator host leading to potential disclosure of sensitive information beyond what is authorized by the user's existing privilege level.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2026-76680"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-918"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2026-09-15T20:17:49Z",
    "severity": "HIGH"
  },
  "details": "Vulnerabilities in the API of EdgeConnect SD-WAN Orchestrator could allow a remote attacker authenticated with low privileges to conduct server-side request forgery (SSRF) attacks. A successful exploit allows an attacker to enumerate information about the internal structure of the EdgeConnect SD-WAN Orchestrator host leading to potential disclosure of sensitive information beyond what is authorized by the user\u0027s existing privilege level.",
  "id": "GHSA-4r8v-7f5q-9mr7",
  "modified": "2026-09-15T21:31:35Z",
  "published": "2026-09-15T21:31:35Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-76680"
    },
    {
      "type": "WEB",
      "url": "https://support.hpe.com/hpesc/public/docDisplay?docId=hpesbnw05135en_us\u0026docLocale=en_US"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:L/A:N",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-4RHC-Q92G-RM98

Vulnerability from github – Published: 2025-01-15 18:30 – Updated: 2025-01-15 18:30
VLAI
Details

A vulnerability classified as problematic has been found in wuzhicms 4.1.0. This affects the function test of the file coreframe/app/search/admin/config.php. The manipulation of the argument sphinxhost/sphinxport leads to server-side request forgery. It is possible to initiate the attack remotely. The exploit has been disclosed to the public and may be used.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2025-0480"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-918"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2025-01-15T18:15:24Z",
    "severity": "MODERATE"
  },
  "details": "A vulnerability classified as problematic has been found in wuzhicms 4.1.0. This affects the function test of the file coreframe/app/search/admin/config.php. The manipulation of the argument sphinxhost/sphinxport leads to server-side request forgery. It is possible to initiate the attack remotely. The exploit has been disclosed to the public and may be used.",
  "id": "GHSA-4rhc-q92g-rm98",
  "modified": "2025-01-15T18:30:58Z",
  "published": "2025-01-15T18:30:58Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2025-0480"
    },
    {
      "type": "WEB",
      "url": "https://github.com/wuzhicms/wuzhicms/issues/212"
    },
    {
      "type": "WEB",
      "url": "https://github.com/wuzhicms/wuzhicms/issues/212#issue-2769226216"
    },
    {
      "type": "WEB",
      "url": "https://vuldb.com/?ctiid.291915"
    },
    {
      "type": "WEB",
      "url": "https://vuldb.com/?id.291915"
    },
    {
      "type": "WEB",
      "url": "https://vuldb.com/?submit.474965"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N",
      "type": "CVSS_V3"
    },
    {
      "score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:L/VI:N/VA:N/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X",
      "type": "CVSS_V4"
    }
  ]
}

GHSA-4RJ6-VRWV-WR8M

Vulnerability from github – Published: 2026-07-24 16:11 – Updated: 2026-08-17 14:54
VLAI
Summary
Microsoft Kiota Workspace-config poisoning: out-of-repo file write + generation-time SSRF
Details

Summary

Microsoft Kiota honors a poisoned .kiota/workspace.json — the workspace configuration that Kiota's documented team workflow has developers commit to their repository — unvalidated on kiota client generate / kiota plugin generate. A repository (or pull request) containing a malicious per-client / per-plugin outputPath causes Kiota, when a developer or CI runs the documented regenerate command, to (CWE-22) write the entire generated client to an arbitrary path outside the workspace — the outputPath was not confined to the workspace root and absolute paths were accepted.

Confirmed on Kiota 1.32.4 (KIOTA_CONFIG_PREVIEW=true, the self-contained linux-x64 release binary).

Details

// .kiota/workspace.json (committed to the repo)
"clients": { "MyClient": {
   "outputPath": "/abs/path/outside/repo/pwned_client"   // -> generated client written here (CWE-22)
}}

Running kiota client generate --client-name MyClient in the repo writes MyClient.cs, P/PRequestBuilder.cs, … to the attacker-chosen outputPath (verified outside the working tree).

Note on descriptionLocation

The per-consumer descriptionLocation is intentionally fetched at generation time — this is how Kiota knows where to pull an updated description from when refreshing a client, the same way any other value in a committed lock/config file is honored. It is not treated as a vulnerability and is unchanged; only outputPath is now confined.

Impact

A malicious or compromised repository — or a malicious PR that edits .kiota/workspace.json — leads to arbitrary file write on the developer's or CI host's filesystem (overwrite source/build files, drop files in auto-loaded locations) whenever a teammate clones/pulls and runs the documented kiota client generate / kiota plugin generate to refresh the client. CWE-22.

This is a different trust boundary from the OpenAPI-description-based findings: the malicious input is the Kiota config, not the spec.

Patches

Fixed in 1.29.1 and 1.32.5 (https://github.com/microsoft/kiota/pull/7885). On loading a workspace configuration, each client/plugin outputPath is validated to be a relative subdirectory of the workspace: null/empty, rooted paths (POSIX /, UNC \\ / //, Windows drive X:\), and any .. traversal segment are rejected, and the resolved full path must stay under the workspace root. Generation aborts with an error if any consumer's outputPath escapes the workspace.

Remediation

Upgrade to Kiota 1.29.1, 1.32.5 or later. Review any committed workspace configs for outputPath values that point outside the workspace.

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "NuGet",
        "name": "Microsoft.OpenApi.Kiota"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "1.30.0"
            },
            {
              "fixed": "1.32.5"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "NuGet",
        "name": "Microsoft.OpenApi.Kiota.Builder"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "1.30.0"
            },
            {
              "fixed": "1.32.5"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "NuGet",
        "name": "Microsoft.OpenApi.Kiota"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "1.29.1"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "NuGet",
        "name": "Microsoft.OpenApi.Kiota.Builder"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "1.29.1"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-59863"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-22",
      "CWE-829",
      "CWE-918"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-07-24T16:11:24Z",
    "nvd_published_at": "2026-07-16T15:16:35Z",
    "severity": "HIGH"
  },
  "details": "### Summary\n\nMicrosoft Kiota honors a poisoned `.kiota/workspace.json` \u2014 the workspace configuration that Kiota\u0027s\ndocumented team workflow has developers commit to their repository \u2014 **unvalidated** on\n`kiota client generate` / `kiota plugin generate`. A repository (or pull request) containing a malicious\nper-client / per-plugin `outputPath` causes Kiota, when a developer or CI runs the documented regenerate\ncommand, to **(CWE-22) write the entire generated client to an arbitrary path outside the workspace** \u2014 the\n`outputPath` was not confined to the workspace root and absolute paths were accepted.\n\nConfirmed on Kiota **1.32.4** (`KIOTA_CONFIG_PREVIEW=true`, the self-contained `linux-x64` release binary).\n\n### Details\n\n```jsonc\n// .kiota/workspace.json (committed to the repo)\n\"clients\": { \"MyClient\": {\n   \"outputPath\": \"/abs/path/outside/repo/pwned_client\"   // -\u003e generated client written here (CWE-22)\n}}\n```\n\nRunning `kiota client generate --client-name MyClient` in the repo writes `MyClient.cs`,\n`P/PRequestBuilder.cs`, \u2026 to the attacker-chosen `outputPath` (verified outside the working tree).\n\n#### Note on `descriptionLocation`\n\nThe per-consumer `descriptionLocation` is intentionally fetched at generation time \u2014 this is how Kiota knows\nwhere to pull an updated description from when refreshing a client, the same way any other value in a\ncommitted lock/config file is honored. It is **not** treated as a vulnerability and is unchanged; only\n`outputPath` is now confined.\n\n### Impact\n\nA malicious or compromised repository \u2014 or a malicious PR that edits `.kiota/workspace.json` \u2014 leads to\narbitrary file write on the developer\u0027s or CI host\u0027s filesystem (overwrite source/build files, drop files in\nauto-loaded locations) whenever a teammate clones/pulls and runs the documented `kiota client generate` /\n`kiota plugin generate` to refresh the client. CWE-22.\n\nThis is a different trust boundary from the OpenAPI-description-based findings: the malicious input is the\nKiota **config**, not the spec.\n\n### Patches\n\nFixed in **1.29.1 and 1.32.5** (https://github.com/microsoft/kiota/pull/7885). On loading a workspace configuration,\neach client/plugin `outputPath` is validated to be a relative subdirectory of the workspace: null/empty,\nrooted paths (POSIX `/`, UNC `\\\\` / `//`, Windows drive `X:\\`), and any `..` traversal segment are rejected,\nand the resolved full path must stay under the workspace root. Generation aborts with an error if any\nconsumer\u0027s `outputPath` escapes the workspace.\n\n### Remediation\n\nUpgrade to Kiota **1.29.1, 1.32.5** or later. Review any committed workspace configs for `outputPath` values that\npoint outside the workspace.",
  "id": "GHSA-4rj6-vrwv-wr8m",
  "modified": "2026-08-17T14:54:18Z",
  "published": "2026-07-24T16:11:24Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/microsoft/kiota/security/advisories/GHSA-4rj6-vrwv-wr8m"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-59863"
    },
    {
      "type": "WEB",
      "url": "https://github.com/microsoft/kiota/pull/7885"
    },
    {
      "type": "WEB",
      "url": "https://github.com/microsoft/kiota/commit/4049327872db7846ace35c9003774d3e3878e4e9"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/microsoft/kiota"
    },
    {
      "type": "WEB",
      "url": "https://github.com/microsoft/kiota/releases/tag/v1.32.5"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:A/VC:L/VI:H/VA:L/SC:N/SI:N/SA:N",
      "type": "CVSS_V4"
    }
  ],
  "summary": "Microsoft Kiota Workspace-config poisoning: out-of-repo file write + generation-time SSRF"
}

GHSA-4RMJ-W58M-FVCH

Vulnerability from github – Published: 2023-03-06 21:30 – Updated: 2025-03-05 19:05
VLAI
Summary
Moodle vulnerable to Server-Side Request Forgery
Details

In Moodle, insufficient redirect handling made it possible to blindly bypass cURL blocked hosts/allowed ports restrictions, resulting in a blind SSRF risk.

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "Packagist",
        "name": "moodle/moodle"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "3.11.0-beta"
            },
            {
              "fixed": "3.11.1"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "Packagist",
        "name": "moodle/moodle"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "3.10.0-beta"
            },
            {
              "fixed": "3.10.5"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "Packagist",
        "name": "moodle/moodle"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "3.9.8"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2021-36396"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-918"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2023-03-07T20:56:50Z",
    "nvd_published_at": "2023-03-06T21:15:00Z",
    "severity": "HIGH"
  },
  "details": "In Moodle, insufficient redirect handling made it possible to blindly bypass cURL blocked hosts/allowed ports restrictions, resulting in a blind SSRF risk.",
  "id": "GHSA-4rmj-w58m-fvch",
  "modified": "2025-03-05T19:05:46Z",
  "published": "2023-03-06T21:30:18Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2021-36396"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/moodle/moodle"
    },
    {
      "type": "WEB",
      "url": "https://moodle.org/mod/forum/discuss.php?d=424802"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:N",
      "type": "CVSS_V3"
    }
  ],
  "summary": "Moodle vulnerable to Server-Side Request Forgery"
}

GHSA-4RQQ-W8V4-7P47

Vulnerability from github – Published: 2026-03-04 19:03 – Updated: 2026-04-24 20:59
VLAI
Summary
OpenClaw has incomplete IPv4 special-use SSRF blocking in web fetch guard
Details

Summary

isPrivateIpv4() in bundled SSRF guard code missed several IPv4 special-use/non-global ranges, so web_fetch could allow targets that should be blocked by SSRF policy.

Affected Packages / Versions

  • Package: openclaw (npm)
  • Latest published affected version: 2026.2.21-2 (published 2026-02-21)
  • Structured vulnerable range: <= 2026.2.21-2
  • Planned patched version (pre-set): >= 2026.2.22

Impact

Low severity. Exploitation requires network reachability to the relevant special-use ranges and a request path that reaches web_fetch URL fetching.

Technical Details

Affected releases used narrow IPv4 private-range checks that omitted multiple RFC special-use/non-global ranges. This allowed requests such as http://198.18.0.1/... through SSRF validation in affected releases. Follow-up hardening consolidates local-host/tailnet range checks so gateway/browser/tailnet paths share one canonical IP classification flow.

Fix Commit(s)

  • 71bd15bb4294d3d1b54386064d69cd0f5f731bd8
  • 44dfbd23df453e51b71ef79a148c28c53e89168c
  • 333fbb86347998526dd514290adfd5f727caa6d9
  • f14ebd743cfc73f667fae80af70043d0ab1f88bd

OpenClaw thanks @princeeismond-dot for reporting.

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "npm",
        "name": "openclaw"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "2026.2.22"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-32019"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-918"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-03-04T19:03:45Z",
    "nvd_published_at": "2026-03-19T22:16:35Z",
    "severity": "MODERATE"
  },
  "details": "### Summary\n`isPrivateIpv4()` in bundled SSRF guard code missed several IPv4 special-use/non-global ranges, so `web_fetch` could allow targets that should be blocked by SSRF policy.\n\n### Affected Packages / Versions\n- Package: `openclaw` (npm)\n- Latest published affected version: `2026.2.21-2` (published 2026-02-21)\n- Structured vulnerable range: `\u003c= 2026.2.21-2`\n- Planned patched version (pre-set): `\u003e= 2026.2.22`\n\n### Impact\nLow severity. Exploitation requires network reachability to the relevant special-use ranges and a request path that reaches `web_fetch` URL fetching.\n\n### Technical Details\nAffected releases used narrow IPv4 private-range checks that omitted multiple RFC special-use/non-global ranges. This allowed requests such as `http://198.18.0.1/...` through SSRF validation in affected releases. Follow-up hardening consolidates local-host/tailnet range checks so gateway/browser/tailnet paths share one canonical IP classification flow.\n\n### Fix Commit(s)\n- `71bd15bb4294d3d1b54386064d69cd0f5f731bd8`\n- `44dfbd23df453e51b71ef79a148c28c53e89168c`\n- `333fbb86347998526dd514290adfd5f727caa6d9`\n- `f14ebd743cfc73f667fae80af70043d0ab1f88bd`\n\nOpenClaw thanks @princeeismond-dot for reporting.",
  "id": "GHSA-4rqq-w8v4-7p47",
  "modified": "2026-04-24T20:59:05Z",
  "published": "2026-03-04T19:03:45Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/openclaw/openclaw/security/advisories/GHSA-4rqq-w8v4-7p47"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-32019"
    },
    {
      "type": "WEB",
      "url": "https://github.com/openclaw/openclaw/commit/333fbb86347998526dd514290adfd5f727caa6d9"
    },
    {
      "type": "WEB",
      "url": "https://github.com/openclaw/openclaw/commit/44dfbd23df453e51b71ef79a148c28c53e89168c"
    },
    {
      "type": "WEB",
      "url": "https://github.com/openclaw/openclaw/commit/71bd15bb4294d3d1b54386064d69cd0f5f731bd8"
    },
    {
      "type": "WEB",
      "url": "https://github.com/openclaw/openclaw/commit/f14ebd743cfc73f667fae80af70043d0ab1f88bd"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/openclaw/openclaw"
    },
    {
      "type": "WEB",
      "url": "https://www.vulncheck.com/advisories/openclaw-incomplete-ipv4-special-use-range-blocking-in-ssrf-guard"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N",
      "type": "CVSS_V3"
    },
    {
      "score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:L/VA:N/SC:N/SI:N/SA:N",
      "type": "CVSS_V4"
    }
  ],
  "summary": "OpenClaw has incomplete IPv4 special-use SSRF blocking in web fetch guard"
}

GHSA-4V28-J6Q3-5M4R

Vulnerability from github – Published: 2026-09-10 15:10 – Updated: 2026-09-10 15:10
VLAI
Summary
Open WebUI: SSRF into internal services via DNS rebinding in the Playwright web loader
Details

Summary

With the Playwright web loader enabled, Open WebUI checks the address behind a user-submitted URL before allowing the request, then handed the request to the browser to perform. The browser resolved the hostname a second time, on its own, and that answer was never checked. An attacker who controls the authoritative DNS for a hostname they submit can answer the first lookup with a public address and the second with an internal one, so the browser connects to an address the check exists to block. The connection-layer pinning that protects the other fetch paths could not apply here, because the request ran inside the browser rather than through our own HTTP clients.

Preconditions

  • WEB_LOADER_ENGINE=playwright. This is not the default, and deployments on the default web loader are unaffected.
  • A reachable Playwright browser, either local or via PLAYWRIGHT_WS_URL.
  • Any authenticated user who can submit a URL for ingestion or trigger a web search. No administrator role is required.
  • Control of the authoritative DNS for a hostname the attacker submits, serving a short TTL and alternating answers. No timing race is needed, because the two lookups are separate queries the attacker answers differently.
  • Internal services the browser process can actually reach. A deployment whose browser has no route to internal addresses loses nothing here.

Impact

An authenticated user can make the server read HTTP responses from addresses only it can reach: cloud instance metadata, loopback-bound admin APIs, and internal services on the same network. The response body is fulfilled back into the page, and the loader returns that page as the document, so the content lands in the web-search or ingestion result the user receives. On a cloud host with IMDSv1 reachable, that is enough to take instance IAM credentials.

Because the intercepted request forwards the original method and headers, a page the attacker controls can also drive requests that need a header or a non-GET method, which covers the header-gated metadata endpoints. This is a read primitive; no modification of Open WebUI data and no availability impact was demonstrated. Deployments on the default web loader are not affected at all.

Fix

Fixed in 0.11.1 by commit 27402ff21 (#28634). The interceptor no longer asks the browser to perform the request. It issues the request from the SSRF-safe HTTP client instead, which resolves the hostname once and connects to that same validated address, re-validates every redirect hop, and then fulfils the browser with the response it received. Upgrading to 0.11.1 fully resolves this, and no configuration change is required.

Root cause

Affected component: SafePlaywrightURLLoader in backend/open_webui/retrieval/web/utils.py, in both the sync and async request interceptors. Affected setup: only builds running the Playwright loader engine.

The address check and the connection were performed by two different resolvers in two different processes. Validation resolved the hostname in Python and inspected the result, then the request was handed to the browser, which resolved the name again and connected to whatever it got. Playwright's request-fetch API offers no way to pin a connection to an already-validated address, so the fix that had been applied to the other fetch paths, resolving once and connecting to that same address, could not reach this one. The check was therefore an opinion about an earlier lookup rather than a constraint on the connection that followed.

Proof of concept

Reproduced against the real implementation: the validation and interception code was taken unmodified, with only the module-level configuration constants stubbed at their documented defaults, and driven against a real Chromium instance inside an unprivileged network namespace with an authoritative DNS server answering the first lookup public and the second internal. Instance metadata and a loopback service were both reached, with the response body returned through the page. A second run showed an attacker-controlled page driving the header-gated metadata sequence to completion. The path from the HTTP endpoint to the loader was traced in source rather than driven end to end.

Credits

  • @baeseungwon1010 — identified that the address check and the browser's own resolution are two separate lookups, so the check cannot constrain where the browser connects.
Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "PyPI",
        "name": "open-webui"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0.9.6"
            },
            {
              "fixed": "0.11.1"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-87996"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-367",
      "CWE-918"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-09-10T15:10:12Z",
    "nvd_published_at": "2026-09-09T22:18:47Z",
    "severity": "HIGH"
  },
  "details": "## Summary\nWith the Playwright web loader enabled, Open WebUI checks the address behind a user-submitted URL before allowing the request, then handed the request to the browser to perform. The browser resolved the hostname a second time, on its own, and that answer was never checked. An attacker who controls the authoritative DNS for a hostname they submit can answer the first lookup with a public address and the second with an internal one, so the browser connects to an address the check exists to block. The connection-layer pinning that protects the other fetch paths could not apply here, because the request ran inside the browser rather than through our own HTTP clients.\n\n## Preconditions\n- `WEB_LOADER_ENGINE=playwright`. This is not the default, and deployments on the default web loader are unaffected.\n- A reachable Playwright browser, either local or via `PLAYWRIGHT_WS_URL`.\n- Any authenticated user who can submit a URL for ingestion or trigger a web search. No administrator role is required.\n- Control of the authoritative DNS for a hostname the attacker submits, serving a short TTL and alternating answers. No timing race is needed, because the two lookups are separate queries the attacker answers differently.\n- Internal services the browser process can actually reach. A deployment whose browser has no route to internal addresses loses nothing here.\n\n## Impact\nAn authenticated user can make the server read HTTP responses from addresses only it can reach: cloud instance metadata, loopback-bound admin APIs, and internal services on the same network. The response body is fulfilled back into the page, and the loader returns that page as the document, so the content lands in the web-search or ingestion result the user receives. On a cloud host with IMDSv1 reachable, that is enough to take instance IAM credentials.\n\nBecause the intercepted request forwards the original method and headers, a page the attacker controls can also drive requests that need a header or a non-GET method, which covers the header-gated metadata endpoints. This is a read primitive; no modification of Open WebUI data and no availability impact was demonstrated. Deployments on the default web loader are not affected at all.\n\n## Fix\nFixed in 0.11.1 by commit `27402ff21` (#28634). The interceptor no longer asks the browser to perform the request. It issues the request from the SSRF-safe HTTP client instead, which resolves the hostname once and connects to that same validated address, re-validates every redirect hop, and then fulfils the browser with the response it received. Upgrading to 0.11.1 fully resolves this, and no configuration change is required.\n\n## Root cause\nAffected component: `SafePlaywrightURLLoader` in `backend/open_webui/retrieval/web/utils.py`, in both the sync and async request interceptors. Affected setup: only builds running the Playwright loader engine.\n\nThe address check and the connection were performed by two different resolvers in two different processes. Validation resolved the hostname in Python and inspected the result, then the request was handed to the browser, which resolved the name again and connected to whatever it got. Playwright\u0027s request-fetch API offers no way to pin a connection to an already-validated address, so the fix that had been applied to the other fetch paths, resolving once and connecting to that same address, could not reach this one. The check was therefore an opinion about an earlier lookup rather than a constraint on the connection that followed.\n\n## Proof of concept\nReproduced against the real implementation: the validation and interception code was taken unmodified, with only the module-level configuration constants stubbed at their documented defaults, and driven against a real Chromium instance inside an unprivileged network namespace with an authoritative DNS server answering the first lookup public and the second internal. Instance metadata and a loopback service were both reached, with the response body returned through the page. A second run showed an attacker-controlled page driving the header-gated metadata sequence to completion. The path from the HTTP endpoint to the loader was traced in source rather than driven end to end.\n\n## Credits\n- **@baeseungwon1010** \u2014 identified that the address check and the browser\u0027s own resolution are two separate lookups, so the check cannot constrain where the browser connects.",
  "id": "GHSA-4v28-j6q3-5m4r",
  "modified": "2026-09-10T15:10:12Z",
  "published": "2026-09-10T15:10:12Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/open-webui/open-webui/security/advisories/GHSA-4v28-j6q3-5m4r"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-87996"
    },
    {
      "type": "WEB",
      "url": "https://github.com/open-webui/open-webui/pull/28634"
    },
    {
      "type": "WEB",
      "url": "https://github.com/open-webui/open-webui/commit/27402ff210bfa253445720920dfb86b15a00327b"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/open-webui/open-webui"
    },
    {
      "type": "WEB",
      "url": "https://github.com/open-webui/open-webui/releases/tag/v0.11.1"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:N/A:N",
      "type": "CVSS_V3"
    }
  ],
  "summary": "Open WebUI: SSRF into internal services via DNS rebinding in the Playwright web loader"
}

No mitigation information available for this CWE.

CAPEC-664: Server Side Request Forgery

An adversary exploits improper input validation by submitting maliciously crafted input to a target application running on a server, with the goal of forcing the server to make a request either to itself, to web services running in the server’s internal network, or to external third parties. If successful, the adversary’s request will be made with the server’s privilege level, bypassing its authentication controls. This ultimately allows the adversary to access sensitive data, execute commands on the server’s network, and make external requests with the stolen identity of the server. Server Side Request Forgery attacks differ from Cross Site Request Forgery attacks in that they target the server itself, whereas CSRF attacks exploit an insecure user authentication mechanism to perform unauthorized actions on the user's behalf.