FlawOpen

flawopen.com/Teardowns/cve-2026-21589-atlassian-arbitrary-file-access

● CVE-2026-21589 · CVSS v4 9.3 · अति गंभीर
सुरक्षा अनुसंधान · FlawOpen

CVE-2026-21589: Atlassian Data Center फ़ाइल पहुँच

Atlassian का परामर्श और 12 अक्टूबर की MS-ISAC रिपोर्ट जोखिम और तात्कालिकता दिखाते हैं, लेकिन किसी खास ग्राहक इंस्टेंस के शोषण की पुष्टि नहीं करते।[1], [4], [5], [10]

💡 आसान भाषा में (ELI5)

एक पुस्तकालय की कल्पना करें जो आगंतुक से शेल्फ़ का पता लेता है। वह सभी शेल्फ़ नहीं देख सकता, लेकिन यदि उसे किसी खास किताब का स्थान पहले से पता हो, तो सीमा-जाँच की गलती कर्मचारी से सार्वजनिक क्षेत्र के बाहर की किताब मँगवा सकती है। सुधार हर हल किए गए पथ को अनुमत क्षेत्र में रखता है और संबंधित उत्पाद का अपडेट लगाता है।[1], [4]

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

मनमानी फ़ाइल तक पहुँच
अनुरोध अपेक्षित दायरे से बाहर की फ़ाइल तक पहुँचता है। Atlassian वेब अनुप्रयोग की रूट में विशिष्ट फ़ाइलों का उल्लेख करता है, पूरे फ़ाइल सिस्टम का नहीं।[1], [4]
पथ ट्रैवर्सल
पथ के घटक अपेक्षित निर्देशिका सीमा पार कर जाते हैं। Atlassian का शमन URL में ट्रैवर्सल संकेतों और उनके एन्कोडेड रूपों को रोकता है।[1], [4]
Data Center
Atlassian का स्वयं-प्रबंधित परिनियोजन मॉडल। सलाह में आठ प्रभावित उत्पाद हैं; Atlassian कहता है कि Cloud उत्पाद ठीक किए जा चुके हैं।[1]
पहले से ज्ञात पथ
लक्ष्य फ़ाइल का सटीक नाम और पथ पहले से जानना आवश्यक है; सलाह के अनुसार निर्देशिकाओं की सूची या गणना नहीं की जा सकती।[1]
CVSS 4.0
Atlassian ने अपनी आंतरिक आकलन-पद्धति के अनुसार इसे Critical, CVSS 4.0 स्कोर 9.3 दिया है।[1]
Router.unescapeSlashes()
साझा लाइब्रेरी resource संभालने से पहले एन्कोड किए separator :: को वापस / में बदलती है; watchTowr के स्रोत विश्लेषण में यही decoding सीमा महत्वपूर्ण है।[1], [4]
ResourceServingHelpers
यह helper resource name हल करके शेष relative path को createResourceWithRelativePath() तक भेजता है।[1], [4]
Crowd credential chain
कॉन्फ़िगरेशन पर निर्भर अगला चरण: पढ़ी जा सकने वाली Crowd properties फ़ाइल application password खोल सकती है; उसका उपयोग नेटवर्क पहुँच और अनुमतियों पर निर्भर है।[4], [5]
CWE-22
Path traversal कमजोरी के लिए FlawOpen का संपादकीय वर्गीकरण: पथ को अपेक्षित निर्देशिका तक पर्याप्त रूप से सीमित नहीं किया गया है। Atlassian की सलाह में CWE निर्दिष्ट नहीं है।[6]

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

  • MITRE CWE के लिए FlawOpen की वैचारिक मैपिंग; किसी विक्रेता या CVE रिकॉर्ड ने इस शोध प्रदर्शन को यह कमजोरी ID नहीं दी है। CWE-22

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

Atlassian की साझा atlassian-plugins-webresource लाइब्रेरी के watchTowr विश्लेषण में path-decoding सीमा सामने आती है। Router.unescapeSlashes() :: को / में बदलता है; resource routes handler बुलाने से पहले अनुरोध-नियंत्रित path components पर यह फ़ंक्शन चलाते हैं। बाद की lookup resource name को बाँटकर शेष relative path createResourceWithRelativePath() को देती है, जहाँ वैकल्पिक separator रूप traversal जाँच की धारणा को पार कर सकता है। शोधकर्ताओं ने Jira, Confluence और Bitbucket में Tomcat application context के भीतर फ़ाइल पढ़ना दिखाया; Atlassian आठ उत्पादों को प्रभावित बताता है। रिपोर्ट के अनुसार परीक्षण Tomcat context से बाहर नहीं गया। शर्तें पूरी होने पर पढ़ी जा सकने वाली WEB-INF/classes/crowd.properties में Crowd application password सादे पाठ में हो सकता है; प्रभाव deployment configuration और Crowd तक नेटवर्क पहुँच पर निर्भर है। BleepingComputer के अनुसार तकनीकी रिपोर्ट और PoC के सार्वजनिक होने के कुछ घंटों बाद Previdian sensors ने प्रयास देखे। ये honeypot पर प्रयास हैं, ग्राहक प्रणालियों में सफल पहुँच का प्रमाण नहीं। नीचे के संवेदनशील Java अंश watchTowr रिपोर्ट से हैं। सुरक्षित उदाहरण सामान्य containment pattern है, Atlassian का अप्रकाशित पूर्ण patch नहीं; हर उत्पाद का आधिकारिक update लगाएँ।[1], [4], [5]

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

चरण 1

साझा decoder पथ बदलता है

Atlassian web-resource router resource देने से पहले वैकल्पिक separator :: को / में बदलता है। यह सामान्य resource routing का हिस्सा है।[1], [4]

चरण 2

डिकोड किया पथ resource lookup तक पहुँचता है

Helper path components बाँटकर शेष relative path resource factory को देता है। वैकल्पिक separator traversal check की मान्यताओं को पार कर सकता है।[4]

चरण 3

Application context की फ़ाइलें पढ़ी जा सकती हैं

watchTowr ने Jira, Confluence और Bitbucket में यह दिखाया। रिपोर्ट कहती है कि परीक्षण Tomcat context से बाहर नहीं गया; इसे host की सभी फ़ाइलों तक पहुँच न मानें।[1], [4]

चरण 4

Identity chain deployment पर निर्भर है

यदि पढ़ी जा सकने वाली Crowd config में application password हो और Crowd तक पहुँचना संभव हो तथा credential स्वीकार हो, तो identity सुविधाएँ खुल सकती हैं।[4], [5]

चरण 5

देखे गए प्रयास तात्कालिकता बढ़ाते हैं, सेंध साबित नहीं करते

12 अक्टूबर को Center for Internet Security के MS-ISAC परामर्श में कहा गया कि CVE-2026-21589 के वास्तविक परिवेश में शोषण की रिपोर्टें हैं। इसमें किसी पीड़ित की पहचान या घटना के प्रमाण प्रकाशित नहीं किए गए; इसलिए इसे MS-ISAC द्वारा दी गई शोषण-सूचना मानें, किसी पहचाने गए ग्राहक तक पहुँच की पुष्टि नहीं। Atlassian के 5 अक्टूबर के परामर्श में कहा गया था कि उसकी जाँच में Cloud उत्पादों के शोषण का प्रमाण नहीं मिला था और उन उत्पादों में सुधार लागू कर दिया गया था। यह निष्कर्ष Cloud तक सीमित था और भेद्यता के शोषण की MS-ISAC रिपोर्ट का खंडन नहीं करता। इनमें से कोई भी बयान किसी खास इंस्टेंस के बारे में निष्कर्ष नहीं देता।[1], [10]

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

कमज़ोर कोड अंश प्रभावित web-resource लाइब्रेरी के लिए watchTowr द्वारा प्रकाशित स्रोत-स्तरीय पाथ रूपांतरण दिखाता है; यह कोई exploit request नहीं है। नीचे दिया गया उदाहरण Java में एक सामान्य सुरक्षा उपाय है, Atlassian का पैच नहीं: यह भरोसेमंद मूल डायरेक्टरी से SecureDirectoryStream हैंडल के ज़रिए पाथ पर चलता है, हर घटक पर सिम्बॉलिक लिंक अस्वीकार करता है और पढ़े जाने वाले बाइट सीमित करता है। कॉल करने वाले को एक बार डिकोड किया गया relative path और भरोसेमंद डायरेक्टरी से rooted SecureDirectoryStream देना होगा। कुछ फ़ाइल सिस्टम प्रदाता SecureDirectoryStream का समर्थन नहीं करते; ऐसे में सुरक्षित रूप से अनुरोध अस्वीकार करें। उत्पाद के लिए विक्रेता का विशिष्ट अपडेट इंस्टॉल करें।यह उदाहरण भरोसेमंद resource tree मानता है, जिसके डायरेक्टरी और फ़ाइलें अविश्वसनीय उपयोगकर्ता बदल न सकें और जिसमें केवल सामान्य फ़ाइलें हों; यह स्वयं फ़ाइल का प्रकार सत्यापित नहीं करता। बाइट सीमा और बिना प्रगति वाली पढ़ाई की सीमित पुनरावृत्ति पढ़ाई को सीमित करती है, लेकिन यह सार्वभौमिक file-serving routine नहीं है। कॉल करने वाले को एक बार डिकोड किया हुआ relative path देना होगा और भरोसेमंद root stream खुला रखना होगा। फ़ाइल सिस्टम प्रदाता SecureDirectoryStream का समर्थन न भी करे; उपलब्ध न होने पर सुरक्षित रूप से अनुरोध अस्वीकार करें।[4], [7]

कमज़ोर कार्यान्वयन
public static String unescapeSlashes(String string) {
    return string.replaceAll("::", "/");
}
सुरक्षित और सुदृढ़ फ़िक्स
static byte[] readUnder(SecureDirectoryStream<Path> root, Path relative, int maxBytes) throws IOException {
    if (relative.isAbsolute() || relative.getNameCount() == 0 || maxBytes < 0) {
        throw new SecurityException("Expected a relative path and non-negative limit");
    }
    List<SecureDirectoryStream<Path>> opened = new ArrayList<>();
    SecureDirectoryStream<Path> parent = root;
    try {
        for (int i = 0; i < relative.getNameCount() - 1; i++) {
            Path part = relative.getName(i);
            if (part.toString().isEmpty() || part.toString().equals(".") || part.toString().equals("..")) {
                throw new SecurityException("Invalid path component");
            }
            parent = parent.newDirectoryStream(part, LinkOption.NOFOLLOW_LINKS);
            opened.add(parent);
        }
        Path leaf = relative.getFileName();
        if (leaf.toString().isEmpty() || leaf.toString().equals(".") || leaf.toString().equals("..")) {
            throw new SecurityException("Invalid file name");
        }
        try (SeekableByteChannel channel = parent.newByteChannel(
                leaf, Set.of(StandardOpenOption.READ, LinkOption.NOFOLLOW_LINKS))) {
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            ByteBuffer buffer = ByteBuffer.allocate(8192);
            int total = 0;
            int zeroReads = 0;
            while (true) {
                int count = channel.read(buffer);
                if (count == -1) break;
                if (count == 0) {
                    if (++zeroReads >= 3) throw new IOException("Resource read made no progress");
                    continue;
                }
                zeroReads = 0;
                if (count > maxBytes - total) throw new IOException("Resource exceeds size limit");
                out.write(buffer.array(), 0, count);
                total += count;
                buffer.clear();
            }
            return out.toByteArray();
        }
    } finally {
        for (int i = opened.size() - 1; i >= 0; i--) opened.get(i).close();
    }
}

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

स्रोत