flawopen.com/Teardowns/cve-2026-21589-atlassian-arbitrary-file-access
CVE-2026-21589: доступ к файлам Atlassian Data Center
Бюллетень Atlassian и сообщение MS-ISAC от 12 октября подтверждают риск и срочность, но не факт эксплуатации конкретной клиентской системы.[1], [4], [5], [10]
Представьте библиотеку, где посетитель называет адрес полки. Он не может осматривать все полки, но если уже знает место конкретной книги, ошибка проверки границ может заставить сотрудника достать её за пределами читального зала. Исправление удерживает каждый разрешённый путь внутри допустимой области и обновляет соответствующий продукт.[1], [4]
Ключевые понятия и термины
Произвольный доступ к файлам- Запрос получает доступ к файлам за пределами ожидаемой области. Atlassian описывает доступ к отдельным файлам в веб-каталоге, а не ко всей файловой системе.[1], [4]
Обход пути- Компоненты пути пересекают границу разрешённого каталога. Мера Atlassian блокирует маркеры обхода и их кодированные варианты в URL.[1], [4]
Data Center- Модель самостоятельного размещения продуктов Atlassian. В уведомлении указаны восемь продуктов; по данным Atlassian, Cloud-продукты исправлены.[1]
Известный путь- Злоумышленнику заранее нужны точное имя и путь к файлу; уведомление подчёркивает, что уязвимость не перечисляет каталоги.[1]
CVSS 4.0- Atlassian оценивает уязвимость как критическую: CVSS 4.0 — 9,3 по собственной оценке компании.[1]
Router.unescapeSlashes()- Общая библиотека преобразует закодированный разделитель
::обратно в/до обработки ресурса; эта граница декодирования важна для анализа watchTowr.[1], [4] ResourceServingHelpers- Вспомогательная функция разрешает имя ресурса и передаёт оставшийся относительный путь в
createResourceWithRelativePath().[1], [4] Цепочка учётных данных Crowd- Условный следующий этап: доступный файл свойств Crowd может раскрыть пароль приложения; возможность его использования зависит от сети и прав.[4], [5]
CWE-22- Редакционная классификация FlawOpen для уязвимости обхода пути: путь недостаточно ограничен заданным каталогом. Atlassian не присваивает CWE в своем уведомлении.[6]
Связи со стандартами
- Концептуальное соответствие FlawOpen для MITRE CWE; ни поставщик, ни запись CVE не присваивали этот идентификатор слабого места данной исследовательской демонстрации. CWE-22
Анализ первопричины
Анализ watchTowr общей библиотеки atlassian-plugins-webresource выявил границу декодирования путей. Router.unescapeSlashes() заменяет :: на /; маршруты ресурсов применяют функцию к компонентам пути из запроса до вызова обработчиков ресурсов. Последующий поиск разбивает имя ресурса и передаёт оставшийся путь в createResourceWithRelativePath(), где альтернативное представление разделителя может обойти проверку traversal. Исследователи продемонстрировали чтение файлов внутри контекста приложения Tomcat в Jira, Confluence и Bitbucket; Atlassian указывает восемь затронутых продуктов. В отчёте сказано, что проверенный traversal не выходил за контекст Tomcat. В условной цепочке доступный для чтения WEB-INF/classes/crowd.properties может раскрыть пароль приложения Crowd в открытом виде; последствия зависят от конфигурации и доступности Crowd. BleepingComputer сообщает, что датчики Previdian зафиксировали попытки через несколько часов после публикации технического разбора и PoC. Это попытки на honeypot-сенсорах, а не доказательство успешного доступа к системам клиентов. Уязвимые фрагменты Java ниже опубликованы watchTowr. Защитный пример — общий шаблон ограничения пути, а не полный исходный код исправления Atlassian; установите официальный патч каждого продукта.[1], [4], [5]
Пошаговый сценарий атаки
Поиск ресурса получает декодированный путь
Вспомогательная функция разбирает компоненты и передаёт остаток относительного пути фабрике ресурсов. Альтернативный разделитель может обойти предположения проверки traversal.[4]
Наблюдавшиеся попытки повышают срочность, но не подтверждают взлом
12 октября в бюллетене MS-ISAC Центра интернет-безопасности сообщалось о случаях эксплуатации CVE-2026-21589 в реальных условиях. В бюллетене не названы пострадавшие и не опубликованы материалы инцидентов, поэтому это следует считать сообщением MS-ISAC об эксплуатации, а не подтверждением доступа к системе конкретного клиента. В бюллетене Atlassian от 5 октября говорилось, что расследование компании не выявило признаков эксплуатации в продуктах Cloud; компания также сообщила, что они исправлены. Этот вывод относился к Cloud и не противоречит сообщению MS-ISAC об эксплуатации уязвимости. Ни одно из заявлений не устанавливает, что произошло с конкретным экземпляром.[1], [10]
Исходный код: Уязвимый vs Защищённый вариант
Уязвимый фрагмент показывает опубликованное watchTowr преобразование пути в исходном коде затронутой библиотеки web-resource; это не запрос для эксплуатации. Нижний пример демонстрирует общий способ защиты на Java, а не патч Atlassian: обход от доверенного корня через дескрипторы SecureDirectoryStream, отказ от символических ссылок на каждом компоненте и ограничение объёма чтения. Вызывающий код должен передать относительный путь, декодированный ровно один раз, и SecureDirectoryStream, открытый от доверенного каталога. Некоторые файловые провайдеры не поддерживают SecureDirectoryStream; в этом случае безопасно откажитесь от операции. Установите исправление поставщика для конкретного продукта. Этот пример предполагает доверенное дерево ресурсов, каталоги и файлы которого не могут изменять недоверенные пользователи и которое содержит только обычные файлы; тип файла здесь отдельно не проверяется. Ограничение байтов и ограниченная обработка отсутствия прогресса сдерживают чтение, но это не универсальная процедура выдачи файлов. Вызывающий код должен передать относительный путь, декодированный ровно один раз, и сохранить открытый доверенный корневой поток. Поддержка со стороны файлового провайдера необязательна; безопасно откажитесь от операции, если 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();
}
}
Чек-лист по защите системы для инженеров
- ✓Минимальные исправленные версии: Bitbucket 9.4.26 / 10.2.8 / 10.5.1; Confluence 9.2.26 / 10.2.19; Jira Service Management 5.12.40 / 10.3.26 / 11.3.12; Jira Software 9.12.40 / 10.3.26 / 11.3.12; Bamboo 10.2.24 / 12.1.12; Crowd 6.3.7 / 7.0.3 / 7.1.7 / 7.2.4; Crucible и Fisheye 4.9.15. Выбирайте версию для нужного продукта и ветки.[1]
- ✓Проведите инвентаризацию всех восьми затронутых самостоятельных продуктов (шесть обозначены как Data Center, а также Crucible и Fisheye), их узлов и зеркал, а также доступных из интернета экземпляров. Atlassian сообщает, что облачные продукты исправлены.[1]
- ✓Обновите каждую затронутую установку до исправленной версии из уведомления и проверьте фактическую версию на каждом узле кластера.[1]
- ✓Если немедленно установить обновление нельзя, ограничьте внешний доступ до установки исправления или меры защиты. Примените подходящее временное правило WAF/proxy, Tomcat RewriteValve или urlrewrite.xml для Bitbucket на каждом нужном узле и проверьте кодированные варианты, прежде чем полагаться на него.[1]
- ✓Проверьте журналы доступа: декодируйте URL, как рекомендует Atlassian (до двух проходов), и ищите
..рядом с/,\или::; сохраните исходные журналы.[1], [9] - ✓Считайте совпавший запрос поводом для расследования, а не доказательством возврата файла. Atlassian не может подтвердить компрометацию; выясните, какие чувствительные файлы существовали, и выберите меры реагирования на основании имеющихся данных.[1], [9]
- ✓В собственном коде задайте один этап канонизации, ограничьте путь разрешённым корнем и учитывайте символические ссылки, гонки и каждый слой декодирования.[7], [6]
Источники
- Уведомление Atlassian — CVE-2026-21589
- CERT-EU — критическая уязвимость в продуктах Atlassian
- Канадский центр кибербезопасности — уведомление Atlassian AV26-1002
- watchTowr Labs — CVE-2026-21589 technical analysis
- BleepingComputer — observed CVE-2026-21589 exploitation attempts
- MITRE CWE-22 — Path Traversal (FlawOpen editorial mapping)
- Oracle Java API — SecureDirectoryStream
- Previdian — sensor telemetry and exploitation methodology
- NIST SP 800-61 Rev. 3 — Рекомендации по реагированию на инциденты
- Center for Internet Security MS-ISAC — CVE-2026-21589 exploitation report (October 12, 2026)