FlawOpen

flawopen.com/Teardowns/cve-2026-105699-langflow-mcp-cross-project-file-disclosure

● CVE-2026-105699 · CVSS v4 7.1 · उच्च
सुरक्षा अनुसंधान · FlawOpen

CVE-2026-105699: Langflow MCP फ़ाइल रिसाव

Langflow ने MCP कनेक्शन को प्रमाणित किया, लेकिन हर माँगी गई फ़ाइल की अनुमति नहीं जाँची। उपयोगकर्ता दूसरे के फ़्लो की फ़ाइलें पढ़ सकता था; 1.9.1 में स्वामित्व-जाँच ठीक की गई।[1], [2], [5]

CVSS वेक्टरCVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:N/VA:N/SC:N/SI:N/SA:N
💡 आसान भाषा में (ELI5)

एक होटल की कल्पना करें जो आपका चाबी कार्ड जाँचता है, फिर केवल सामान का टैग बताने पर किसी भी कमरे का बैग दे देता है। कार्ड होटल में प्रवेश का प्रमाण है, दूसरे अतिथि के बैग का स्वामित्व नहीं। फ़ाइल खोलने से पहले Langflow के MCP रीड को मालिक और प्रोजेक्ट की जाँच करनी चाहिए।[1]

इस पेज के मुख्य शब्द

Model Context Protocol (MCP)
वह प्रोटोकॉल जिससे AI ऐप सर्वर से टूल और संसाधन माँगता है। सर्वर को हर अनुरोधित ऑब्जेक्ट की अनुमति अलग से जाँचनी होती है।[1]
प्रोजेक्ट-सीमित MCP एंडपॉइंट
किसी एक प्रोजेक्ट से जुड़ा Langflow MCP कनेक्शन। इस एंडपॉइंट तक पहुँच सभी प्रोजेक्ट की फ़ाइलों की अनुमति नहीं देती।[1]
resources/read
MCP क्रिया जो सर्वर से URI द्वारा पहचाना गया संसाधन लौटाने को कहती है।[1]
ऑब्जेक्ट-स्तरीय अनुमति
जाँच कि प्रमाणित उपयोगकर्ता को माँगे गए खास रिकॉर्ड या फ़ाइल तक पहुँच है, केवल एंडपॉइंट तक नहीं।[1], [6]
CWE-639
उपयोगकर्ता-नियंत्रित कुंजी से अनुमति को बायपास करना: पहचानकर्ता बदलकर दूसरे उपयोगकर्ता का रिकॉर्ड पाया जा सकता है।[6], [2]

फ्रेमवर्क मैपिंग

  • इस गाइड में बताई गई कमजोरी के लिए CWE संदर्भ: CWE-639

मूल कारण विश्लेषण (Root Cause)

प्रभावित Langflow 1.6.8 से 1.9.0 में, प्रोजेक्ट-सीमित MCP ट्रांसपोर्ट ने कनेक्शन URL में दिए प्रोजेक्ट ID तक पहुँच को प्रमाणित किया। इसके बाद resources/read हैंडलर ने संसाधन URI से फ़्लो ID और फ़ाइल नाम निकाले और उन्हें storage_service.get_file() को दे दिया, पर यह नहीं जाँचा कि फ़्लो प्रमाणित उपयोगकर्ता या मौजूदा प्रोजेक्ट का है। स्टोरेज लेयर केवल namespace और फ़ाइल नाम से पढ़ती है; उसे Langflow के उपयोगकर्ता या प्रोजेक्ट अधिकारों की जानकारी नहीं होती। इसलिए अपने प्रोजेक्ट MCP एंडपॉइंट तक पहुँच रखने वाला खाता-धारी उपयोगकर्ता दूसरे उपयोगकर्ता के फ़्लो namespace की फ़ाइल माँग सकता था। अलग से दर्ज वैश्विक resources/list और tools/list व्यवहार पहचानकर्ता उजागर कर लक्ष्य चुनना आसान कर सकता था, पर पढ़ने के लिए सूचीकरण आवश्यक नहीं था। यह प्रमाणित उपयोगकर्ताओं के बीच गोपनीयता का उल्लंघन है, अनाम पहुँच या कोड निष्पादन नहीं। CVE रिकॉर्ड CVSS 4.0 7.1 High और CWE-639 देता है। Langflow 1.9.1 में handle_read_resource() प्रमाणित उपयोगकर्ता प्राप्त करता है और फ़्लो को Flow.user_id == current_user.id से खोजता है; प्रोजेक्ट ट्रांसपोर्ट में Flow.folder_id == project_id भी अनिवार्य है। अनधिकृत namespace को स्टोरेज से पहले अस्वीकार किया जाता है। पैच path separator और traversal क्रम भी अस्वीकार करता है, स्टोरेज के पढ़ने/लिखने/मिटाने के मार्ग पर path containment जाँचता है और वैश्विक सूचियाँ वर्तमान उपयोगकर्ता तक सीमित करता है। मेंटेनर का regression test दूसरे उपयोगकर्ता का फ़्लो पढ़ने से रोकता है।[1], [2], [3], [5]

हमले का चरण-दर-चरण प्रवाह

चरण 1

उपयोगकर्ता अपने प्रोजेक्ट MCP एंडपॉइंट पर प्रमाणित होता है

हमलावर के पास Langflow खाता और कम-से-कम एक प्रोजेक्ट MCP कनेक्शन की पहुँच होनी चाहिए। यह दोष लॉगिन को बायपास नहीं करता।[1]

चरण 2

क्लाइंट संसाधन URI माँगता है

MCP resources/read अनुरोध में URI होता है जिसके अंतिम पथ हिस्से फ़्लो namespace और फ़ाइल बताते हैं।[1]

चरण 3

कमज़ोर हैंडलर पहचानकर्ताओं पर भरोसा करता है

handle_read_resource() ने ID और नाम निकाले, पर फ़्लो को उपयोगकर्ता या एंडपॉइंट के प्रोजेक्ट से नहीं बाँधा।[1], [3]

चरण 4

स्टोरेज namespace से फ़ाइल पढ़ता है

storage_service.get_file() ने बताए गए namespace की फ़ाइल लौटाई। स्टोरेज के पास उपयोगकर्ता स्वामित्व संदर्भ नहीं था।[1]

चरण 5

उत्तर उपयोगकर्ता सीमा पार करता है

अनुरोधकर्ता को दूसरे उपयोगकर्ता के फ़्लो की फ़ाइल मिल सकती थी। वैश्विक सूचियाँ पहचानकर्ता उजागर कर सकती थीं, पर अनुमति की कमी के लिए वे आवश्यक नहीं थीं।[1], [2]

सोर्स कोड: कमज़ोर बनाम सुरक्षित कार्यान्वयन

ये दस्तावेज़ित कोड मार्ग के केंद्रित Python अंश हैं, पूरा चलने वाला ऐप नहीं। कमज़ोर मार्ग क्लाइंट द्वारा दिए namespace को पर्याप्त अधिकार मानता था। 1.9.1 का सुधार पहले प्रमाणित उपयोगकर्ता और प्रोजेक्ट MCP कनेक्शन में मौजूदा प्रोजेक्ट के दायरे में फ़्लो खोजता है; उसके बाद ही स्टोरेज पढ़ता है। पैच फ़ाइल नाम भी जाँचता है और स्टोरेज लेयर में पथ सीमा लागू करता है, ताकि दूसरे read/write/delete रास्ते जाँच को न लाँघें। अनुमति उस सेवा में रखें जिसे उपयोगकर्ता और प्रोजेक्ट का संदर्भ पता हो; स्टोरेज एडैप्टर स्वामित्व स्वयं नहीं जान सकता। इस excerpt का दायरा: वास्तविक handler user-bucket फ़ाइल को तभी अनुमति देता है जब namespace authenticated caller की अपनी user ID हो और server project-scoped न हो। यह अलग branch snippet में शामिल नहीं है; इसे मनमाने namespace तक पहुँच न समझें। Upstream regression suite में test_handle_read_resource_denies_other_users_flow है, जो cross-user read के अस्वीकार होने की पुष्टि करता है।[1], [3], [4], [7]

सोर्स अंश: mcp_utils.py — स्रोत के प्रासंगिक अंश

कमज़ोर कार्यान्वयन
# प्रभावित read path का अंश: parse किए गए IDs सीधे storage को दिए जाते थे।
content = await storage_service.get_file(
    flow_id=flow_id,
    file_name=filename,
)
सुरक्षित और सुदृढ़ फ़िक्स
# 1.9.1 की authorization boundary का source-जैसा संक्षिप्त रूप।
current_user = current_user_ctx.get()
query = select(Flow).where(
    Flow.id == namespace_id,
    Flow.user_id == current_user.id,
)
if project_id is not None:
    query = query.where(Flow.folder_id == project_id)
flow = (await session.exec(query)).first()
if flow is None:
    raise ValueError("Resource not found or access denied")
content = await storage_service.get_file(
    flow_id=namespace_id,
    file_name=filename,
)

इंजीनियरिंग और सिस्टम सुरक्षा चेकलिस्ट

स्रोत