FlawOpen

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

● CVE-2026-21589 · CVSS v4 9.3 · Kritisch
Sicherheitsforschung · FlawOpen

CVE-2026-21589: Dateizugriff in Atlassian Data Center

Atlassians Hinweis und der MS-ISAC-Bericht vom 12. Oktober belegen Risiko und Dringlichkeit, aber keine Ausnutzung einer bestimmten Kundeninstanz.[1], [4], [5], [10]

💡 Einfache Erklärung (ELI5)

Stellen Sie sich eine Bibliothek vor, die von Besuchern einen Regalstandort entgegennimmt. Sie können nicht alle Regale durchsuchen, doch wenn sie den Standort eines bestimmten Buches kennen, kann eine fehlerhafte Grenzprüfung den Mitarbeiter dazu bringen, es außerhalb des öffentlichen Bereichs zu holen. Der Fix hält jeden aufgelösten Pfad im erlaubten Bereich und aktualisiert das jeweilige Produkt.[1], [4]

Kernkonzepte & Begriffe

Beliebiger Dateizugriff
Eine Anfrage kann Dateien außerhalb des vorgesehenen Bereichs erreichen. Atlassian beschreibt den Zugriff auf bestimmte Dateien unterhalb des Webroots, nicht auf das gesamte Dateisystem.[1], [4]
Pfad-Traversal
Pfadbestandteile überschreiten die Grenze des vorgesehenen Verzeichnisses. Atlassians Abwehr zielt auf Traversal-Muster und codierte URL-Varianten.[1], [4]
Data Center
Atlassians selbstverwaltetes Bereitstellungsmodell. Der Hinweis nennt acht betroffene Produkte; Atlassian zufolge sind Cloud-Produkte gepatcht.[1]
Bekannter Pfad
Dateiname und exakter Pfad müssen vorher bekannt sein; laut Hinweis ermöglicht der Fehler keine Verzeichnisauflistung.[1]
CVSS 4.0
Atlassian bewertet die Schwachstelle intern als Kritisch mit CVSS 4.0 9,3.[1]
Router.unescapeSlashes()
Die gemeinsame Bibliothek wandelt den kodierten Trenner :: vor der Ressourcenverarbeitung zurück in /; diese Dekodierungsgrenze steht im Zentrum von watchTowrs Analyse.[1], [4]
ResourceServingHelpers
Der Helper löst den Ressourcennamen auf und übergibt den verbleibenden relativen Pfad an createResourceWithRelativePath().[1], [4]
Crowd-Zugangsdatenkette
Bedingter Folgeschritt: Eine lesbare Crowd-Properties-Datei kann ein Anwendungspasswort offenlegen; Erreichbarkeit und Berechtigungen entscheiden über die Nutzbarkeit.[4], [5]
CWE-22
Redaktionelle FlawOpen-Zuordnung für die Path-Traversal-Schwäche: Der Pfad wird nicht ausreichend auf das vorgesehene Verzeichnis beschränkt. Atlassians Hinweis nennt keinen CWE.[6]

Framework-Zuordnungen

  • Konzeptionelle Zuordnung von FlawOpen zu MITRE CWE; weder ein Anbieter noch ein CVE-Datensatz hat diese Schwachstellen-ID dieser Forschungsdemonstration zugewiesen. CWE-22

Ursachenanalyse

watchTowrs Analyse der gemeinsamen Bibliothek atlassian-plugins-webresource zeigt die Pfaddekodierungsgrenze. Router.unescapeSlashes() wandelt :: in / um; Ressourcenrouten wenden die Funktion auf anfragegesteuerte Pfadbestandteile an, bevor sie Ressourcenhandler aufrufen. Die nachgelagerte Suche zerlegt den Ressourcennamen und übergibt den verbleibenden Pfad an createResourceWithRelativePath(), wo die alternative Trennzeichendarstellung die Traversal-Prüfung umgehen kann. Forschende demonstrierten Dateizugriffe innerhalb des Tomcat-Anwendungskontexts in Jira, Confluence und Bitbucket; Atlassian nennt acht betroffene Produkte. Laut Bericht verließ der getestete Traversal den Tomcat-Kontext nicht. In einer bedingten Kette kann eine lesbare WEB-INF/classes/crowd.properties das Crowd-Anwendungspasswort im Klartext offenlegen; die Folgen hängen von Konfiguration und Erreichbarkeit von Crowd ab. BleepingComputer berichtet, Previdian-Sensoren hätten wenige Stunden nach Veröffentlichung der technischen Analyse und des PoC Angriffsversuche beobachtet. Das belegt Versuche gegen Honeypots, keinen erfolgreichen Zugriff auf Kundensysteme. Die verwundbaren Java-Auszüge stammen aus watchTowrs Bericht. Das sichere Beispiel ist ein allgemeines Begrenzungsmuster, nicht Atlassians nicht vollständig veröffentlichter Patch; installieren Sie das offizielle Produktupdate.[1], [4], [5]

Schritt-für-Schritt Angriffsablauf

Schritt 1

Ein gemeinsamer Decoder verändert den Pfad

Atlassians Webressourcen-Router wandelt den alternativen Trenner :: vor dem Ausliefern einer Ressource in / um. Diese Dekodierung erfolgt im normalen Ressourcenrouting.[1], [4]

Schritt 2

Die Ressourcensuche erhält den dekodierten Pfad

Der Helper zerlegt Pfadbestandteile und übergibt den übrigen relativen Pfad an die Ressourcenfabrik. Der alternative Trenner kann Annahmen der Traversal-Prüfung umgehen.[4]

Schritt 3

Dateien im Anwendungskontext werden lesbar

watchTowr zeigte dies in Jira, Confluence und Bitbucket. Laut Bericht verließ der getestete Pfad den Tomcat-Kontext nicht; daraus folgt kein Zugriff auf beliebige Hostdateien.[1], [4]

Schritt 4

Eine Identitätskette hängt von der Konfiguration ab

Enthält eine lesbare Crowd-Konfiguration das Anwendungspasswort und ist Crowd mit diesem Konto erreichbar, können Identitätsfunktionen zugänglich werden. IP-Listen und Deployment beeinflussen dies.[4], [5]

Schritt 5

Beobachtete Versuche erhöhen die Dringlichkeit, belegen aber keinen Einbruch

Am 12. Oktober erklärte der MS-ISAC-Hinweis des Center for Internet Security, es gebe Berichte über eine Ausnutzung von CVE-2026-21589 in freier Wildbahn. Er nannte weder Opfer noch veröffentlichte er Vorfallsartefakte. Behandle dies daher als einen vom MS-ISAC gemeldeten Ausnutzungshinweis, nicht als bestätigten Zugriff bei einem namentlich bekannten Kunden. Atlassians Hinweis vom 5. Oktober sagte, die eigene Untersuchung habe keine Hinweise auf eine Ausnutzung in den Cloud-Produkten ergeben; diese seien gepatcht worden. Diese Feststellung bezog sich auf Cloud und widerspricht nicht dem MS-ISAC-Bericht über Ausnutzungsberichte zur Schwachstelle. Keine der Aussagen belegt, was auf einer bestimmten Instanz geschah.[1], [10]

Quellcode: Verwundbar vs. Sicher

Der verwundbare Ausschnitt zeigt die von watchTowr veröffentlichte Quellcode-Transformation des Pfads für die betroffene Web-Resource-Bibliothek; er ist keine Exploit-Anfrage. Das untere Beispiel zeigt eine allgemeine Java-Abwehr, nicht Atlassians Patch: Es durchläuft den Pfad ab einem vertrauenswürdigen Stammverzeichnis über SecureDirectoryStream-Handles, weist symbolische Links an jedem Bestandteil zurück und begrenzt die gelesene Bytezahl. Der Aufrufer muss einen genau einmal dekodierten relativen Pfad und einen in einem vertrauenswürdigen Verzeichnis verankerten SecureDirectoryStream bereitstellen. Dateisystem-Provider unterstützen SecureDirectoryStream möglicherweise nicht; brechen Sie dann sicher ab. Installieren Sie das produktspezifische Update des Anbieters. Dieses Beispiel setzt einen vertrauenswürdigen Ressourcenbaum voraus, dessen Verzeichnisse und Dateien nicht von nicht vertrauenswürdigen Benutzern verändert werden können und der nur reguläre Dateien enthält; den Dateityp prüft es nicht selbst. Byte-Limit und begrenzte Behandlung ausbleibenden Lesefortschritts begrenzen das Lesen, ergeben aber keine universelle Routine zur Dateiauslieferung. Der Aufrufer muss den genau einmal dekodierten relativen Pfad bereitstellen und einen vertrauenswürdigen Stammstream offen halten. Die Unterstützung durch den Dateisystem-Provider ist optional; brechen Sie sicher ab, wenn SecureDirectoryStream fehlt.[4], [7]

VERWUNDBARE IMPLEMENTIERUNG
public static String unescapeSlashes(String string) {
    return string.replaceAll("::", "/");
}
GEHÄRTETER SICHERHEITS-PATCH
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();
    }
}

Checkliste für Engineering & Systemsicherheit

Quellen