FlawOpen

flawopen.com/Teardowns/cve-2026-77244-mcp-atlassian-http-auth-bypass

● CVE-2026-77244 · CVSS 10.0[1] · अति गंभीर
सुरक्षा अनुसंधान · FlawOpen

CVE-2026-77244: mcp-atlassian में बिना प्रमाणीकरण HTTP टूल एक्सेस

CVE-2026-77244 में बिना प्रमाणीकरण वाले callers समुदाय-प्रोजेक्ट mcp-atlassian के HTTP tool handlers तक पहुँच सकते थे, जहाँ operator के environment में configured Jira या Confluence credentials इस्तेमाल हो सकते थे। मुख्य सुधार 0.22.0 में आया; SSE उपयोगकर्ताओं को अलग संबंधित transport flaw के लिए 0.23.1 या नया संस्करण चाहिए।[1], [4], [5], [6]

CVSS वेक्टरCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:N[1]
💡 आसान भाषा में (ELI5)

रिसेप्शन को स्टाफ़-केवल दरवाज़ा खोलने से पहले आगंतुक का बैज जाँचना चाहिए। पुराने प्रवाह में बैज न होने पर रिसेप्शन अपना मास्टर-की दे देता था। इस दोष में दो जाँचें अनुपस्थित थीं: HTTP अनुरोध सत्यापित उपयोगकर्ता पहचान के बिना टूल तक पहुँच सकता था और टूल operator के साझा Atlassian credentials इस्तेमाल कर सकते थे। सुधार बिना प्रमाणीकरण वाले HTTP अनुरोध रोकता है और credential fallback को स्पष्ट अनुमति पर निर्भर करता है।[1], [3]

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

MCP transport
वह चैनल जो client और server के बीच Model Context Protocol अनुरोध ले जाता है। यह CVE mcp-atlassian के HTTP transport को प्रभावित करता है; advisory के अनुसार stdio प्रभावित नहीं है।[1], [4]
Global credential fallback
अनुरोध की अपनी user identity न होने पर server environment में configured Jira या Confluence credentials का उपयोग। दूर से पहुँच योग्य HTTP में इससे anonymous अनुरोध operator के रूप में काम कर सकता है।[1], [4]
Authentication boundary
Server-side जाँच जो अनुरोध को protected tool handlers तक पहुँचने से पहले caller की पहचान तय करती है। Network reachability, non-empty token string या proxy पर अनुमानित भरोसा स्वयं पहचान सत्यापित नहीं करते।[1], [7]
CWE-287
Improper Authentication: पहुँच देने से पहले application किसी actor की बताई पहचान को पर्याप्त रूप से प्रमाणित नहीं करता।[1], [7]
CWE-303
टोकन verifier authentication को गलत तरीके से लागू करता है: वह वैधता जाँचे बिना हर non-empty token स्वीकार करता है。[1], [9]
CWE-862
HTTP अनुरोध सत्यापित user identity की आवश्यकता वाली authorization जाँच के बिना privileged tool handlers तक पहुँच सकता था।[1], [10]

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

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

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

GitHub security advisory समुदाय-प्रोजेक्ट mcp-atlassian की attack chain बताती है, Atlassian product की vulnerability नहीं। 0.22.0 से पहले HTTP middleware user identity के बिना अनुरोध को tool handlers तक जाने दे सकती थी। यदि deployment operator credentials environment variables से लेता था, तो JiraFetcher या ConfluenceFetcher global credentials पर fallback कर सकता था। Advisory यह भी बताती है कि opaque-token verifier कोई भी non-empty string स्वीकार करता था; इससे caller की वास्तविक पहचान प्रमाणित नहीं होती। सुरक्षा सीमा को request identity और credential selection दोनों सुरक्षित करने चाहिए: अनुपस्थित या unverified user को operator के privileged credentials कभी विरासत में नहीं मिलने चाहिए। 0.22.0 सुधार unauthenticated streamable-HTTP MCP POST पर HTTP 401 देता है और HTTP context में global fallback रोकता है, जब तक single-user deployment के लिए ALLOW_GLOBAL_CRED_FALLBACK=true स्पष्ट रूप से न दिया जाए। stdio व्यवहार नहीं बदलता। अलग से, GHSA-5j8j-256g-vvp5 SSE path matching flaw बताती है जो 0.23.1 में ठीक हुई; यह CVE-2026-77244 नहीं है। SSE deployment को 0.23.1 या नए में अपडेट करें और यह न मानें कि CVE का 0.22.0 patch उस अलग advisory को भी ठीक करता है। Advisory पुष्टि की गई exploitation नहीं बताती; यह लेख वास्तविक breach का दावा नहीं करता। CVE advisory इस श्रृंखला की authentication, token verification और authorization की खामियों के लिए CWE-287, CWE-303 और CWE-862 सूचीबद्ध करती है। अडवाइजरी में crazydude123 को रिपोर्टर के रूप में श्रेय दिया गया है।[1], [3], [4], [5], [6], [7], [9], [10]

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

चरण 1

MCP HTTP endpoint तक पहुँच संभव है

Deployment community mcp-atlassian server को HTTP पर चलाता है और unauthenticated पक्ष transport तक पहुँच सकता है। केवल stdio deployment इस CVE के प्रभावित path से बाहर है।[1]

चरण 2

सत्यापित user के बिना अनुरोध tool तक पहुँचता है

0.22.0 से पहले user identity रहित HTTP अनुरोध transport boundary पर reject होने के बजाय middleware पार कर सकता था। Advisory यह भी कहती है कि non-empty string को स्वतंत्र रूप से identity के रूप में verify नहीं किया जाता था।[1], [3]

चरण 3

Tool operator के साझा credentials चुनता है

यदि user identity नहीं है और server environment में Jira या Confluence credentials हैं, तो fetcher global credentials इस्तेमाल कर सकता है। अनुरोध operator के enabled tools की permissions पा सकता है; सटीक प्रभाव account अधिकार और configuration पर निर्भर है।[1], [3]

चरण 4

Transport पर reject करें और credential चयन में fail closed रखें

संस्करण 0.22.0 unauthenticated streamable-HTTP अनुरोधों पर HTTP 401 देता है और स्पष्ट opt-in के बिना HTTP context में global fallback रोकता है। SSE के लिए 0.23.1 या नया लगाएँ, जिसमें अलग path-matching flaw ठीक है।[1], [4], [5], [6]

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

यह control flow का संक्षिप्त रूप है, पूरे functions की हूबहू प्रति नहीं। Upstream patch transport boundary पर HTTP 401 और HTTP context में global fetcher लौटाने से पहले दूसरी रोक जोड़ता है।[1], [3], [4]

कमज़ोर कार्यान्वयन
# प्रभावित control flow का सरल रूप।
async def handle_request(scope, ctx):
    user_identity = scope.get("state", {}).get("user_atlassian_auth_type")
    # HTTP boundary पर identity न होने की स्थिति अस्वीकार नहीं की गई।
    return await call_tool_handler(ctx, user_identity=user_identity)

def get_fetcher(user_identity, global_config):
    if user_identity:
        return fetcher_for_user(user_identity)
    # विकल्प के रूप में environment में configured operator credentials इस्तेमाल होते हैं।
    return fetcher_from_config(global_config)
सुरक्षित और सुदृढ़ फ़िक्स
# 0.22.0 में जोड़े गए safeguards का संक्षिप्त रूप।
async def handle_request(scope, ctx):
    user_identity = scope.get("state", {}).get("user_atlassian_auth_type")
    if is_mcp_http_post(scope) and not user_identity and not allow_global_fallback():
        return http_401("Authentication required")
    return await call_tool_handler(ctx, user_identity=user_identity)

def get_fetcher(user_identity, global_config, *, in_http_context):
    if user_identity:
        return fetcher_for_user(user_identity)
    if in_http_context and not allow_global_fallback():
        raise PermissionError("Refusing operator credentials for an unauthenticated HTTP request")
    return fetcher_from_config(global_config)

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

स्रोत