Safeguard
Supply Chain Security•

Git security in 2026: CVE trends by class and a hardening baseline

47 git advisories since 2019, one CISA KEV entry. Credential, clone and submodule bugs dominate; upgrade to a fixed release and set a hardened gitconfig.

Safeguard Security Team
41 min read

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 strict protocol.allow policy, no default submodule recursion, safe.bareRepository=explicit, a central core.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.

  1. Core git advisories. We read all four pages of the GitHub security advisory list for the git/git repository 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.
  2. Git for Windows advisories. We read both pages of the advisory list for the git-for-windows/git repository. 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.
  3. NVD records by product. We queried the NVD CVE API for records matching the CPE cpe:2.3:a:git-scm:git and listed every record by publication date and CVSS v3 score. The query returned 41 records, the oldest published in 2009.
  4. 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.

YearCore git advisories (git/git)Git for Windows advisoriesNVD records matching the git CPE (by NVD publish date)
2017n/an/a4
2018n/an/a5
20199n/a2
20202n/a5
20211n/a2
2022335
2023667
2024504
2025601
2026 (to 23 Oct)060
Total in window321535 (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 --mirror documentation 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:

PublishedAdvisoryCVEClassSeverityPatched version listed
10 Mar 2026GHSA-hv9c-4jm9-jh3x: NTLM hash leak when cloning from an attacker's serverCVE-2025-66413Credential leakHigh (7.4)2.53.0(2)
15 Apr 2026GHSA-9j5h-h4m7-85hx: clone from manipulated repositories can leak NTLM hashesCVE-2026-32631Credential leakHigh (7.4)2.53.0
14 Jul 2026GHSA-rxqw-wxqg-g7hw: heap corruption in wincred store and erase pathsnone assignedCredential helper memory safetyModerate (4.4)None listed
11 Aug 2026GHSA-xrpg-8j9v-v282: server-advertised bundle URI can trigger outbound SMBCVE-2026-62960Credential leak via protocolHigh (7.4)None listed
28 Sep 2026GHSA-v3h4-vrpr-rh9x: wincred OAuth store heap overflowCVE-2026-100407Credential helper memory safetyModerate (4.4)None listed
28 Sep 2026GHSA-5j7x-r6vf-jhq2: wincred erase path heap overflownot checkedCredential helper memory safetyModeratenot 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.

RankClassCore gitGit for WindowsTotalRated High or CriticalMain mitigation
1Credential handling and leaks (helpers, URL parsing, NTLM)46105Upgrade; OS keychain helper; credential.protectProtocol; avoid store
2Local clone and repository ownership trust7182Upgrade; safe.directory left strict; safe.bareRepository=explicit
3Windows search path, installer and GUI tool issues0886Upgrade Git for Windows; do not run Git GUI or gitk inside untrusted clones
4Submodule and recursive clone path confusion7075Upgrade; no default recursion; protocol.file.allow=user
5Path and filesystem confusion (NTFS, HFS, case folding)5054Upgrade; keep core.protectNTFS and core.protectHFS on
6Memory safety in parsers and formatters3033Upgrade; restrict git archive and git shell on servers
6File write via git apply or fast-import3031Upgrade; do not apply untrusted patches with --reject as a privileged user
8Terminal and output injection2021Upgrade; credential.sanitizePrompt
9Protocol and argument injection1011Upgrade; transfer.bundleURI=false
Total32154728

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.

ClassCore git advisories
Credential handlingGHSA-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 ownershipGHSA-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 cloneGHSA-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 filesystemGHSA-8prw-h3cq-mghm (2021), GHSA-5wph-8frv-58vj, GHSA-589j-mmg9-733v, GHSA-xjx4-8694-q2fq, GHSA-39hj-fvvf-mq4f (2019)
Memory safetyGHSA-c738-c5qq-xg89, GHSA-475x-2q3q-hvwq (2023), GHSA-rjr6-wcq6-83p6 (git shell, 2022)
File write via apply or importGHSA-2hvf-7c8p-28fx, GHSA-r87m-v37r-cwfh (2023), GHSA-2pw3-gwg9-8pqr (2019)
Terminal and output injectionGHSA-7jjc-gg6m-3329 (sideband, 2025), GHSA-hmg8-h7qf-7cxr (2025)
Protocol and argument injectionGHSA-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":

CVEKEV nameDate addedFederal due dateKnown ransomware use (CISA field)
CVE-2025-48384Git Link Following Vulnerability25 Aug 202515 Sep 2025Unknown

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).

LayerKEV entries foundFixed by upgrading core git?
Core git client1Yes
Self-hosted forge servers8No, needs the forge vendor's patch
Third-party CI actions2No, 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, .gitattributes or .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:

  1. 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.
  2. 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 deinit advisory) are rated High.
  3. 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.
  4. 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.

CVEDateWhat made paths disagreeAdvisory scorePlatforms
CVE-2018-11235May 2018Path traversal in submodule namesNVD 7.8All
CVE-2018-17456Oct 2018URL beginning with a dash read as an optionNVD 9.8All
CVE-2019-1387Dec 2019Weak submodule name validationNVD 8.8All
CVE-2024-32002May 2024Case-insensitive filesystem plus symlinks9.0 (advisory)Case-insensitive filesystems with symlink support
CVE-2025-48384Jul 2025Trailing carriage return lost on write8.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.

HelperWhere secrets are keptRisk notes
storePlain text file in your home directoryReadable by any process running as you; ends up in backups and dotfile repos
cacheIn memory for a timeoutNo disk copy, but secrets come back to every caller during the window
osxkeychainmacOS KeychainOS-managed and encrypted at rest
libsecretDesktop secret service on LinuxOS-managed; needs a desktop session
wincredWindows Credential ManagerSubject of several 2025 and 2026 memory safety advisories
Credential manager helper shipped with Git for WindowsOS stores, with OAuth flowsGit 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.

FormatKey managementVerification setupGood fit
OpenPGPSeparate GPG keyring, web of trust or published keysImport public keys; git verify-commitProjects that already use OpenPGP for releases
SSHReuses SSH keys developers already havegpg.ssh.allowedSignersFile listing principals and keysMost teams starting fresh
X.509Certificates from an internal CAgpgsm or a compatible tool, CA trust chainOrganisations 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

BranchMinimum version with all published core git advisory fixesLast core advisory fixed
2.432.43.7CVE-2025-48384, CVE-2025-48385, CVE-2025-48386 (8 Jul 2025)
2.442.44.4same
2.452.45.4same
2.462.46.4same
2.472.47.3same
2.482.48.2same
2.492.49.1same
2.502.50.1same
2.51 and laterany releaseFeature releases after July 2025
Current2.56.0 (28 Sep 2026, per git-scm.com)n/a
Git for Windows2.53.0(2) or later; newest available recommendedCVE-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 shell overflow and the 2023 git archive overflow are reached from the network.
  • If you expose git shell, keep the allowed command set minimal.
  • Do not run git daemon on any network you do not fully control; it serves the unauthenticated git:// 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 .gitmodules is checked against an allow list of URLs.
  • safe.directory names the workspace path, never *.
  • Tokens are not persisted into .git/config after 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=false as 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-submodules alias 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 store as 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 situationWhat to use
A fixed version existsAutonomous remediation opens the upgrade pull request; Gold Open Source confirms the safe version
You need to know today whether you are affectedGold Open Source lookup and "Am I affected?" checker, free and without login
You want vulnerable versions to stop shippingThe Gold scan GitHub Action in CI, plus Safeguard policies and gates
Upstream has no fix yet, or will not ship oneA custom Gold request; fork and patch (early access)
You want to start clean on new projectsPull 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

Last reviewed: 23 October 2026. Advisory counts and minimum versions change with each git release; check the linked advisory pages for the latest status.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.