
mcp-atlassian में confluence_upload_attachment के माध्यम से पाथ ट्रैवर्सल द्वारा मनमानी फ़ाइल पढ़ने के लिए प्रूफ-ऑफ-कॉन्सेप्ट एक्सप्लॉइट, विश्लेषण और प्रजनन स्क्रिप्ट के साथ।
गंभीरता: उच्च (CVSS 8.6)
CWE: CWE-22 — पाथ ट्रैवर्सल
प्रभावित: sooperset/mcp-atlassian < 0.22.0
समाधान: 0.22.0 में
परामर्श: GHSA-p6hp-93wp-fh6p
NVD: https://nvd.nist.gov/vuln/detail/CVE-2026-77262
श्रेय: Romain Deperne
confluence_upload_attachment MCP टूल अपने file_path तर्क को बिना किसी पाथ सत्यापन के सीधे open(file_path, "rb") में पास करता है। कोई हमलावर जो टूल को आमंत्रित कर सकता है, वह सर्वर फ़ाइलसिस्टम से मनमानी फ़ाइलें पढ़ सकता है और उन्हें हमलावर-नियंत्रित Confluence एंडपॉइंट पर मल्टीपार्ट अपलोड के माध्यम से बाहर निकाल सकता है। डिफ़ॉल्ट streamable-http ट्रांसपोर्ट बिना किसी प्रमाणीकरण के से बाइंड होता है, जिससे यह बिना क्रेडेंशियल के दूरस्थ रूप से शोषणीय है।
0.0.0.0यह पहले से पैच किए गए GHSA-xjgw-4wvw-rgm4 का रीड-साइड सममित जुड़वां है — v0.17.0 फिक्स ने केवल राइट/डाउनलोड पथ को कवर किया था। अपलोड पथ असुरक्षित छोड़ दिया गया था।
mcp-atlassian को पहले ही v0.17.0 (GHSA-xjgw-4wvw-rgm4) में पाथ ट्रैवर्सल फिक्स मिल चुका था, जिसने राइट पथ — अटैचमेंट को स्थानीय डिस्क पर डाउनलोड करना — को पैच किया था। मेरी परिकल्पना: जब किसी सममित ऑपरेशन की एक दिशा पर फिक्स लागू किया जाता है, तो दूसरी दिशा अक्सर छूट जाती है।
attachments.py में open( कॉल साइट्स की समीक्षा से पता चला कि डाउनलोड पथ फ़ाइल खोलने से पहले validate_safe_path(local_path) को कॉल करता था, जबकि अपलोड पथ ऐसा नहीं करता था। दोनों दिशाओं में असंगत पाथ सत्यापन था।
टूल परिभाषा ने इसकी पुष्टि की: file_path: Annotated[str, Field(description="Absolute path to the file to upload")] बिना किसी pattern= बाधा, बिना किसी वैलिडेटर, बिना कुछ भी। फ़ील्ड को शाब्दिक रूप से बिना किसी प्रतिबंध के एक निरपेक्ष पथ स्वीकार करने के रूप में प्रलेखित किया गया है।
मैंने इसे एंड-टू-एंड पुन: प्रस्तुत किया: वास्तविक mcp-atlassian सर्वर प्रक्रिया को स्पॉन किया, इसे MCP stdio क्लाइंट (mcp.ClientSession) के साथ चलाया, इसे स्थानीय मॉक Confluence HTTP स्टब पर इंगित किया, और file_path=/etc/passwd के साथ confluence_upload_attachment को आमंत्रित किया। मॉक सर्वर ने मल्टीपार्ट बॉडी में पूर्ण /etc/passwd सामग्री लॉग की। दो पूर्ण पुनरुत्पादन रन, दोनों PoC फ़ाइलों में लॉग किए गए।
डिफ़ॉल्ट HOST=0.0.0.0 बाइंडिंग बिना किसी प्रमाणीकरण के इसे डिफ़ॉल्ट तैनाती में बिना क्रेडेंशियल के दूरस्थ रूप से शोषणीय बनाती है।
फ़ाइल: src/mcp_atlassian/confluence/attachments.py, पंक्ति 477
with open(file_path, "rb") as fp: # ← file_path हमलावर-नियंत्रित है
files = {"file": (filename, fp, content_type)}
response = self.confluence.session.post(url, files=files, ...)
टूल परिभाषा (src/mcp_atlassian/servers/confluence.py:1307):
file_path: Annotated[str, Field(description="Absolute path to the file to upload")]
# कोई pattern= नहीं, कोई वैलिडेटर नहीं, कोई validate_safe_path() नहीं
पैच किए गए डाउनलोड पथ के साथ विषमता:
# attachments.py:223 — पैच किया गया (डाउनलोड पथ)
validate_safe_path(local_path) # ← v0.17.0 में जोड़ा गया गार्ड
open(local_path, "wb")
# attachments.py:477 — कमजोर (अपलोड पथ)
open(file_path, "rb") # ← कोई गार्ड नहीं, v0.17.0 में छूट गया
GHSA-xjgw-4wvw-rgm4 के लिए v0.17.0 पैच ने राइट-साइड (अटैचमेंट को स्थानीय डिस्क पर डाउनलोड करना) पर validate_safe_path() कॉल जोड़े, लेकिन रीड-साइड (स्थानीय फ़ाइलों को Confluence पर अपलोड करना) का ऑडिट नहीं किया। check_write_access डेकोरेटर असंबंधित है — यह केवल READ_ONLY_MODE को गेट करता है।
डिफ़ॉल्ट नेटवर्क एक्सपोज़र (src/mcp_atlassian/__init__.py:151):
HOST = "0.0.0.0" # सभी इंटरफेस से बाइंड होता है
# streamable-http ट्रांसपोर्ट में कोई प्रमाणीकरण परत नहीं
Confluence API का अनुकरण करने वाले स्थानीय HTTP स्टब के विरुद्ध पूरी तरह से एंड-टू-एंड पुन: प्रस्तुत किया गया। mcp_client.py, mock_confluence.py, और poc_run1.sh देखें।
# poc_run1.sh — confluence_upload_attachment के माध्यम से /etc/passwd पढ़ता है
# 1. मॉक Confluence एंडपॉइंट शुरू करें
python mock_confluence.py &
# 2. पाथ ट्रैवर्सल पेलोड के साथ MCP टूल आमंत्रित करें
python mcp_client.py \
--tool confluence_upload_attachment \
--page-id 123456 \
--file-path /etc/passwd \
--filename passwd.txt
# → /etc/passwd सामग्री mock_confluence.py लॉग में दिखाई देती है
/etc/passwd, SSH कुंजियाँ, .env, एप्लिकेशन रहस्य)streamable-http ट्रांसपोर्ट 0.0.0.0 से बाइंड होता है, कोई प्रमाणीकरण नहीं; कोई भी नेटवर्क-सुलभ हमलावर सीधे MCP टूल आमंत्रित कर सकता है