Git's own advisory pages list 47 security advisories since December 2019: 32 for core git and 15 for Git for Windows. Credential handling, local clone trust and submodule path confusion are the classes that keep coming back. One core git bug, CVE-2025-48384, is in CISA's Known Exploited Vulnerabilities catalog. The fix is a current git release plus a short, hardened configuration on every laptop, CI runner and server.
That is the answer in three sentences. The rest of this post shows where the numbers come from, why three public datasets give three different totals, and which settings map to which class of bug. It ends with a copy and paste ~/.gitconfig, a server baseline and a CI checklist.
Key takeaways
- Counting from git's own GitHub advisory pages on 23 October 2026, core git has published 32 advisories (December 2019 to July 2025) and Git for Windows 15 (April 2022 to September 2026). Six of the Git for Windows advisories were published in 2026; core git published none in 2026 as of that date.
- Ranked by count across both projects, the top classes are credential handling and leaks (10), local clone and repository ownership trust (8), Windows search path and GUI tool issues (8) and submodule or recursive clone path confusion (7).
- Submodule and path confusion bugs are the most severe on average: 5 of the 7 submodule advisories are rated High or Critical, and two of the three Critical core advisories involve clone or attribute parsing.
- Exactly one core git CVE appears in CISA KEV: CVE-2025-48384, added 25 August 2025 with a federal due date of 15 September 2025. Several git forges and CI actions appear in KEV too, but those are separate products and should not be counted as "git".
- NVD's product match for git returns 41 CVE records in total and misses several recent core git CVEs, including CVE-2024-32002. Do not build a fleet policy on a CPE query alone.
- The minimum safe floors for core git branches are 2.43.7, 2.44.4, 2.45.4, 2.46.4, 2.47.3, 2.48.2, 2.49.1 and 2.50.1. The current feature release on git-scm.com is 2.56.0, dated 28 September 2026. Git for Windows users need 2.53.0 or later, and two 2026 credential helper issues still list no patched version.
- Configuration closes most of the remaining gap:
transfer.fsckObjects, a strictprotocol.allowpolicy, no default submodule recursion,safe.bareRepository=explicit, a centralcore.hooksPath, an OS keychain credential helper and signed commits verified at merge time.
How we measured
We built the counts on 23 October 2026 from four primary datasets, and we kept them separate rather than summing them, because each one counts a different thing.
- Core git advisories. We read all four pages of the GitHub security advisory list for the
git/gitrepository and recorded every advisory's identifier, title, severity and publication date. The list holds 32 advisories, the oldest dated 13 December 2019 and the newest 8 July 2025. - Git for Windows advisories. We read both pages of the advisory list for the
git-for-windows/gitrepository. It holds 15 advisories, from 12 April 2022 to 28 September 2026. We opened the 2026 advisories individually to record CVE identifiers, scores and patched versions. - NVD records by product. We queried the NVD CVE API for records matching the CPE
cpe:2.3:a:git-scm:gitand listed every record by publication date and CVSS v3 score. The query returned 41 records, the oldest published in 2009. - CISA KEV. We read the full KEV catalog CSV and searched every row for git, git forges and git related CI components.
We then assigned each of the 47 advisories in datasets 1 and 2 to exactly one primary class, based on the advisory title and summary. Where a bug touched two classes (for example, CVE-2025-48384 is a config parsing bug that is reached through submodules), we used the route an attacker needs, which for CVE-2025-48384 is a recursive clone of a repository with submodules. Severity is the rating on the advisory itself, not NVD's.
What we excluded: git libraries in other languages (libgit2, JGit, go-git, GitPython and others), git hosting platforms and forges, and third-party GUI clients. Mixing those into a "git CVE" count is the most common way totals get inflated. We mention forges only in the KEV section, labelled as forges.
Limits: GitHub's advisory feature for these repositories starts in late 2019, so the advisory counts cannot cover 2017 and 2018. For those years we report NVD records only. Our class assignment is a judgement call on a handful of advisories, and we show the full mapping so you can redo it.
How many git CVEs are there per year?
Three datasets, three answers. The table below shows them side by side for 2017 through 2026.
| Year | Core git advisories (git/git) | Git for Windows advisories | NVD records matching the git CPE (by NVD publish date) |
|---|---|---|---|
| 2017 | n/a | n/a | 4 |
| 2018 | n/a | n/a | 5 |
| 2019 | 9 | n/a | 2 |
| 2020 | 2 | n/a | 5 |
| 2021 | 1 | n/a | 2 |
| 2022 | 3 | 3 | 5 |
| 2023 | 6 | 6 | 7 |
| 2024 | 5 | 0 | 4 |
| 2025 | 6 | 0 | 1 |
| 2026 (to 23 Oct) | 0 | 6 | 0 |
| Total in window | 32 | 15 | 35 (41 including 2009 to 2016) |
Sources: git/git and git-for-windows/git advisory lists, NVD CVE API, all read 23 October 2026.
Why the datasets disagree
The differences are not noise. Each one tells you something about how to track git risk.
- Batch releases move years around. Git shipped nine advisories on 13 December 2019. NVD published two of the related CVE records in December 2019 and others, such as CVE-2019-1348 and CVE-2019-1353, on 24 January 2020. The same fix lands in different calendar years depending on whose clock you read.
- Old bugs get new records. NVD published CVE-2014-9390, the case-insensitive filesystem config issue fixed in 2014, as a 2020 record. CVE-2014-9938 shows up as a 2017 record. A "CVEs per year" chart built from NVD publish dates will show these as new.
- The CPE match misses recent bugs. Our CPE query did not return CVE-2024-32002, the Critical recursive clone bug from May 2024, or five of the six core advisories from 2025. It returned exactly one 2025 record: CVE-2025-48384. If your scanner or asset tool relies on that CPE alone, it will under-report git exposure for the last two years.
- Identifier year and publish year differ. Git for Windows advisory GHSA-hv9c-4jm9-jh3x carries CVE-2025-66413 but was published in March 2026. Another Git for Windows advisory published in July 2026 has no CVE at all.
- Some issues sit outside the advisory list. The Git for Windows 2.50.1 announcement on 8 July 2025 listed nine CVEs, including four for the bundled gitk and Git GUI tools (CVE-2025-27613, CVE-2025-27614, CVE-2025-46334, CVE-2025-46835). Those four do not appear in either advisory list we counted.
- At least one record is disputed. NVD lists CVE-2022-24975 (the
--mirrordocumentation issue sometimes called "GitBleed") and notes that several parties dispute it.
The practical rule: track git by the project's own advisories and release announcements first, and use NVD and CPE matches as a cross-check, not the source of truth.
What 2026 looks like so far
Core git published no new advisories in the git/git list between January and 23 October 2026. That does not mean 2026 was quiet. Git for Windows published six:
| Published | Advisory | CVE | Class | Severity | Patched version listed |
|---|---|---|---|---|---|
| 10 Mar 2026 | GHSA-hv9c-4jm9-jh3x: NTLM hash leak when cloning from an attacker's server | CVE-2025-66413 | Credential leak | High (7.4) | 2.53.0(2) |
| 15 Apr 2026 | GHSA-9j5h-h4m7-85hx: clone from manipulated repositories can leak NTLM hashes | CVE-2026-32631 | Credential leak | High (7.4) | 2.53.0 |
| 14 Jul 2026 | GHSA-rxqw-wxqg-g7hw: heap corruption in wincred store and erase paths | none assigned | Credential helper memory safety | Moderate (4.4) | None listed |
| 11 Aug 2026 | GHSA-xrpg-8j9v-v282: server-advertised bundle URI can trigger outbound SMB | CVE-2026-62960 | Credential leak via protocol | High (7.4) | None listed |
| 28 Sep 2026 | GHSA-v3h4-vrpr-rh9x: wincred OAuth store heap overflow | CVE-2026-100407 | Credential helper memory safety | Moderate (4.4) | None listed |
| 28 Sep 2026 | GHSA-5j7x-r6vf-jhq2: wincred erase path heap overflow | not checked | Credential helper memory safety | Moderate | not checked |
Source: git-for-windows/git advisory pages, read 23 October 2026.
Every 2026 advisory is about credentials on Windows. Three are network-reachable NTLM exposures rated 7.4, and three are local memory bugs in the wincred helper. The bundle URI advisory says the trigger requires transfer.bundleURI=true, which is a setting you can audit today.
Which classes of git bug keep coming back?
This is the ranked table the rest of the post hangs on. It covers all 47 advisories from both projects.
| Rank | Class | Core git | Git for Windows | Total | Rated High or Critical | Main mitigation |
|---|---|---|---|---|---|---|
| 1 | Credential handling and leaks (helpers, URL parsing, NTLM) | 4 | 6 | 10 | 5 | Upgrade; OS keychain helper; credential.protectProtocol; avoid store |
| 2 | Local clone and repository ownership trust | 7 | 1 | 8 | 2 | Upgrade; safe.directory left strict; safe.bareRepository=explicit |
| 3 | Windows search path, installer and GUI tool issues | 0 | 8 | 8 | 6 | Upgrade Git for Windows; do not run Git GUI or gitk inside untrusted clones |
| 4 | Submodule and recursive clone path confusion | 7 | 0 | 7 | 5 | Upgrade; no default recursion; protocol.file.allow=user |
| 5 | Path and filesystem confusion (NTFS, HFS, case folding) | 5 | 0 | 5 | 4 | Upgrade; keep core.protectNTFS and core.protectHFS on |
| 6 | Memory safety in parsers and formatters | 3 | 0 | 3 | 3 | Upgrade; restrict git archive and git shell on servers |
| 6 | File write via git apply or fast-import | 3 | 0 | 3 | 1 | Upgrade; do not apply untrusted patches with --reject as a privileged user |
| 8 | Terminal and output injection | 2 | 0 | 2 | 1 | Upgrade; credential.sanitizePrompt |
| 9 | Protocol and argument injection | 1 | 0 | 1 | 1 | Upgrade; transfer.bundleURI=false |
| Total | 32 | 15 | 47 | 28 |
Classes assigned by Safeguard from advisory titles and summaries; severities from each advisory. Read 23 October 2026.
Three patterns stand out.
Clone is the attack surface. Adding up the local clone, submodule, path confusion and credential leak classes, more than half of all advisories describe something that goes wrong while git is fetching or checking out content someone else controls. The advisory text for CVE-2024-32002 says the attack can run code during a clone "before the user has a chance" to look at the repository. That is the core reason the baseline below focuses on what git does at clone time.
Severity concentrates in path handling. Of the three Critical core advisories, one is the recursive clone bug on case-insensitive filesystems (CVE-2024-32002, scored 9.0 on the advisory) and two are integer overflows in parsers reached from repository content (.gitattributes and commit formatting, both January 2023). Submodule and filesystem confusion together account for 9 of the 28 High or Critical advisories.
Windows has its own stream. All 8 search path, installer and GUI advisories come from Git for Windows, as do 6 of the 10 credential advisories. If your fleet is mostly Windows developers, the Git for Windows release feed matters as much as core git's.
The full class mapping
So you can check our work, here is how each core git advisory was classed, grouped by class and listed by GHSA identifier from the git/git list.
| Class | Core git advisories |
|---|---|
| Credential handling | GHSA-4v56-3xvj-xvfr (wincred overflow, 2025), GHSA-r5ph-xg7q-xfrp (newline confusion, 2025), GHSA-hjc9-x69f-jqj7 and GHSA-qm7j-c969-7j4q (crafted URLs send stored credentials to the wrong server, 2020) |
| Local clone and ownership | GHSA-5rfh-556j-fhgj, GHSA-mvxm-9j2h-qjx7, GHSA-xfc6-vwr8-r389, GHSA-vm9j-46j9-qvq4 (2024), GHSA-gw92-x3fm-3g3q (2023), GHSA-3wp6-j8xr-qw85 (2022), GHSA-j342-m5hw-rr3v (safe.directory bypass, 2022) |
| Submodule and recursive clone | GHSA-vwqx-4fm8-6qc9 (CVE-2025-48384), GHSA-8h77-4q3w-gfgv (CVE-2024-32002), GHSA-v48j-4xgg-4844 (submodule deinit, 2023), GHSA-4wfr-gwrh-8mj2, GHSA-4qvh-qvv7-frc7, GHSA-44fr-r2hj-3f4x, GHSA-cj5c-9839-g2ch (2019) |
| Path and filesystem | GHSA-8prw-h3cq-mghm (2021), GHSA-5wph-8frv-58vj, GHSA-589j-mmg9-733v, GHSA-xjx4-8694-q2fq, GHSA-39hj-fvvf-mq4f (2019) |
| Memory safety | GHSA-c738-c5qq-xg89, GHSA-475x-2q3q-hvwq (2023), GHSA-rjr6-wcq6-83p6 (git shell, 2022) |
| File write via apply or import | GHSA-2hvf-7c8p-28fx, GHSA-r87m-v37r-cwfh (2023), GHSA-2pw3-gwg9-8pqr (2019) |
| Terminal and output injection | GHSA-7jjc-gg6m-3329 (sideband, 2025), GHSA-hmg8-h7qf-7cxr (2025) |
| Protocol and argument injection | GHSA-m98c-vgpc-9655 (bundle URI, CVE-2025-48385) |
One note on the sideband advisory (CVE-2024-52005): the advisory lists only a Git for Windows release as patched and says the core git patches were under discussion on the mailing list when it was published. Check your core git release notes before assuming a given version carries a fix.
Which git CVEs are in CISA KEV, and when were they added?
We read every row of the CISA KEV CSV. One entry has the vendor and product both set to "Git":
| CVE | KEV name | Date added | Federal due date | Known ransomware use (CISA field) |
|---|---|---|---|---|
| CVE-2025-48384 | Git Link Following Vulnerability | 25 Aug 2025 | 15 Sep 2025 | Unknown |
Source: CISA KEV catalog CSV, read 23 October 2026.
The KEV entry describes the bug as a link following weakness in how git handles configuration, reachable through a recursive clone. Git's own advisory (GHSA-vwqx-4fm8-6qc9, published 8 July 2025, CVSS 8.0) explains the root cause in plainer terms: git can drop a trailing carriage return when it writes certain config values, so a submodule can end up checked out somewhere other than intended, and in a specific layout a hook can run after checkout. Git's advisory lists the fix as "Upgrade to the latest Git version, or avoid recursively cloning submodules in untrusted repositories."
Help Net Security reported on 26 August 2025 that attacks had been observed in the wild but that details were not public, and that working proof of concept code circulated within days of the 8 July release. A security research team's analysis published 10 July 2025 says the bug affects git on Linux and macOS and that Windows is not affected, which matches the KEV description. We did not find exploitation details in any primary source and do not speculate about them here. For the full story, see our post on CVE-2025-48384 and its KEV listing.
Forges and CI actions are a different list
The KEV catalog also contains entries that people sometimes call "git vulnerabilities" but that are bugs in other products: self-hosted git forge servers (for example CVE-2021-22205 added 3 November 2021, CVE-2022-36804 added 30 September 2022, CVE-2023-7028 added 1 May 2024, CVE-2025-8110 added 12 January 2026, CVE-2021-39935 added 3 February 2026, CVE-2021-22175 added 18 February 2026, CVE-2026-60004 added 25 August 2026 and CVE-2026-85706 added 11 September 2026), and two compromised third-party CI actions (CVE-2025-30066 and CVE-2025-30154, added in March 2025).
| Layer | KEV entries found | Fixed by upgrading core git? |
|---|---|---|
| Core git client | 1 | Yes |
| Self-hosted forge servers | 8 | No, needs the forge vendor's patch |
| Third-party CI actions | 2 | No, needs pinning or replacing the action |
Counted from the CISA KEV CSV, 23 October 2026. Our search covered vendor, product and name fields; an entry that mentions git only in its description could be missed.
The same split applies outside KEV. In March 2026 a large hosted forge disclosed CVE-2026-3854, a flaw in how its push pipeline handled user-supplied push option values, which let a user with push access run commands on the server. The fix was in the forge's own services and its self-hosted server product (fixed in releases 3.14.25, 3.15.20, 3.16.16, 3.17.13, 3.18.7, 3.19.4 and 3.20.0), not in core git. Upgrading git on your laptop does nothing for that class, and patching your forge does nothing for CVE-2025-48384 on your laptop. Track both.
What does safe.directory protect against, and what does it not?
The git-config documentation is direct about the job: by default git "will refuse to even parse a Git config of a repository owned by someone else, let alone run its hooks." safe.directory lists exceptions to that ownership check.
It exists because of CVE-2022-24765, published 12 April 2022. On a shared Windows machine, a user could create a .git directory high in the path (for example at the root of a drive). Another user running git in a subdirectory would pick up that repository's config, and config can name programs to run. The fix made git check ownership, and safe.directory became the way to say "I trust this path anyway". A follow-up bypass, CVE-2022-29187, was fixed in July 2022. Our deeper post on the safe.directory bypass covers the history.
What it protects:
- Repositories on shared machines and shared mounts that another account created.
- Root or administrator sessions that wander into a directory a less trusted user controls.
- CI agents that run as one user over a workspace created by another.
What it does not protect:
- A repository you cloned yourself. You own it, so the ownership check passes. Every clone-time bug in the ranked table above affects repositories you own.
- Malicious content in tracked files, submodules,
.gitattributesor.gitmodules. - Anything once you set
safe.directory=*, which the docs describe as the way "to completely opt-out of this security check".
The docs also say the setting "is only respected in protected configuration", meaning system, global and command line scope. A repository cannot whitelist itself. That is the right design, and it is why the common CI workaround of git config --global --add safe.directory '*' is worth replacing with the specific workspace path.
safe.bareRepository is the companion setting. With the value explicit, git only works with bare repositories named through --git-dir or GIT_DIR, so a bare repository embedded inside a cloned project cannot be picked up just because you ran git status in that folder. Git's BreakingChanges document says the default will change from all to explicit in Git 3.0, which has no planned release date. You can set it now.
When can cloning cause code to run?
A plain git clone does not copy hooks from the remote. The githooks documentation says hooks live in $GIT_DIR/hooks by default, and that git init (which clone runs) "may copy hooks to the new repository" from your local template directory, not from the server. The post-checkout hook "is also run after git-clone", but it is your hook from your template, not the attacker's.
So how do clone-time code execution bugs happen? From the advisories we counted, there are four routes:
- A bug writes into the hooks directory. CVE-2024-32002 and CVE-2025-48384 both get a file into a place where git will later treat it as a hook. Path confusion in submodules is the usual vehicle.
- Configuration that names a program. Settings such as filters, credential helpers and editors run programs. That is why the ownership check exists and why config injection bugs (for example the 2023
git submodule deinitadvisory) are rated High. - Filters and smudge processes on checkout. CVE-2021-21300 combined case-insensitive filesystems, symlinks and a clean or smudge filter (such as a large file extension) to run a checked-out script.
- Tools other than git run inside the clone. Several Git for Windows advisories and the 2025 gitk and Git GUI CVEs involve a helper tool finding and running a program planted in the working tree.
What core.hooksPath and protocol settings change
core.hooksPath tells git to look for hooks somewhere else; the docs give /etc/git/hooks as an example. Set globally, it means hooks inside each repository's .git/hooks are not consulted. That does not fix a bug that writes files where it should not, and git's advisories still list upgrading as the fix, but it does remove the most common place those bugs aim at. Treat it as defence in depth. Our post on whether git hooks can run code on your laptop walks through the trade-offs, and git hooks supply chain controls covers team rollout.
Protocol settings control which transports clone, fetch and push may use. The git-config docs list the defaults: http, https, git and ssh are always; ext is never; everything else, including file, is user, which means allowed when you typed it but not when a submodule or other indirect source asks for it. Many local clone bugs in the ranked table rely on a submodule pointing at a local path, so keeping file at user matters.
Why do submodules keep showing up?
Submodules appear in our table in 2019, 2023, 2024 and 2025, and the CVE record trail goes back to CVE-2018-11235 (May 2018), which NVD describes as a crafted .gitmodules leading to code execution during clone through path traversal and untrusted submodule hooks.
The reason is structural. A submodule turns data from the remote, the .gitmodules file, into paths and URLs that git then acts on: it creates directories, writes a nested git directory, fetches from another URL and checks out files. Every one of those steps has to agree with every other step about what a path means. Carriage returns (CVE-2025-48384), case folding plus symlinks (CVE-2024-32002), names that look like options (CVE-2018-17456) and NTFS quirks (the December 2019 batch) are all ways to make two steps disagree.
| CVE | Date | What made paths disagree | Advisory score | Platforms |
|---|---|---|---|---|
| CVE-2018-11235 | May 2018 | Path traversal in submodule names | NVD 7.8 | All |
| CVE-2018-17456 | Oct 2018 | URL beginning with a dash read as an option | NVD 9.8 | All |
| CVE-2019-1387 | Dec 2019 | Weak submodule name validation | NVD 8.8 | All |
| CVE-2024-32002 | May 2024 | Case-insensitive filesystem plus symlinks | 9.0 (advisory) | Case-insensitive filesystems with symlink support |
| CVE-2025-48384 | Jul 2025 | Trailing carriage return lost on write | 8.0 (advisory) | Linux and macOS |
Sources: NVD records and git/git advisories, read 23 October 2026.
For a step by step look at the 2024 case, see our CVE-2024-32002 walkthrough.
The setting to avoid is default recursion. submodule.recurse "defaults to false", according to the git-config docs. Keep it that way, and do not add --recurse-submodules to clone aliases, scripts or CI steps that touch repositories you do not control. When you need submodules, clone first, read .gitmodules, and then run git submodule update --init for the paths you expect. The CVE-2024-32002 advisory also notes that the attack does not work if symlink support is disabled with core.symlinks false; that breaks repositories that rely on symlinks, so use it as a temporary measure while you roll out an upgrade, not as a permanent setting. Scanning gaps that submodules create are covered in git submodules and vulnerability scans.
Credential helpers: where passwords live and how they leak
Credential handling is the top class in our ranked table, so it deserves its own baseline.
| Helper | Where secrets are kept | Risk notes |
|---|---|---|
store | Plain text file in your home directory | Readable by any process running as you; ends up in backups and dotfile repos |
cache | In memory for a timeout | No disk copy, but secrets come back to every caller during the window |
osxkeychain | macOS Keychain | OS-managed and encrypted at rest |
libsecret | Desktop secret service on Linux | OS-managed; needs a desktop session |
wincred | Windows Credential Manager | Subject of several 2025 and 2026 memory safety advisories |
| Credential manager helper shipped with Git for Windows | OS stores, with OAuth flows | Git for Windows often uses this instead of wincred, which the 2026 wincred advisory says reduces exposure |
Our comparison of git credential cache and store goes deeper on the first two.
Leaks through crafted URLs have their own history. The April 2020 advisories (CVE-2020-5260 and CVE-2020-11008) describe malicious URLs making git send a stored credential to the wrong server. The January 2025 advisories describe newline confusion in the helper protocol (CVE-2024-52006) and control sequences in account names shown in prompts (CVE-2024-50349). Git responded with two settings that the git-config docs now describe as on by default: credential.protectProtocol rejects carriage returns in the protocol sent to helpers, and credential.sanitizePrompt stops user names and hosts in prompts from containing control characters. Do not turn either off.
The 2026 Git for Windows advisories add NTLM to the picture. Two of them say a clone or fetch from an attacker's server could expose an NTLM hash, and one advisory notes that by default NTLM authentication "does not need any user interaction". The fix is Git for Windows 2.53.0 or later. For the bundle URI variant (CVE-2026-62960), the advisory lists no patched release and names transfer.bundleURI=true as the trigger, so set it to false fleet-wide until a fix ships.
Two more settings are worth knowing. credential.useHttpPath makes git treat the URL path as part of the credential key, which stops one token being offered to every repository on the same host. It "defaults to false". And git config --show-origin --get-all credential.helper shows which helper is actually in use and which file set it, which is the fastest audit you can run on a laptop.
What transfer.fsckObjects and protocol.allow block
transfer.fsckObjects tells git to check every object it receives. The docs say that "when set, the fetch or receive will abort in the case of a malformed object or a link to a nonexistent object". It defaults to false. Setting it covers both fetch and receive; fetch.fsckObjects and receive.fsckObjects let you set one side only.
What it blocks: malformed trees and commits, including the kinds of tree entries that several path confusion fixes added checks for, such as names that would land inside .git or that collide on case-insensitive or NTFS filesystems. Many git security releases add new fsck checks alongside the code fix, so a server with receive.fsckObjects on refuses to accept and redistribute those objects even to clients that are not yet patched.
What it does not block: valid objects with harmful content. A perfectly well formed script, a valid .gitmodules with a hostile URL, or a dependency manifest that pulls a vulnerable package all pass fsck.
protocol.allow sets the default policy for any transport without its own protocol.<name>.allow rule. A deny-by-default policy that allows only https and ssh blocks the unauthenticated git:// protocol, the ext remote helper that runs commands, and indirect local file access. Our explainer on transfer.fsckObjects and protocol.allow has worked examples.
Signed commits and tags: SSH, OpenPGP or X.509?
Git supports three signature formats through gpg.format: openpgp (the default), x509 and ssh. Signing does not stop any of the CVEs in our tables, because those bugs fire on content regardless of who signed it. What signing gives you is attribution: a way to tell at merge time whether a commit came from a key you trust.
| Format | Key management | Verification setup | Good fit |
|---|---|---|---|
| OpenPGP | Separate GPG keyring, web of trust or published keys | Import public keys; git verify-commit | Projects that already use OpenPGP for releases |
| SSH | Reuses SSH keys developers already have | gpg.ssh.allowedSignersFile listing principals and keys | Most teams starting fresh |
| X.509 | Certificates from an internal CA | gpgsm or a compatible tool, CA trust chain | Organisations with existing PKI and smart cards |
Turning on signing is two settings (commit.gpgSign and tag.gpgSign). The git-config docs warn that signing every tag automatically in scripts "can result in a large number of tags being signed", so think about where automation signs on your behalf.
Verification is where most teams stop short. A signature nobody checks is decoration. Check it in CI on the merge target, not only on the developer's machine:
# Verify every commit in a pull request range against your allowed signers
git config gpg.ssh.allowedSignersFile .github/allowed_signers
git log --format='%H %G? %GS' origin/main..HEAD
# %G? prints G for a good signature; fail the job on anything else
git log --format='%G?' origin/main..HEAD | grep -qv '^G$' && exit 1 || true
merge.verifySignatures makes git merge refuse unsigned or untrusted commits locally, which helps maintainers who merge by hand.
Is SHA-256 usable today?
Partly. Git's BreakingChanges document says "the default hash function for new repositories will be changed from 'sha1' to 'sha256'" in Git 3.0, and that "there is no planned release date for this breaking version yet". It also says there is "no plan to deprecate the 'sha1' object format at this point in time." You can create a SHA-256 repository today with git init --object-format=sha256 or init.defaultObjectFormat, but interoperability with hosting platforms, libraries and tools varies. Our companion post in this series covers readiness layer by layer. For this baseline, the point is narrower: none of the 47 advisories we counted depends on SHA-1 collisions, so moving hash functions is not a substitute for patching.
Minimum safe git versions as of 23 October 2026
| Branch | Minimum version with all published core git advisory fixes | Last core advisory fixed |
|---|---|---|
| 2.43 | 2.43.7 | CVE-2025-48384, CVE-2025-48385, CVE-2025-48386 (8 Jul 2025) |
| 2.44 | 2.44.4 | same |
| 2.45 | 2.45.4 | same |
| 2.46 | 2.46.4 | same |
| 2.47 | 2.47.3 | same |
| 2.48 | 2.48.2 | same |
| 2.49 | 2.49.1 | same |
| 2.50 | 2.50.1 | same |
| 2.51 and later | any release | Feature releases after July 2025 |
| Current | 2.56.0 (28 Sep 2026, per git-scm.com) | n/a |
| Git for Windows | 2.53.0(2) or later; newest available recommended | CVE-2025-66413, CVE-2026-32631 |
Sources: git/git advisories, Git for Windows advisories, git-scm.com, read 23 October 2026.
Older branches (2.42 and below) received fixes in earlier batches, for example 2.42.2 and 2.39.4 for CVE-2024-32002, but are not listed as fixed for the July 2025 advisories, so treat anything older than 2.43 as out of support. Linux distributions backport fixes into their own version strings, so compare against your distribution's security tracker rather than the upstream number. The CVE-2025-48384 coverage from Help Net Security also notes that macOS users should update the git that ships with the developer command line tools, which is separate from any git installed through a package manager.
Three Git for Windows advisories from July to September 2026 list no patched version yet. For those, the mitigations are configuration: avoid wincred if you do not need it, and keep transfer.bundleURI off.
Step by step: a hardened baseline
1. Find out what you are running
git --version
git version --build-options
which -a git # more than one git on PATH is common on macOS
git config --show-origin --list | grep -Ei 'safe\.|protocol|fsck|hooksPath|credential|submodule|bundle'
On servers and in images:
dpkg -l git 2>/dev/null | tail -1 # Debian and Ubuntu
rpm -q git 2>/dev/null # RHEL, Fedora, SUSE
apk info -v git 2>/dev/null # Alpine
docker run --rm --entrypoint git your-ci-image:tag --version
2. Upgrade
Use your package manager or the Git for Windows installer, then re-run git --version. On macOS, check both the package manager git and the one under the developer command line tools.
3. Apply the client baseline
This is a copy and paste ~/.gitconfig fragment. Review each line against your workflows before rolling it out; two settings (protocol.allow and core.hooksPath) change behaviour that some teams depend on.
# ~/.gitconfig security baseline, reviewed 23 October 2026
[transfer]
fsckObjects = true # abort on malformed or dangling objects
bundleURI = false # keep server-advertised bundle URIs off
[fetch]
fsckObjects = true
[protocol]
allow = never # deny any transport not listed below
[protocol "https"]
allow = always
[protocol "ssh"]
allow = always
[protocol "file"]
allow = user # only when you type a local path yourself
[protocol "ext"]
allow = never
[protocol "git"]
allow = never # unauthenticated git:// transport
[submodule]
recurse = false # explicit, even though false is the default
[safe]
bareRepository = explicit # will become the default in Git 3.0
[core]
hooksPath = ~/.config/git/hooks # central, reviewed hooks only
protectNTFS = true
protectHFS = true
[credential]
helper = osxkeychain # macOS; use libsecret on Linux desktops,
# the bundled credential manager on Windows
useHttpPath = true
[gpg]
format = ssh
[gpg "ssh"]
allowedSignersFile = ~/.config/git/allowed_signers
[commit]
gpgSign = true
[tag]
gpgSign = true
Or apply it with commands, which is easier to push through a device management tool:
git config --global transfer.fsckObjects true
git config --global fetch.fsckObjects true
git config --global transfer.bundleURI false
git config --global protocol.allow never
git config --global protocol.https.allow always
git config --global protocol.ssh.allow always
git config --global protocol.file.allow user
git config --global protocol.ext.allow never
git config --global submodule.recurse false
git config --global safe.bareRepository explicit
git config --global core.hooksPath "$HOME/.config/git/hooks"
git config --global credential.useHttpPath true
mkdir -p "$HOME/.config/git/hooks"
If transfer.fsckObjects rejects an old internal repository because of a known harmless issue, skip that one check for that one repository with fetch.fsck.<msg-id> ignore rather than turning fsck off globally.
4. Apply the server baseline
For bare repositories you host yourself, including mirrors:
git config --system receive.fsckObjects true
git config --system receive.denyNonFastForwards true
git config --system receive.denyDeletes true
git config --system protocol.ext.allow never
git config --system uploadpack.allowAnySHA1InWant false
Then:
- Keep the server's git on a current release. Server-side bugs such as the 2022
git shelloverflow and the 2023git archiveoverflow are reached from the network. - If you expose
git shell, keep the allowed command set minimal. - Do not run
git daemonon any network you do not fully control; it serves the unauthenticatedgit://protocol. - Patch the forge separately. Track your forge vendor's advisories alongside git's.
5. Harden CI
# Example CI checkout settings (GitHub Actions syntax)
- uses: actions/checkout@v4
with:
submodules: false # never recurse for untrusted pull requests
persist-credentials: false # do not leave a token in .git/config
fetch-depth: 1
- name: Enforce git floor
run: |
v=$(git --version | awk '{print $3}')
printf '%s\n%s\n' "2.50.1" "$v" | sort -V -C || { echo "git $v is below floor"; exit 1; }
- name: Workspace trust
run: git config --global --add safe.directory "$GITHUB_WORKSPACE"
CI checklist:
- Runner images pin a git version at or above the floor in the table, and rebuild when git ships a security release.
- Submodules are fetched only for trusted branches, and only after
.gitmodulesis checked against an allow list of URLs. -
safe.directorynames the workspace path, never*. - Tokens are not persisted into
.git/configafter checkout. - Jobs that process untrusted pull requests run without secrets and without write tokens.
- Commit signatures on the merge target are verified in a required check.
- The forge and any self-hosted runners are on the vendor's latest patched release.
Common mistakes
- Counting forges and libraries as git. A self-hosted forge bug in KEV is not a git client bug, and a libgit2 or go-git CVE is not fixed by upgrading the git binary. Keep separate inventories.
- Trusting a CPE query for coverage. Our NVD CPE query missed CVE-2024-32002 and most of 2025. If your tooling depends on it, add the project advisories as a feed.
- Setting
safe.directory=*to silence an error. That opts out of the check entirely. Name the path. - Treating
core.symlinks=falseas a permanent fix. It was a stopgap for CVE-2024-32002. Upgrade, then turn it back on if your repositories need symlinks. - Aliasing clone to recurse. A
git clone --recurse-submodulesalias makes every clone of an untrusted repository the riskiest kind of clone. - Upgrading one git and missing the others. macOS developer tools, IDE bundled git, container images and CI runners each carry their own copy.
- Signing without verifying. Signatures only help if a required check rejects commits that fail verification.
- Leaving
storeas the credential helper. A plain text token file is readable by every process running as that user. - Forgetting Windows. Six advisories in 2026 so far came from Git for Windows, all about credentials. A Linux-first baseline misses them.
FAQ
How many vulnerabilities does git have?
It depends on the dataset. As of 23 October 2026, core git's GitHub advisory list holds 32 advisories (December 2019 to July 2025), Git for Windows holds 15, and an NVD query for the git product CPE returns 41 CVE records going back to 2009. The NVD query misses several recent core git CVEs.
Is CVE-2025-48384 the only git CVE in CISA KEV?
It is the only KEV entry with vendor and product both listed as Git, based on our full read of the KEV CSV on 23 October 2026. KEV also lists several git forge servers and two compromised CI actions, which are separate products.
What git version should I be on in October 2026?
At least 2.43.7, 2.44.4, 2.45.4, 2.46.4, 2.47.3, 2.48.2, 2.49.1 or 2.50.1 on those branches, or any release from 2.51 onward. The current release listed on git-scm.com is 2.56.0. On Windows, use Git for Windows 2.53.0(2) or later.
Does git clone run hooks from the remote repository?
No. Clone does not copy the remote's hooks. Hooks come from your local template directory or core.hooksPath. Clone-time code execution bugs work by getting a file into a hooks location or by abusing configuration and filters, which is why upgrading matters even though clone itself does not copy hooks.
Is it safe to clone with --recurse-submodules?
Only for repositories you trust. Several High and Critical git advisories, including the KEV-listed CVE-2025-48384 and CVE-2024-32002, require a recursive clone. For untrusted repositories, clone without recursion, read .gitmodules, then initialise only the submodules you expect.
What does safe.directory actually do?
It lists directories git should treat as trusted even though another user owns them. It defends shared machines and CI workspaces against a planted repository. It does nothing for repositories you clone yourself, and setting it to * disables the protection.
Should I turn on transfer.fsckObjects?
Yes, for clients and especially for servers. It makes git abort on malformed objects. A few old repositories may trip a specific check; ignore that one check for that repository rather than disabling fsck.
Which git credential helper is safest?
Use the operating system's keychain: osxkeychain on macOS, libsecret on Linux desktops and the bundled credential manager on Windows. Avoid store, which writes plain text. On Windows, check whether you use wincred, which has open advisories in 2026.
Does moving to SHA-256 make git more secure against these CVEs?
No. None of the 47 advisories we counted depends on SHA-1 collisions. SHA-256 addresses object integrity over the long term; it does not fix path handling, credential or clone bugs.
Do git library CVEs (libgit2, go-git, JGit) count as git CVEs?
Not in this post. They are separate codebases with separate advisories and separate fixed versions. Track them as application dependencies, because they ship inside your software rather than on a developer's machine.
Fix it without waiting for upstream
The git client itself is a runtime you install, so its fixes come from the git project, Git for Windows or your distribution. But git also ships inside your software, as libraries in your dependency tree and as a package in your container images, and that is where the steps below apply.
Whatever the vulnerability, most of the risk sits in two gaps. The first is the time between a fix being published and that fix actually running in your production builds. The second, and worse, is the time before any fix exists at all, while a maintainer works out a patch and a release schedule. Waiting through both gaps is a habit, not a requirement. Safeguard gives teams three ways to close them.
1. Autonomous remediation: pull requests, not tickets
When a fixed version exists, Safeguard's Griffin models open a tested, policy gated pull request that moves the affected dependency to the safe version. You can run it on one repository or in bulk across every project that carries the vulnerable version. Remediation covers eight categories, including dependencies, licenses, security posture and findings. Reachability analysis ranks the vulnerable code paths your application actually calls first, so the first pull requests you merge are the ones that matter most. Autonomous remediation ships switched off, with every category set to Manual, so your team decides how much runs on its own and what still needs a human approval.
2. Gold Open Source: the safe version in seconds, free
gold.safeguard.sh is free and needs no login. Search any CVE or package to see affected and fixed versions, CVSS, EPSS, CISA KEV status and a recommended safe version, or use the "Am I affected?" checker. The same data is available through a free read API, README status badges and RSS threat feeds. The safeguard-sh/gold-scan-action GitHub Action can fail a build on a known exploited vulnerability, on any known vulnerability, or never, so a version you have just removed cannot quietly come back in next week's merge.
3. Gold Registry: start from components that are already fixed
registry.safeguard.sh provides hardened, drop in replacements for upstream packages and container images. Every Gold artifact is held continuously to zero exploitable critical or high CVEs, zero malware and a completed license check, with SLSA L3 or higher provenance, a Sigstore signature and a public evidence page you can hand to an auditor. An artifact loses its Gold badge if it regresses. Teams can point their own package directory at the registry so hardened equivalents resolve without changing how developers install anything.
When upstream has no fix yet, or will not ship one, Safeguard first works to get the fix accepted upstream. If the issue is severe or upstream will not move, Safeguard builds a fork, fixes the vulnerability there and publishes a hardened Gold build, so you are not stuck on a maintainer's release schedule. You can also request a hardened, compatibility tested build of a specific package. This fork and patch flow is in early access today, so ask which packages it covers before you plan around it.
| Your situation | What to use |
|---|---|
| A fixed version exists | Autonomous remediation opens the upgrade pull request; Gold Open Source confirms the safe version |
| You need to know today whether you are affected | Gold Open Source lookup and "Am I affected?" checker, free and without login |
| You want vulnerable versions to stop shipping | The Gold scan GitHub Action in CI, plus Safeguard policies and gates |
| Upstream has no fix yet, or will not ship one | A custom Gold request; fork and patch (early access) |
| You want to start clean on new projects | Pull hardened components and images from Gold Registry |
One honest limit: when the vulnerable code lives in a vendor appliance, a hosted service or an operating system runtime you do not build yourself, the fix still has to come from that vendor or distribution. The steps above apply to the open source dependencies and container images you build and ship, which is where most teams carry the largest and least tracked share of their exposure.
Where Safeguard fits, and where it does not
Safeguard scans repositories, container images and SBOM files (safeguard scan --dir ., --image <name>, --sbom <file>, with JSON results under ./output). That picks up git where it ships as a component: the git package inside a CI runner or application image, and git libraries declared in your manifests. The platform shows which projects contain a given component and version, so "which of our images still carry a git older than 2.50.1" becomes a query rather than a spreadsheet. Vulnerability matching, reachability analysis, policies and gates, and autonomous fix pull requests (off by default) all apply to those components.
Safeguard does not configure developer workstations, push ~/.gitconfig settings, or patch the git binary your laptop uses. It does not patch your forge either. Those stay with your device management, your package manager and your forge vendor. The baseline in this post is the part you own directly.
See how Safeguard would help
To try these flows yourself, download Safeguard or read the CLI docs.
The first demo is a real Safeguard CLI session. It installs the CLI, opens the interactive terminal and asks it to fix a lodash CVE: the assistant reads the finding and advisory, asks before each command, bumps the version, runs the install and tests with approval and pushes nothing. The same flow applies when a scan finds a vulnerable git library such as a go-git or GitPython version in your manifests; it ends with /scan . so you can see the scan step too.
Click through it at your own pace, or open it full screen.
The second demo sets up the Safeguard runner on your own machine, approves it with its device code and scans from the terminal. That is the route for checking CI runner images for an outdated git package without sending source code anywhere else.
Click through it at your own pace, or open it full screen.
The third demo connects Claude to the Safeguard MCP server with OAuth and chooses which tools Claude can use. Once connected, you can ask which projects contain a given git library version and get the answer from your own scan data.
Click through it at your own pace, or open it full screen.
Quick check
A teammate set safe.directory to * on a shared build server to stop an ownership error. What protection did that remove?
The ownership check that stops git from reading the config of, or running hooks from, a repository another user created. Name the specific workspace path instead.
Which single habit would have avoided the trigger for both CVE-2024-32002 and CVE-2025-48384?
Not cloning untrusted repositories with submodule recursion. Both required a recursive clone, and both advisories list avoiding recursive clones of untrusted repositories alongside upgrading.
Sources
- git/git security advisories, page 1
- git/git security advisories, page 2
- git/git security advisories, page 3
- git/git security advisories, page 4
- GHSA-vwqx-4fm8-6qc9: CVE-2025-48384
- GHSA-8h77-4q3w-gfgv: CVE-2024-32002
- GHSA-7jjc-gg6m-3329: CVE-2024-52005
- Git for Windows security advisories, page 1
- Git for Windows security advisories, page 2
- Git for Windows GHSA-hv9c-4jm9-jh3x: CVE-2025-66413
- Git for Windows GHSA-9j5h-h4m7-85hx: CVE-2026-32631
- Git for Windows GHSA-rxqw-wxqg-g7hw
- Git for Windows GHSA-xrpg-8j9v-v282: CVE-2026-62960
- Git for Windows GHSA-v3h4-vrpr-rh9x: CVE-2026-100407
- Git for Windows 2.50.1 announcement, git-packagers list
- NVD CVE API, records matching cpe:2.3:a:git-scm:git
- CISA Known Exploited Vulnerabilities catalog (CSV)
- KEV record mirror for CVE-2025-48384
- git-config documentation
- githooks documentation
- gitsubmodules documentation
- Git BreakingChanges (Git 3.0)
- git-scm.com home page (current release)
- Help Net Security: Git vulnerability leading to RCE is being exploited (26 Aug 2025)
- Security research analysis of CVE-2025-48384 (10 Jul 2025)
- Hosted forge write-up on CVE-2026-3854 (push pipeline)
Last reviewed: 23 October 2026. Advisory counts and minimum versions change with each git release; check the linked advisory pages for the latest status.