{"id":"CVE-2026-41272","aliases":["EUVD-2026-25289","GHSA-2x8m-83vc-6wv4"],"status":"published","title":"Flowise: SSRF Protection Bypass (TOCTOU \u0026 Default Insecure)","description":"Flowise is a drag \u0026 drop user interface to build a customized large language model flow. Prior to 3.1.0, the core security wrappers (secureAxiosRequest and secureFetch) intended to prevent Server-Side Request Forgery (SSRF) contain multiple logic flaws. These flaws allow attackers to bypass the allow/deny lists via DNS Rebinding (Time-of-Check Time-of-Use) or by exploiting the default configuration which fails to enforce any deny list. This vulnerability is fixed in 3.1.0.","severity":{"version":"3.1","score":7.1,"vector":"CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:L","level":"high","assessor":"cna","from":"cve"},"epss":{"day":"2026-11-09","score":0.00258,"percentile":0.1758,"model":"v2026.06.15"},"facts":{"in_kev":false,"known_exploited":false,"public_exploit":false,"fix_available":true},"cwes":["CWE-367","CWE-918"],"published":"2026-04-16T21:51:00Z","modified":"2026-10-28T02:30:33Z","fixes":[{"ecosystem":"npm","package":"flowise","fixed_in":["3.1.0"],"sources":["ghsa","osv"]},{"ecosystem":"npm","package":"flowise-components","fixed_in":["3.1.0"],"sources":["ghsa","osv"]}],"affected":[{"source":"ghsa","ecosystem":"npm","package":"flowise","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"last_affected":"3.0.13"},{"fixed":"3.1.0"}]}]},{"source":"ghsa","ecosystem":"npm","package":"flowise-components","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"last_affected":"3.0.13"},{"fixed":"3.1.0"}]}]},{"source":"osv","ecosystem":"npm","package":"flowise","ranges":[{"type":"SEMVER","events":[{"introduced":"0"},{"fixed":"3.1.0"}]}]},{"source":"osv","ecosystem":"npm","package":"flowise-components","ranges":[{"type":"SEMVER","events":[{"introduced":"0"},{"fixed":"3.1.0"}]}]}],"products":[{"vendor":"flowiseai","product":"flowise"},{"vendor":"flowiseai","product":"flowise-components"}],"references":[{"url":"https://github.com/FlowiseAI/Flowise/security/advisories/GHSA-2x8m-83vc-6wv4","tags":["x_refsource_CONFIRM","exploit","Exploit","Vendor Advisory","advisory","web"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-41272","tags":["advisory"]},{"url":"https://github.com/advisories/GHSA-2x8m-83vc-6wv4"},{"url":"https://github.com/CVEProject/cvelistV5/tree/main/cves/2026/41xxx/CVE-2026-41272.json","tags":["advisory"]},{"url":"https://github.com/FlowiseAI/Flowise","tags":["package"]}],"sources":{"cve":[{"id":"CVE-2026-41272","title":"Flowise: SSRF Protection Bypass (TOCTOU \u0026 Default Insecure)","description":"Flowise is a drag \u0026 drop user interface to build a customized large language model flow. Prior to 3.1.0, the core security wrappers (secureAxiosRequest and secureFetch) intended to prevent Server-Side Request Forgery (SSRF) contain multiple logic flaws. These flaws allow attackers to bypass the allow/deny lists via DNS Rebinding (Time-of-Check Time-of-Use) or by exploiting the default configuration which fails to enforce any deny list. This vulnerability is fixed in 3.1.0.","status":"published","published":"2026-04-23T19:16:08.113Z","modified":"2026-04-23T20:18:56.831Z","cvss":[{"version":"3.1","score":7.1,"vector":"CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:L","level":"high","assessor":"cna"}],"cwes":["CWE-918"],"updated_at":"2026-11-02T13:41:08.498858Z"}],"euvd":[{"id":"EUVD-2026-25289","description":"Flowise is a drag \u0026 drop user interface to build a customized large language model flow. Prior to 3.1.0, the core security wrappers (secureAxiosRequest and secureFetch) intended to prevent Server-Side Request Forgery (SSRF) contain multiple logic flaws. These flaws allow attackers to bypass the allow/deny lists via DNS Rebinding (Time-of-Check Time-of-Use) or by exploiting the default configuration which fails to enforce any deny list. This vulnerability is fixed in 3.1.0.","status":"published","published":"2026-04-23T19:16:08Z","modified":"2026-04-23T20:18:56Z","cvss":[{"version":"3.1","score":7.1,"vector":"CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:L","level":"high"}],"updated_at":"2026-11-02T19:24:18.636842Z"}],"ghsa":[{"id":"GHSA-2x8m-83vc-6wv4","title":"Flowise: SSRF Protection Bypass (TOCTOU \u0026 Default Insecure)","description":"### Summary\nThe core security wrappers (secureAxiosRequest and secureFetch) intended to prevent Server-Side Request Forgery (SSRF) contain multiple logic flaws. These flaws allow attackers to bypass the allow/deny lists via DNS Rebinding (Time-of-Check Time-of-Use) or by exploiting the default configuration which fails to enforce any deny list.\n\n\n### Details\nThe flaws exist in `packages/components/src/httpSecurity.ts`.\n\nDefault Insecure: If process.env.HTTP_DENY_LIST is undefined, checkDenyList returns immediately, allowing all requests (including localhost).\n\nDNS Rebinding (TOCTOU): The function performs a DNS lookup (dns.lookup) to validate the IP, and then the HTTP client performs a new lookup to connect. An attacker can serve a valid IP first, then switch to an internal IP (e.g., `127.0.0.1`) for the second lookup.\n\n\n### PoC\nEnsure `HTTP_DENY_LIST` is unset (default behavior).\n\nUse any node utilizing secureFetch to access `http://127.0.0.1`.\n\nResult: Request succeeds.\n\n#### Scenario 2: DNS Rebinding\n\nAttacker controls domain attacker.com and a custom DNS server.\n\nConfigure DNS to return `1.1.1.1` (Safe IP) with TTL=0 for the first query.\n\nConfigure DNS to return `127.0.0.1` (Blocked IP) for subsequent queries.\n\nFlowise validates `attacker.com` -\u003e `1.1.1.1` (Allowed).\n\nFlowise fetches `attacker.com` -\u003e `127.0.0.1` (Bypass).\n\nRun the following for manual verification \n\n```ts\n// PoC for httpSecurity.ts Bypasses\nimport * as dns from 'dns/promises';\n\n// Mocking the checkDenyList logic from Flowise\nasync function checkDenyList(url: string) {\n    const deniedIPs = ['127.0.0.1', '0.0.0.0']; // Simplified deny list logic\n\n    if (!process.env.HTTP_DENY_LIST) {\n        console.log(\\\"⚠️  HTTP_DENY_LIST not set. Returning allowed.\\\");\n        return; // Vulnerability 1: Default Insecure\n    }\n\n    const { hostname } = new URL(url);\n    const { address } = await dns.lookup(hostname);\n\n    if (deniedIPs.includes(address)) {\n        throw new Error(`IP ${address} is denied`);\n    }\n    console.log(`✅ IP ${address} allowed check.`);\n}\n\nasync function runPoC() {\n    console.log(\\\"--- Test 1: Default Configuration (Unset HTTP_DENY_LIST) ---\\\");\n    // Ensure env var is unset\n    delete process.env.HTTP_DENY_LIST;\n    try {\n        await checkDenyList('http://127.0.0.1');\n        console.log(\\\"[PASS] Default config allowed localhost access.\\\");\n    } catch (e) {\n        console.log(\\\"[FAIL] Blocked:\\\", e.message);\n    }\n\n    console.log(\\\"\\\n--- Test 2: 'private' Keyword Bypass (Logic Flaw) ---\\\");\n    process.env.HTTP_DENY_LIST = 'private'; // User expects this to block localhost\n    try {\n        await checkDenyList('http://127.0.0.1');\n        // In real Flowise code, 'private' is not expanded to IPs, so it only blocks the string \\\"private\\\"\n        console.log(\\\"[PASS] 'private' keyword failed to block localhost (Mock simulation).\\\");\n    } catch (e) {\n        console.log(\\\"[FAIL] Blocked:\\\", e.message);\n    }\n}\n\nrunPoC();\n```\n\n\n### Impact\nConfidentiality: High (Access to internal services if protection is bypassed).\n\nIntegrity: Low/Medium (If internal services allow state changes via GET).\n\nAvailability: Low.","status":"published","published":"2026-04-16T21:51:00Z","modified":"2026-04-24T21:01:29Z","cvss":[{"version":"3.0","score":7.1,"vector":"CVSS:3.0/AV:N/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:L","level":"high"}],"cwes":["CWE-367","CWE-918"],"updated_at":"2026-11-02T14:39:57.650091Z"}],"nvd":[{"id":"CVE-2026-41272","description":"Flowise is a drag \u0026 drop user interface to build a customized large language model flow. Prior to 3.1.0, the core security wrappers (secureAxiosRequest and secureFetch) intended to prevent Server-Side Request Forgery (SSRF) contain multiple logic flaws. These flaws allow attackers to bypass the allow/deny lists via DNS Rebinding (Time-of-Check Time-of-Use) or by exploiting the default configuration which fails to enforce any deny list. This vulnerability is fixed in 3.1.0.","status":"published","published":"2026-04-23T20:16:15.81Z","modified":"2026-10-26T22:10:00.163Z","cvss":[{"version":"3.1","score":7.1,"vector":"CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:L","level":"high","assessor":"secondary"}],"cwes":["CWE-918"],"updated_at":"2026-11-02T14:12:15.867234Z"}],"osv":[{"id":"CVE-2026-41272","title":"Flowise: SSRF Protection Bypass (TOCTOU \u0026 Default Insecure)","description":"Flowise is a drag \u0026 drop user interface to build a customized large language model flow. Prior to 3.1.0, the core security wrappers (secureAxiosRequest and secureFetch) intended to prevent Server-Side Request Forgery (SSRF) contain multiple logic flaws. These flaws allow attackers to bypass the allow/deny lists via DNS Rebinding (Time-of-Check Time-of-Use) or by exploiting the default configuration which fails to enforce any deny list. This vulnerability is fixed in 3.1.0.","status":"published","published":"2026-04-23T19:16:08.113Z","modified":"2026-10-28T02:30:33.802952767Z","cvss":[{"version":"3.1","score":7.1,"vector":"CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:L","level":"high"}],"cwes":["CWE-918"],"updated_at":"2026-11-02T15:45:03.764807Z"},{"id":"GHSA-2x8m-83vc-6wv4","title":"Flowise: SSRF Protection Bypass (TOCTOU \u0026 Default Insecure)","description":"### Summary\nThe core security wrappers (secureAxiosRequest and secureFetch) intended to prevent Server-Side Request Forgery (SSRF) contain multiple logic flaws. These flaws allow attackers to bypass the allow/deny lists via DNS Rebinding (Time-of-Check Time-of-Use) or by exploiting the default configuration which fails to enforce any deny list.\n\n\n### Details\nThe flaws exist in `packages/components/src/httpSecurity.ts`.\n\nDefault Insecure: If process.env.HTTP_DENY_LIST is undefined, checkDenyList returns immediately, allowing all requests (including localhost).\n\nDNS Rebinding (TOCTOU): The function performs a DNS lookup (dns.lookup) to validate the IP, and then the HTTP client performs a new lookup to connect. An attacker can serve a valid IP first, then switch to an internal IP (e.g., `127.0.0.1`) for the second lookup.\n\n\n### PoC\nEnsure `HTTP_DENY_LIST` is unset (default behavior).\n\nUse any node utilizing secureFetch to access `http://127.0.0.1`.\n\nResult: Request succeeds.\n\n#### Scenario 2: DNS Rebinding\n\nAttacker controls domain attacker.com and a custom DNS server.\n\nConfigure DNS to return `1.1.1.1` (Safe IP) with TTL=0 for the first query.\n\nConfigure DNS to return `127.0.0.1` (Blocked IP) for subsequent queries.\n\nFlowise validates `attacker.com` -\u003e `1.1.1.1` (Allowed).\n\nFlowise fetches `attacker.com` -\u003e `127.0.0.1` (Bypass).\n\nRun the following for manual verification \n\n```ts\n// PoC for httpSecurity.ts Bypasses\nimport * as dns from 'dns/promises';\n\n// Mocking the checkDenyList logic from Flowise\nasync function checkDenyList(url: string) {\n    const deniedIPs = ['127.0.0.1', '0.0.0.0']; // Simplified deny list logic\n\n    if (!process.env.HTTP_DENY_LIST) {\n        console.log(\\\"⚠️  HTTP_DENY_LIST not set. Returning allowed.\\\");\n        return; // Vulnerability 1: Default Insecure\n    }\n\n    const { hostname } = new URL(url);\n    const { address } = await dns.lookup(hostname);\n\n    if (deniedIPs.includes(address)) {\n        throw new Error(`IP ${address} is denied`);\n    }\n    console.log(`✅ IP ${address} allowed check.`);\n}\n\nasync function runPoC() {\n    console.log(\\\"--- Test 1: Default Configuration (Unset HTTP_DENY_LIST) ---\\\");\n    // Ensure env var is unset\n    delete process.env.HTTP_DENY_LIST;\n    try {\n        await checkDenyList('http://127.0.0.1');\n        console.log(\\\"[PASS] Default config allowed localhost access.\\\");\n    } catch (e) {\n        console.log(\\\"[FAIL] Blocked:\\\", e.message);\n    }\n\n    console.log(\\\"\\\n--- Test 2: 'private' Keyword Bypass (Logic Flaw) ---\\\");\n    process.env.HTTP_DENY_LIST = 'private'; // User expects this to block localhost\n    try {\n        await checkDenyList('http://127.0.0.1');\n        // In real Flowise code, 'private' is not expanded to IPs, so it only blocks the string \\\"private\\\"\n        console.log(\\\"[PASS] 'private' keyword failed to block localhost (Mock simulation).\\\");\n    } catch (e) {\n        console.log(\\\"[FAIL] Blocked:\\\", e.message);\n    }\n}\n\nrunPoC();\n```\n\n\n### Impact\nConfidentiality: High (Access to internal services if protection is bypassed).\n\nIntegrity: Low/Medium (If internal services allow state changes via GET).\n\nAvailability: Low.","status":"published","published":"2026-04-16T21:51:00Z","modified":"2026-05-05T16:11:44.55857Z","cvss":[{"version":"3.0","score":7.1,"vector":"CVSS:3.0/AV:N/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:L","level":"high"}],"cwes":["CWE-367","CWE-918"],"updated_at":"2026-11-02T15:46:35.050232Z"}]}}
