flawopen.com/Teardowns/cve-2026-21589-atlassian-arbitrary-file-access
CVE-2026-21589:Atlassian Data Center 文件访问漏洞
Atlassian 公告和 10月12日的 MS-ISAC 报告说明了风险和紧迫性,但不能证明某个客户实例遭到利用或已确认被入侵。[1], [4], [5], [10]
想象图书馆允许访客报出书架位置。访客不能浏览所有书架,但如果他已知道某本书的确切位置,边界检查缺陷可能让工作人员从阅览区以外取书。修复要确保解析后的路径始终位于允许范围,并安装对应产品的更新。[1], [4]
核心概念与专有名词
Data Center- Atlassian 的自托管部署模式。公告列出八款受影响产品;Atlassian 表示 Cloud 产品已修复。[1]
已知路径前提- 攻击者必须预先知道目标文件的确切名称和路径;公告指出该漏洞不能枚举或列出目录。[1]
CVSS 4.0- Atlassian 根据自身评估将其定为严重,CVSS 4.0 评分为 9.3。[1]
CWE-22- FlawOpen 对路径遍历弱点的编辑分类:路径未被充分限制在预期目录内。Atlassian 的公告未指定 CWE。[6]
框架映射
- FlawOpen 对 MITRE CWE 的概念性映射;没有厂商或 CVE 记录将此弱点编号分配给本研究演示。 CWE-22
根本原因剖析 (Root Cause)
watchTowr 对共享库 atlassian-plugins-webresource 的分析指出了路径解码边界。Router.unescapeSlashes() 会将 :: 转换为 /;资源路由在调用资源处理程序前,会对请求可控的路径组件应用该函数。后续查找拆分资源名称,并将剩余路径传给 createResourceWithRelativePath();替代分隔符表示可绕过路径穿越检查的假设。研究人员在 Jira、Confluence 和 Bitbucket 中演示了读取 Tomcat 应用上下文内文件;Atlassian 列出八款受影响产品。报告称其测试路径未越出 Tomcat 上下文。在有条件的攻击链中,可读取的 WEB-INF/classes/crowd.properties 可能暴露明文 Crowd 应用密码;影响取决于具体配置及 Crowd 是否可达。BleepingComputer 报道称,Previdian 传感器在技术分析和 PoC 发布数小时后观察到利用尝试。这是针对蜜罐的尝试证据,并不证明客户系统访问成功。下方脆弱 Java 片段来自 watchTowr 报告。安全示例是通用路径约束模式,并非 Atlassian 未完整公开的补丁源码;请安装各产品官方修复版本。[1], [4], [5]
攻击执行流程分解
资源查找接收解码后的路径
辅助函数拆分路径组件,并将剩余相对路径传给资源工厂。替代分隔符可能绕过路径穿越检查所依赖的假设。[4]
源代码对比:漏洞与安全实现
易受攻击的代码片段展示了 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 表示其 Cloud 产品已修复。[1]
- ✓将每个受影响实例升级到公告列出的修复版本,并逐一核验每个集群节点的实际运行版本。[1]
- ✓若无法立即打补丁,应限制公网访问,直到实例完成修补或缓解。对所有相关节点应用适用于该产品的临时 WAF/代理、Tomcat RewriteValve 或 Bitbucket urlrewrite.xml 规则,并在依赖该规则前测试编码后的路径变体。[1]
- ✓按照 Atlassian 指引对访问日志中的 URL 解码(最多两轮),查找紧邻
/、\或::的..;保留原始日志。[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)