flawopen.com/Teardowns/CVE-2024-32002
Imagine um entregador levando um pacote confidencial para a 'Sala 101'. Um invasor coloca uma placa na porta dizendo: 'A Sala 101 mudou-se para o Cofre da Diretoria'. Em vez de verificar se a placa é legítima, o entregador segue a seta cegamente e deixa o pacote dentro do cofre. No Git, o entregador era o clonador de submódulos, a placa enganosa era um symlink (atalho), e o cofre era o diretório oculto .git/hooks/, onde scripts são executados automaticamente.
git clone --recursive <url>Em builtin/submodule--helper.c e dir.c, o Git inicializava a árvore de trabalho do submódulo sem verificar se algum diretório pai no caminho de clone era um symlink apontando para fora da árvore segura.
// 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 que aponta para .git/modules/sub (onde o Git armazena metadados internos).SUB/hooks, o sistema operacional resolvia SUB através do symlink, gravando em .git/modules/sub/hooks/.post-checkout dentro da pasta de hooks. Ao finalizar a clonagem, o Git disparava automaticamente o hook, executando comandos arbitrários no terminal.Pasta/A e pasta/a colidem no disco mesmo que seu código os trate como strings diferentes.lstat ou O_NOFOLLOW)..git/ protegido.