git/compat
Johannes Schindelin c57c052ae8 mingw: skip symlink type auto-detection for network share targets
On Windows, symbolic links come in two flavors: file symlinks and
directory symlinks.  Since Git was born on Linux where this distinction
does not exist, Git for Windows has to auto-detect the type by looking
at the target.  When the target does not yet exist at symlink creation
time, Git for Windows creates a "phantom" file symlink and later, once
checkout is complete, calls `CreateFileW()` on the target to check
whether it is actually a directory.

If the symlink target is a UNC path (e.g. `\\attacker\share`), this
auto-detection triggers an SMB connection to the remote host.  Windows
performs NTLM authentication by default for such connections, which
means a crafted repository can exfiltrate the cloning user's NTLMv2 hash
to an attacker-controlled server without any user interaction beyond
`git clone -c core.symlinks=true <url>`.

There are ways to specify UNC paths that start with only a single
backslash (e.g. `\??\UNC\host\share`); All of them do start like that,
though, so let's use that as a tell-tale that we should skip the
auto-detection in `process_phantom_symlink()`. The symlink is then left
as a file symlink (the `mklink` default), and a warning is emitted
suggesting the user set the `symlink` gitattribute to `dir` if a
directory symlink is needed.  When the attribute is already set,
auto-detection is never invoked in the first place, so that code path is
unaffected.

This is the same class of vulnerability as CVE-2025-66413
(https://github.com/git-for-windows/git/security/advisories/GHSA-hv9c-4jm9-jh3x)
and follows the same general mitigation pattern that MinTTY adopted for
ANSI escape sequences referencing network share paths
(https://github.com/mintty/mintty/security/advisories/GHSA-jf4m-m6rv-p6c5).

Note that there are legitimate paths starting with a single backslash
that are _not_ network paths: drive-less absolute paths are interpreted
as relative to the current working directory's drive. In practice, these
are highly uncommon (and brittle, just one working directory change away
from breaking). In any case, the only consequence is now that the
symlink type of those has to be specified via Git attributes, is all.

Reported-by: Justin Lee <jessdhoctor@gmail.com>
Addresses: CVE-2026-32631
Assisted-by: Claude Opus 4.6
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-28 15:39:59 -07:00
..
darwin trace2: add macOS process ancestry tracing 2026-02-13 12:18:31 -08:00
fsmonitor fsmonitor: implement filesystem change listener for Linux 2026-04-15 08:44:33 -07:00
linux
poll unify and bump _WIN32_WINNT definition to Windows 8.1 2026-04-06 10:06:20 -07:00
regex compat/regex: explicitly mark intentional use of the comma operator 2025-03-28 17:38:11 -07:00
simple-ipc git-compat-util: introduce MEMZERO_ARRAY() macro 2025-12-11 14:44:43 +09:00
stub compat: mark unused parameters in win32/mingw functions 2024-08-28 09:51:18 -07:00
vcbuild mingw.c: Fix complier warnings for a 64 bit msvc 2024-10-17 14:42:27 -04:00
win32 Merge branch 'ty/migrate-ignorecase' 2026-07-19 10:42:19 -07:00
.gitattributes
access.c
apple-common-crypto.h
basename.c compat/win32: fix const-correctness with string constants 2024-06-07 10:30:52 -07:00
bswap.h bswap.h: provide a built-in based version of bswap32/64 if possible 2025-07-15 14:36:51 -07:00
compiler.h mingw.c: Fix complier warnings for a 64 bit msvc 2024-10-17 14:42:27 -04:00
disk.h
fileno.c
fopen.c
hstrerror.c
inet_ntop.c
inet_pton.c
memmem.c
mingw-posix.h mingw: implement basic `symlink()` functionality (file symlinks only) 2026-01-09 18:32:55 -08:00
mingw.c mingw: skip symlink type auto-detection for network share targets 2026-07-28 15:39:59 -07:00
mingw.h compat/mingw: split out POSIX-related bits 2025-02-18 10:55:39 -08:00
mkdir.c
mmap.c compat/mmap: mark unused argument in git_munmap() 2025-11-18 09:36:05 -08:00
msvc-posix.h compat/msvc: use _chsize_s for ftruncate 2026-06-15 07:45:40 -07:00
msvc.c
msvc.h compat/mingw: split out POSIX-related bits 2025-02-18 10:55:39 -08:00
nonblock.c
nonblock.h
obstack.c
obstack.h
open.c object-file: move `git_open_cloexec()` to "compat/open.c" 2025-04-15 08:24:35 -07:00
posix.h win32: ensure that `localtime_r()` is declared even in i686 builds 2026-06-22 06:00:30 -07:00
pread.c
precompose_utf8.c Merge branch 'ih/precompose-flex-array' 2026-07-16 23:05:48 -07:00
precompose_utf8.h precompose_utf8: use a flex array for d_name 2026-07-04 17:59:36 -07:00
qsort_s.c
regcomp_enhanced.c regexp: leave a pointer to resurrect workaround for Homebrew 2026-03-25 15:04:30 -07:00
setenv.c
sha1-chunked.c hash-ll: merge with "hash.h" 2024-06-14 10:26:33 -07:00
sha1-chunked.h
snprintf.c
stat.c
strcasestr.c
strdup.c
strlcpy.c
strtoimax.c
strtoumax.c
terminal.c global: trivial conversions to fix `-Wsign-compare` warnings 2024-12-06 20:20:04 +09:00
terminal.h
unsetenv.c
win32.h mingw: teach dirent about symlinks 2026-01-09 18:32:55 -08:00
win32mmap.c global: mark code units that generate warnings with `-Wsign-compare` 2024-12-06 20:20:02 +09:00
winansi.c compat/winansi: drop pre-Vista workaround 2026-04-06 10:06:22 -07:00
zlib-compat.h test-tool: add a helper to synthesize large packfiles 2026-05-09 11:25:32 +09:00