Astral-tokio-tar 与 uv 中的任意文件写入路径穿越漏洞剖析

本文详细分析了 Rust 包 astral-tokio-tar 及其下游工具 uv 中的一个中危安全漏洞。该漏洞允许恶意 tar 文件在解压过程中向文件系统的任意位置写入文件,可能导致任意代码执行。文章探讨了漏洞根因、利用方法及修复时间线。

漏洞概述

“astral-tokio-tar” 是一个 Rust 库,被流行的 Python 工具 “uv” 所使用。该库在处理 tar 文件解包时存在一个漏洞,可能导致任意文件写入。具体到 “uv” 的场景中,此漏洞允许恶意的 Python 源码发行版在解压过程中将文件写入任意位置。

漏洞细节

漏洞主要源于 astral-tokio-tar 对符号链接的支持以及其"记忆化集合"(memoized set)的行为——该行为会跳过对已观察并验证过的路径的二次验证。

核心问题

  1. 父目录记忆化绕过Entry.unpack_in_raw() 方法引入的记忆化集合旨在提升文件系统操作性能。在 uvuntar_in() 函数中,为整个 tar 文件的解压过程使用同一个记忆化集合。当验证一个条目的父目录(例如,文件 path/to/file.txt 的父目录 path/to)时,如果该父目录路径已存在于记忆化集合中,则跳过验证步骤。
  2. 利用符号链接
    • 攻击者可以先创建一个指向目标目录(dst)内无害目录的符号链接(例如 ptr -> decoy)。该符号链接的父目录路径(dst/ptr)会被验证并加入记忆化集合。
    • 随后,在同一个 tar 文件中,可以用一个新的符号链接条目替换同一个路径(ptr),使其指向一个恶意位置。由于 dst/ptr 路径已在记忆化集合中,对其父目录的验证被跳过。
  3. 符号链接检查绕过astral-tokio-tar 本有一个由 allow_external_symlinks 标志控制的检查,旨在防止符号链接指向目标目录之外。但此检查可通过创建两个特定的、顺序排列的符号链接来绕过:
    • "ptr" -> "noop/noop/.../../../../../../tmp" (路径解析后仍在 dst 下,通过检查)
    • "noop" -> "." (指向当前目录,通过检查)
    • 创建后,ptr 的实际指向变为 ./../../../../../tmp,从而指向 dst 之外的目录。

概念验证(PoC)

攻击者可以构造包含以下条目的 tar 文件来实现任意写入:

  1. 创建目录 decoy
  2. 创建符号链接 ptr -> decoy
  3. 创建空文件 ptr/dummy。此操作会将 ptr(其解析路径为 decoy)的父目录路径加入记忆化集合,同时文件实际写入 decoy/dummy
  4. 替换符号链接 ptr -> noop/noop/.../../../../../../tmp
  5. 创建符号链接 noop -> .。现在 ptr 实际指向 dst/./../../../../../tmp(即 /tmp)。
  6. 写入恶意文件 ptr/payload。由于 ptr 的父目录路径已在记忆化集合中,验证被跳过,文件被写入 /tmp/payload

严重性

中危 - 由于可能导致任意代码执行。

受影响版本与修复

  • 受影响的包:Rust crate astral-tokio-tar
  • 受影响版本:<= 0.5.3
  • 已修复版本:> 0.8.22
  • 时间线
    • 报告日期:2025年8月11日
    • 修复日期:2025年9月23日
    • 披露日期:2025年11月17日

相关标识

  • CVE ID: CVE-2025-59825
  • GitHub Advisory: GHSA-9p78-p5g6-gcj8
  • 相关咨询: GHSA-7j9j-68r2-f35q, GHSA-3wgq-wrwc-vqmv
comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计