flawopen.com/Teardowns/CVE-2024-32002
想象一位快递员要将内部包裹送到“101房间”。攻击者在101门上挂了一个指示牌:“101房间已临时搬至总裁保险库”。快递员不加核实,盲目顺着指示牌将包裹放进了保险库。在 Git 中,快递员就是子模块克隆程序,误导性指示牌是一个符号链接(symlink),而保险库就是 Git 的隐藏目录 .git/hooks/,存放在这里的钩子脚本会在特定操作时被自动执行。
git clone --recursive <url>在 builtin/submodule--helper.c 和 dir.c 中,Git 在初始化子模块工作区时,未验证克隆路径中的父目录组件是否存在指向外部的符号链接。
// Git clone created submodule directory blindly
static int clone_submodule(const struct module_clone_data *clone_data)
{
struct strbuf sb = STRBUF_INIT;
// BUG: clone_data->path could traverse an existing symlink
strbuf_addf(&sb, "%s", clone_data->path);
safe_create_leading_directories(sb.buf);
return do_clone(clone_data);
}
// Fixed: Refuse to clone into or through symlinked path components
static int clone_submodule(const struct module_clone_data *clone_data)
{
struct strbuf sb = STRBUF_INIT;
// FIX: Validate that no parent component is a symlink
if (path_has_symlinks(clone_data->path))
die(_("fatal: submodule path '%s' contains a symlink"),
clone_data->path);
strbuf_addf(&sb, "%s", clone_data->path);
return do_clone(clone_data);
}
sub 的符号链接,指向内部元数据目录 .git/modules/sub。SUB/hooks 的子模块时,操作系统将路径自动解析到符号链接指向的目标位置。post-checkout 钩子,Git 在克隆完成时立即自动执行该脚本。Path/A 与 path/a 在底层指向同一物理文件。lstat 或安全 API 校验中间路径。.git/ 目录的非法写入。