flawopen.com/Teardowns/cve-2026-105699-langflow-mcp-cross-project-file-disclosure
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एक होटल की कल्पना करें जो आपका चाबी कार्ड जाँचता है, फिर केवल सामान का टैग बताने पर किसी भी कमरे का बैग दे देता है। कार्ड होटल में प्रवेश का प्रमाण है, दूसरे अतिथि के बैग का स्वामित्व नहीं। फ़ाइल खोलने से पहले Langflow के MCP रीड को मालिक और प्रोजेक्ट की जाँच करनी चाहिए।[1]
इस पेज के मुख्य शब्द
Model Context Protocol (MCP)- वह प्रोटोकॉल जिससे AI ऐप सर्वर से टूल और संसाधन माँगता है। सर्वर को हर अनुरोधित ऑब्जेक्ट की अनुमति अलग से जाँचनी होती है।[1]
प्रोजेक्ट-सीमित MCP एंडपॉइंट- किसी एक प्रोजेक्ट से जुड़ा Langflow MCP कनेक्शन। इस एंडपॉइंट तक पहुँच सभी प्रोजेक्ट की फ़ाइलों की अनुमति नहीं देती।[1]
resources/read- MCP क्रिया जो सर्वर से URI द्वारा पहचाना गया संसाधन लौटाने को कहती है।[1]
फ्रेमवर्क मैपिंग
- इस गाइड में बताई गई कमजोरी के लिए 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]
हमले का चरण-दर-चरण प्रवाह
उपयोगकर्ता अपने प्रोजेक्ट MCP एंडपॉइंट पर प्रमाणित होता है
हमलावर के पास Langflow खाता और कम-से-कम एक प्रोजेक्ट MCP कनेक्शन की पहुँच होनी चाहिए। यह दोष लॉगिन को बायपास नहीं करता।[1]
क्लाइंट संसाधन URI माँगता है
MCP resources/read अनुरोध में URI होता है जिसके अंतिम पथ हिस्से फ़्लो namespace और फ़ाइल बताते हैं।[1]
स्टोरेज namespace से फ़ाइल पढ़ता है
storage_service.get_file() ने बताए गए namespace की फ़ाइल लौटाई। स्टोरेज के पास उपयोगकर्ता स्वामित्व संदर्भ नहीं था।[1]
सोर्स कोड: कमज़ोर बनाम सुरक्षित कार्यान्वयन
ये दस्तावेज़ित कोड मार्ग के केंद्रित 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,
)
इंजीनियरिंग और सिस्टम सुरक्षा चेकलिस्ट
- ✓Langflow को 1.9.1 या बाद के संस्करण में अपडेट करें और केवल स्रोत शाखा नहीं, तैनात पैकेज तथा कंटेनर इमेज सत्यापित करें।[5]
- ✓स्टोरेज कॉल से पहले हर
resources/readURI को प्रमाणित उपयोगकर्ता और MCP कनेक्शन के प्रोजेक्ट के आधार पर अधिकृत करें।[1], [3] - ✓पहचानकर्ता को डेटाबेस ऑब्जेक्ट में बदलें; उपयोगकर्ता स्वामित्व और प्रोजेक्ट-सीमित एंडपॉइंट में प्रोजेक्ट सदस्यता दोनों आवश्यक हों।[1], [3]
- ✓क्लाइंट से मनमाने स्टोरेज पथ या डाउनलोड URI लेने के बजाय सर्वर-निर्मित अपारदर्शी resource ID अपनाएँ।[1], [3]
- ✓डिकोड करने के बाद फ़ाइल नाम जाँचें, separator और traversal अंश रोकें, और हर read/write/delete में canonical path containment लागू करें।[1], [3]
- ✓
resources/listतथाtools/listक्वेरी को प्रमाणित उपयोगकर्ता तक सीमित करें; ID सूचीकरण अलग जानकारी-प्रकटीकरण है जो अनुमति दोष को बढ़ा सकता है।[7] - ✓दो उपयोगकर्ताओं वाला regression test जोड़ें: एक का project MCP दूसरे के फ़्लो फ़ाइल और अन्य प्रोजेक्ट के फ़्लो को अस्वीकार करे।[1]
- ✓प्रभावित तैनाती के access log की समीक्षा करें और संभावित खुलासे का आकलन करें; advisory दोष बताती है, वास्तविक दुनिया में शोषण की पुष्टि नहीं।[7], [3]
- ✓Upstream regression
test_handle_read_resource_denies_other_users_flowबनाए रखें और project-scope case जोड़ें जो साबित करे कि मौजूदा project के बाहर caller के अपने flow को भी अस्वीकार किया जाता है।[7], [3]
स्रोत
- Langflow maintainer advisory GHSA-4hmc-cfm3-w43c
- CVE Program record CVE-2026-105699
- Upstream fix commit b8fe970
- Upstream pull request #12818 and regression coverage
- Langflow 1.9.1 release
- MITRE CWE-639 — Authorization Bypass Through User-Controlled Key
- Langflow regression tests — MCP resource authorization