Git and Subversion protect code in opposite ways. Git makes every clone a hash-chained copy of history and leaves authorization to the server in front of it; Subversion's one server owns integrity and path-level access control. The advisory data matches: 85% of Subversion's 52 advisories hit server code, while 29 of Git's 32 hit the client.
That split decides where hardening effort should go. If you run Subversion, your risk is concentrated in Apache httpd with mod_dav_svn, in svnserve, and in the authz file that decides who reads what. If you run Git, your risk lives on every laptop and CI runner that clones a repository it did not create. This post compares the two trust models from each project's own documentation, counts every published advisory by year, severity and class, and ends with a control list for each system.
Key takeaways
- Integrity: Git names every object by its hash and chains commits by hash, so any clone can verify history on its own. Subversion clients trust the server's storage and checksums.
- Signing: Git can sign commits, tags and pushes with OpenPGP, X.509 or SSH keys. Subversion has no built-in signing; authorship comes from server authentication.
- Authorization: Subversion has path-based authorization in the product. Core Git has none: read access is all or nothing per repository, and write policy lives in server hooks or the hosting platform.
- Advisory data: 44 of Subversion's 52 advisories (85%) are in server code and 25 (48%) are denial of service. Git's list holds 32 advisories since December 2019, 29 of them (91%) in client behavior, led by local clone trust, submodules and path aliasing.
- Recency: Git published six advisories in 2025, and CVE-2025-48384 has been in the CISA Known Exploited Vulnerabilities catalog since 25 August 2025. Subversion's latest advisories are from 2024; Subversion 1.15.0 shipped on 8 October 2026.
- Counts are not risk scores. The projects disclose differently and serve very different install bases. Use the counts to locate attack surface, not to pick a winner.
Two trust models in one paragraph each
Git is distributed. A clone holds every commit, tree and blob, each named by a hash of its content, and a commit names its tree and parents by hash, so the tip commit is a commitment to all history beneath it. Any clone can serve as a remote for another. Git's core has no user accounts and no read permissions: whoever can fetch a repository gets all of it. Authentication and write policy come from the transport (SSH, or HTTP through a web server) and from hooks or a hosting platform on the receiving side.
Subversion is centralized. The server owns one repository with global revision numbers. Clients hold a working copy of one revision of a subtree, not the full history. The server authenticates users, enforces path-based read and write rules, runs hooks around each commit, and is the only party that can say what revision 41,203 contains. A client cannot independently prove history has not been rewritten.
How each system guarantees history has not been tampered with
Git: content addressing and a hash chain
Change one byte in a Git file and you get a different blob name, tree name and commit name, and different names for every descendant commit. Two people who agree on a commit hash agree on every file and ancestor below it. That is what lets one signature on a tag or commit cover an entire tree.
Git can also check objects as it receives them. The transfer.fsckObjects setting, and its per-direction forms fetch.fsckObjects and receive.fsckObjects, runs consistency checks on incoming objects so malformed or hostile objects are rejected before they land. It is off by default, which makes it one of the first settings to change on servers.
The weakness is the hash function. Git object names have been SHA-1 from the start, and SHA-1 is no longer collision resistant; the SHA-1 section below covers Git's response.
Subversion: the server is the source of truth
Subversion stores history on the server, today almost always in the FSFS backend. The server records checksums for file contents, and svnadmin verify walks the repository to check stored data. Clients compare their pristine copies against checksums too.
What Subversion lacks is independent verification. An administrator with filesystem access, or with svnadmin dump and load, can rewrite history, and the protection is operational: who has shell access, whether offline dumps exist, whether an svnsync mirror on a second host can be compared after an incident.
| Property | Git | Subversion |
|---|---|---|
| Unit of history | Commit, named by hash of content and parents | Global revision number assigned by the server |
| Who can verify history | Any clone, offline | The server; clients trust it |
| Integrity mechanism | Hash chain over all objects; optional object checks on transfer | Server-side checksums; svnadmin verify |
| Evidence of a rewrite | Downstream hashes change; signatures stop verifying | Backups, mirrors and server logs |
| Hash in use | SHA-1 with collision detection; SHA-256 repositories available | SHA-1 and MD5 checksums inside the repository format |
| Offline copy of full history | Every full clone | Only the server, mirrors and dumps |
What can be signed, and with what
Signing in Git
Git's signature format documentation lists commits, tags and merge tags as signed objects, and pushes can be signed through push certificates.
- Commits:
git commit -Sstores the signature in agpgsigheader inside the commit object. - Tags:
git tag -sappends the signature to the tag object. - Merge tags: merging a signed tag embeds the whole tag in the merge commit as a
mergetagheader, so the tag signature can still be checked later. - Pushes:
git push --signedsigns "the push request to update refs on the receiving side", per the git-push documentation. The server stores the certificate and exposes the result to its pre-receive hook throughGIT_PUSH_CERT_STATUS,GIT_PUSH_CERT_SIGNER,GIT_PUSH_CERT_NONCE_STATUSand related variables. A server-issued nonce lets the hook detect a certificate replayed from another session.
Git calls an external program for the cryptography, chosen by gpg.format: openpgp (the default), x509, or ssh. SSH signing is the easiest for most teams because developers already have SSH keys; verifiers need an allowed signers file set with gpg.ssh.allowedSignersFile. See our guides to signing Git commits with an SSH key and verifying a signed Git tag before you build.
Two caveats. A signature covers a commit hash, so it is only as strong as the hash. And Git verifies only when asked (git verify-commit, git verify-tag, or a server hook). An unsigned commit is still a valid commit, so enforcement is a policy you build.
What Subversion offers instead
Subversion cannot sign a revision. The svn:author property is set by the server from the authenticated user, and it is only as trustworthy as that authentication; CVE-2015-0251 on Subversion's advisory list describes HTTP servers that allowed svn:author spoofing.
What Subversion gives you instead is one chokepoint. Every commit passes through the server's start-commit and pre-commit hooks, which can inspect and reject the transaction. Teams that need signatures usually sign release artifacts outside the repository. That works inside one organization, but it gives downstream consumers no way to check authorship without trusting your server.
| Capability | Git | Subversion |
|---|---|---|
| Sign individual commits | Yes, git commit -S | No |
| Sign tags or releases | Yes, git tag -s | No; sign artifacts externally |
| Sign the push itself | Yes, push certificates with server nonce | No; server authentication only |
| Key types | OpenPGP, X.509, SSH | Not applicable |
| Source of authorship | Commit metadata plus optional signature | Server-assigned svn:author |
| Central enforcement point | Server hooks or hosting platform rules | Hooks on the one server |
SHA-1, SHAttered and SHA-256
Git
In February 2017 researchers published two different PDFs with the same SHA-1 hash, the attack known as SHAttered. Git's hash function transition document says that since Git 2.13.0 the default build uses a hardened SHA-1 implementation that is not vulnerable to that attack, because it detects the patterns used to build such collisions.
The same document is plain that this is a stopgap: "SHA-1 is still weak." The project chose SHA-256 in late 2018. A SHA-256 repository sets repositoryFormatVersion = 1 and extensions.objectFormat = sha256, and older Git versions refuse to open it. The design notes that the wire protocol does not yet negotiate the hash and discourages SHA-256 on public servers until it does. Our post on where SHA-1 still shows up covers the wider picture.
In practice for late 2026: collision detection removes the known technique, signatures on SHA-1 commits still mean something against it, and an organization-wide move to SHA-256 depends on every tool and hosting platform in the chain supporting it.
Subversion
Subversion's exposure was different. FSFS deduplicates content by SHA-1 (representation sharing). Subversion's SHA-1 advisory explains that when the SHAttered PDFs were committed, the server kept one copy, and later updates and commits failed with checksum errors because the files' MD5 values differed. The result was a broken repository rather than an integrity bypass.
The advisory covers "Servers running Apache Subversion up to and including 1.9.5." Releases 1.9.6 and 1.8.18 reject commits that would create a SHA-1 collision when representation sharing is enabled, which is the default. Unix pre-commit hook scripts were offered for servers that could not upgrade.
Path-based authorization: Subversion has it, Git does not
How Subversion does it
Apache httpd loads mod_authz_svn and points AuthzSVNAccessFile at an access file; svnserve points authz-db at a file in the same format. The Subversion book describes the rules:
- Sections name a path,
[/path]or[repository:/path], and set users or groups tor,rwor nothing. - The default is deny: "By default, nobody has any access to the repository at all."
- Rules inherit downward and the most specific path wins, so access to a subdirectory can be removed by setting a user to nothing there.
- Groups live in
[groups]and are referenced with@; since 1.5 there are aliases, the$authenticatedand$anonymoustokens, and~inversion. - Under
SVNParentPath, a section without a repository name applies to that path in every repository, a common source of accidental access. - Since 1.7, path matching is case sensitive.
The book also warns that per-path checks cost server time, and that over HTTP a checkout authenticates once, so unreadable subdirectories are silently skipped.
This model is why many regulated, embedded and game studios kept Subversion: one repository can hold code some people may read and others may not. The cost shows in the advisory list, where nine entries are authorization or disclosure bugs, including revision metadata leakage (CAN-2004-0749, CVE-2007-2448), unreadable paths exposed with SVNPathAuthz short_circuit (CVE-2010-3315), anonymous access not restricted under httpd 2.4 (CVE-2015-3184), paths revealed that authz should hide (CVE-2015-3187), and a regression in protecting copyfrom paths (CVE-2021-28544).
What Git has instead
Core Git has no read authorization below the repository, and its data model rules it out. A clone receives every object reachable from the refs it fetches, so any file anywhere in that history is readable. The only way to hide /billing from someone who needs /frontend is to split the repository.
Writes are different. The git-receive-pack documentation describes pre-receive, which runs once per push before any ref changes and can reject the whole push, and update, which runs per ref. Git itself enforces only receive.denyNonFastForwards; any other rule is policy the administrator or hosting platform implements, such as branch protection, required review and code owner rules.
| Need | Subversion | Git |
|---|---|---|
| Hide a directory from some readers | Path-based authz in the server | Not possible in one repository; split it |
| Restrict writes to a path | Path-based authz with rw | pre-receive or update hook, or platform rules |
| Default stance | Deny unless granted | Whoever can fetch reads everything |
| Typical failure mode | Server bug exposes hidden paths | Restricted file committed anywhere in history |
Server attack surface: mod_dav_svn and svnserve vs git-daemon, git-http-backend and SSH
Subversion servers
- httpd with mod_dav_svn speaks a WebDAV-based HTTP protocol and gets httpd's authentication, TLS and mod_authz_svn. It is where Subversion's advisories concentrate: 17 of 52 name mod_dav_svn and four more name mod_authz_svn.
- svnserve listens on TCP port 3690. The Subversion book documents its defaults:
anon-accessisreadandauth-accessiswrite, so an unconfigured server lets anonymous users read. Its password file holds plainname = passwordpairs. Built-in CRAM-MD5 never sends the password but offers no encryption; SASL withmin-encryptionandmax-encryptioncan require an encrypted session, andsvn+ssh://hands authentication to SSH. Seven advisories name svnserve or its protocol parser.
Ten more affect several server access methods at once, four affect repository storage or admin tools, and two sit in optional modules and contributed hook scripts: 44 of 52 in all.
Git servers
- git-daemon serves
git://on TCP port 9418. Its documentation says push is for "a closed LAN setting where everybody is friendly", because the protocol has no authentication. It serves only repositories with agit-daemon-export-okfile unless--export-allis set, and push is off by default; if enabled, anyone can push anything, including deleting refs. - git-http-backend is a CGI program that leaves authentication and TLS to the web server in front of it.
- SSH is the common write path, running
git-receive-packas the authenticated user, often withgit-shellas a restricted shell.
Git has few server advisories because little server logic lives in Git: one in git shell (2022), plus two in code servers often run for users, git archive with git log --format and .gitattributes parsing (both 2023, both critical). The bigger server surface in Git deployments is the hosting platform's web application, API, tokens and CI, which are outside this dataset.
Advisory data: how often each project has shipped security fixes
How we measured
We built both datasets on 23 October 2026 from each project's own published list.
- Subversion: every entry on the Apache Subversion security page, 52 in total: 49 with CVE or CAN identifiers and three identified only by advisory file name (a date parser overflow in 1.0.0 to 1.0.2, a mod_authz_svn deep copy disclosure, and the SHA-1 advisory). The page shows no dates, so we assigned each identified advisory to the year in its identifier. That is the reservation year, which can precede publication; CVE-2021-28544, for example, was fixed in releases announced in April 2022 per the Subversion news page. The three file-only entries are counted as undated.
- Git: every entry on the git project's security advisories list, four pages and 32 advisories, using the published date and severity on each. The list starts in December 2019, so older Git fixes are not in it, and advisories for companion tools published elsewhere (gitk, Git GUI, Git for Windows) are excluded.
- Classification: we read each title and description and assigned one primary class and one primary component, choosing what a defender would patch or configure when two fit. The labels are ours; neither project publishes a taxonomy. Anyone can reproduce the mapping from the two public lists.
- Limits: these are advisory counts, not vulnerabilities, exploits or incidents. One advisory can carry several CVEs, Git publishes in batches (nine on 13 December 2019 alone), Subversion's page has no severity ratings, and nothing is adjusted for install base or researcher attention.
Advisories by year
| Year | Subversion (by CVE ID year) | Git (by publish date) |
|---|---|---|
| 2004 | 2 | n/a |
| 2007 | 2 | n/a |
| 2009 | 1 | n/a |
| 2010 | 3 | n/a |
| 2011 | 4 | n/a |
| 2013 | 14 | n/a |
| 2014 | 5 | n/a |
| 2015 | 6 | n/a |
| 2016 | 3 | n/a |
| 2017 | 1 | n/a |
| 2018 | 2 | n/a |
| 2019 | 1 | 9 |
| 2020 | 1 | 2 |
| 2021 | 1 | 1 |
| 2022 | 1 | 3 |
| 2023 | 0 | 6 |
| 2024 | 2 | 5 |
| 2025 | 0 | 6 |
| 2026 (to 23 Oct) | 0 | 0 |
| Undated | 3 | 0 |
| Total | 52 | 32 |
Years not shown had no Subversion advisories. "n/a" means the git list does not go back that far, not that Git had no security fixes then.
Subversion peaked in 2013 with 14 advisories, five of them one cluster of mod_dav_svn crash and memory bugs (CVE-2013-1845 through CVE-2013-1884). Since 2017 it has averaged about one a year. The latest two are CVE-2024-45720, a Windows client argument injection fixed in 1.14.4 on 8 October 2024, and CVE-2024-46901, a mod_dav_svn denial of service from control characters in paths, fixed in 1.14.5 on 8 December 2024. Subversion has published no advisories in 2025 or 2026 as of 23 October 2026, which describes the advisory page, not the absence of bugs.
Git's rate has risen. In the 2019 to 2025 window both datasets cover, Git published 32 advisories against Subversion's six by identifier year, and 17 of Git's came in 2023 to 2025. The git list has no 2026 entries as of our fetch; the latest batch is dated 8 July 2025.
Git advisories by severity and year
| Year | Critical | High | Moderate | Low | Total |
|---|---|---|---|---|---|
| 2019 | 0 | 5 | 0 | 4 | 9 |
| 2020 | 0 | 2 | 0 | 0 | 2 |
| 2021 | 0 | 1 | 0 | 0 | 1 |
| 2022 | 0 | 1 | 2 | 0 | 3 |
| 2023 | 2 | 2 | 2 | 0 | 6 |
| 2024 | 1 | 2 | 0 | 2 | 5 |
| 2025 | 0 | 3 | 1 | 2 | 6 |
| Total | 3 | 16 | 5 | 8 | 32 |
Nineteen of 32 (59%) are critical or high. All three critical ratings came in 2023 and 2024: the .gitattributes integer overflow and the git archive and git log --format heap overflow (January 2023), and remote code execution in recursive clones on case-insensitive filesystems with symlinks (May 2024, CVE-2024-32002).
Subversion advisories by component
| Component (primary) | Advisories | Share |
|---|---|---|
| mod_dav_svn (httpd module) | 17 | 33% |
| Several server access methods at once | 10 | 19% |
svnserve and the svn:// protocol parser | 7 | 13% |
| Client only | 5 | 10% |
| mod_authz_svn | 4 | 8% |
| Repository storage and admin tools | 4 | 8% |
| Shared libraries used by client and server | 3 | 6% |
| Optional modules and contributed hook scripts | 2 | 4% |
| Total | 52 | 100% |
Server-side rows total 44 of 52 (85%). Client-only issues are 5.
Git advisories by component
| Component (primary) | Advisories | Share |
|---|---|---|
| Clone, fetch and checkout on the client (including submodules and bundle-uri) | 21 | 66% |
| Credential prompts and credential helpers | 5 | 16% |
Patch and import tools (git apply, git fast-import) | 3 | 9% |
Code also run by servers (git shell, git archive, attribute parsing) | 3 | 9% |
| Total | 32 | 100% |
The first three rows are client-side behavior: 29 of 32, or 91%.
Ranked: the most common vulnerability classes in each system
Each advisory is counted once, in its primary class.
| Rank | Subversion class | Count (of 52) | Share | Git class | Count (of 32) | Share |
|---|---|---|---|---|---|---|
| 1 | Server denial of service (crash, assertion, memory exhaustion, entity expansion) | 25 | 48% | Local clone and repository ownership trust (hardlinks, symlinks, safe.directory) | 7 | 22% |
| 2 | Authorization bypass or hidden path and metadata disclosure | 9 | 17% | Submodule handling during recursive clone and update | 6 | 19% |
| 3 | Memory corruption | 5 | 10% | Path aliasing on checkout (NTFS, backslashes, drive letters, case-insensitive filesystems) | 6 | 19% |
| 4 | Authentication, credential and TLS handling | 4 | 8% | Credential handling (wrong server, newline confusion, helper overflow) | 4 | 13% |
| 5 | Code execution or file delivery from client input | 4 | 8% | Arbitrary file write from crafted input (git apply, fast-import, bundle-uri) | 4 | 13% |
| 6 | Repository integrity and corruption | 3 | 6% | Memory safety (heap and integer overflows) | 3 | 9% |
| 7 | Local symlink attacks on pid files | 2 | 4% | Terminal control character injection | 2 | 6% |
Subversion's top class is a remote request that knocks the server over, which is what you expect when one long-running server parses every user's requests. Its second is the authorization logic leaking what it should hide, the price of having path-level authorization at all.
Git's top three classes share one theme: a repository you did not create makes your client do something on your machine during clone or checkout. That covers trusting a repository owned by another user, following links during a local clone, writing a submodule where it should not go, and creating a file whose name means .git to a case-insensitive or NTFS filesystem.
A theme the table splits across rows is configuration and argument injection: three Git advisories from 2023 to 2025 inject config or parameters, and Subversion's CVE-2017-9800 (malicious svn+ssh URLs) and CVE-2024-45720 belong to the same family. Our post on argument injection in Git and Mercurial goes deeper.
The one Git flaw on the KEV list
CVE-2025-48384, titled "Arbitrary code execution through broken config quoting", is the clearest example of Git's client-side risk. The git advisory describes Git dropping a trailing carriage return from a config value when writing it, so during a recursive clone a submodule can be checked out to an unintended location, which can lead to an unintended script running. It is rated high, CVSS 8.0, with user interaction required. Fixed releases 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 workaround is to avoid recursive clones of untrusted repositories. CISA added it to the KEV catalog on 25 August 2025 with a federal due date of 15 September 2025.
Client-side risks: cloning untrusted Git repositories vs checking out SVN working copies
Cloning an untrusted Git repository writes an object store and working tree chosen by someone else to your disk, often followed by recursive clones of more repositories they chose. Git's defenses have grown with each advisory batch: core.protectNTFS and core.protectHFS reject names that alias .git, submodule names are validated, protocol.file.allow restricts local transport, and safe.directory stops Git honoring config in a repository owned by another user. Each exists because an advisory proved the old behavior unsafe, so version currency on every machine that clones is the most important control. Two habits carry most of the risk: recursive clones (--recurse-submodules or submodule.recurse = true), and automation such as dependency bots, indexers, coding agents and fork-triggered CI that clones repositories nobody reviewed.
Checking out a Subversion working copy is narrower in practice. Clients usually talk to a server inside the organization, and there is no submodule mechanism pulling from arbitrary servers by default, though svn:externals can reference other repositories and is worth auditing. Subversion's client advisories cover URLs and arguments (CVE-2017-9800, CVE-2024-45720), cached credentials sent to the wrong server (CVE-2014-3528) and certificate wildcard validation (CVE-2014-3522).
Both share a risk no upgrade fixes: build scripts, test scripts and package manifests in a working copy run when developers or CI use them.
What changes when you add a forge on top
A hosting platform with web UI, API, CI and webhooks changes the security model more than the choice of Git or Subversion.
- Authorization moves into the platform. Branch protection, required review and code owner rules are enforced there; Git accepts whatever the platform lets through.
- Tokens become the main credential. Personal, deploy, CI job and app tokens can read or write without a user's key, so scope and lifetime matter more than protocol.
- CI turns content into execution. A fork's pull request can carry workflow changes and build scripts; whether they run with secrets is a platform setting.
- The web app parses repository content. Rendering, archives and search run on the server, which is why Git's
git archiveand attribute parsing advisories matter most to forges.
For Subversion shops running a Git mirror during migration, that mirror has no path-level read control, so anything hidden by authz must be excluded. Subversion's SHA-1 advisory notes that authz rules and svndumpfilter exclude also work with svnsync and git-svn.
Step by step: baseline hardening for each system
These are defensive version checks and configuration. Adapt paths and groups to your environment.
Git clients, CI runners and servers
- Check the version on every machine and image that runs Git, and compare against the latest advisory batch (for CVE-2025-48384: 2.43.7, 2.44.4, 2.45.4, 2.46.4, 2.47.3, 2.48.2, 2.49.1, 2.50.1 or later):
git --version
- Check every object Git receives:
git config --global transfer.fsckObjects true
git config --global fetch.fsckObjects true
git config --global receive.fsckObjects true
- Do not set
submodule.recurseglobally on CI, and review submodule URLs before initializing them:
git config --global --get submodule.recurse
git -C project submodule status
- Keep local transport restricted and
safe.directorynarrow (never*on shared hosts):
git config --global protocol.file.allow user
git config --global --get-all safe.directory
- Sign with SSH keys and verify:
git config --global gpg.format ssh
git config --global user.signingkey ~/.ssh/id_ed25519.pub
git config --global commit.gpgSign true
git config --global tag.gpgSign true
git config --global gpg.ssh.allowedSignersFile ~/.config/git/allowed_signers
git verify-commit HEAD
git verify-tag v1.4.0
- On servers you run, check
GIT_PUSH_CERT_STATUSandGIT_PUSH_CERT_NONCE_STATUSinpre-receiveif you require signed pushes, set a secretreceive.certNonceSeed, and never enable push on git-daemon.
Subversion servers and clients
- Check versions. The 1.14 line is long-term support, 1.14.5 fixed CVE-2024-46901, 1.15.0 was released on 8 October 2026, and 1.10 reached end of life on 24 September 2023:
svn --version --quiet
svnserve --version --quiet
httpd -M | grep -i svn
- Close anonymous access in
svnserve.confand require encryption through SASL, or usesvn+ssh://:
[general]
anon-access = none
auth-access = write
authz-db = authz
[sasl]
use-sasl = true
min-encryption = 128
max-encryption = 256
- For httpd, wire in path-based authz and qualify every section with a repository name:
<Location /svn>
DAV svn
SVNParentPath /var/svn
AuthType Basic
AuthName "Subversion"
AuthUserFile /etc/svn/htpasswd
Require valid-user
AuthzSVNAccessFile /etc/svn/authz
</Location>
[groups]
release = alice, bob
[payments:/]
@release = rw
* =
[payments:/trunk/keys]
@release =
- Validate authz changes and verify storage on a schedule, keep representation sharing on (the default) so collisions are rejected, and keep dumps or an
svnsyncmirror off the main host:
svnauthz validate /etc/svn/authz
svnadmin verify /var/svn/payments
Both: the packages inside your images
- Git and Subversion are packages in base images, build agents and appliances. Scan those images and SBOMs like application dependencies so an outdated
gitorsubversionpackage is visible. Results are written as JSON under./output:
safeguard scan --image registry.example.com/ci/build-agent:latest
safeguard scan --sbom ./build-agent.cdx.json
Which controls to apply: a decision table
| If you run | Biggest exposure in the data | First controls | Second controls |
|---|---|---|---|
| Subversion over httpd | Server denial of service and authz disclosure | Current 1.14.x or 1.15.0; repository-qualified authz; svnauthz validate in change control | httpd request limits; crash monitoring; offline dumps |
| Subversion over svnserve | Unauthenticated denial of service; weak defaults | anon-access = none; SASL with encryption or svn+ssh://; patch | Firewall port 3690; lock down the password file |
| Git on laptops | Untrusted clone and submodule handling | Current Git; no recursive clones of untrusted repos; object checks | SSH commit signing; narrow safe.directory |
| Git on CI runners and bots | Same, at machine speed, near secrets | Pin and update Git in runner images; isolate jobs that clone untrusted code | Scan runner images; per-job credentials |
| Self-hosted Git servers | git shell, archive and attribute parsing; weak write policy | Patch; pre-receive policy hooks | Signed pushes; no git-daemon push |
| Either, behind a platform | Platform authorization, tokens, CI | Branch protection and review; short-lived scoped tokens; fork CI without secrets | Export audit logs; review webhooks |
Common mistakes
- Reading advisory counts as a safety ranking. Git has more recent advisories partly because far more people use and study it.
- Assuming signing is enforced because some commits are signed. Unsigned commits are valid unless a hook or platform rule rejects them.
- Leaving svnserve on defaults.
anon-access = readlets anyone who reaches port 3690 read without authz. - Unqualified authz sections under
SVNParentPath. A[/secret]section applies in every repository. - Mirroring restricted Subversion paths into Git. Git cannot hide them from anyone who can clone.
- Updating laptops and forgetting build images. Runners often carry the oldest Git and clone the most untrusted code.
- Setting
safe.directoryto*to silence a warning. That switches off the 2022 ownership protection.
FAQ
Is Git more secure than SVN?
Neither is more secure in general. Git gives independently verifiable integrity and optional signing; Subversion gives built-in path-level read control and one place to enforce policy. Git's advisories cluster in the client, Subversion's in the server.
How many CVEs does Subversion have?
The Apache Subversion security page lists 52 advisories as of 23 October 2026: 49 with CVE or CAN identifiers and 3 without. The most recent are CVE-2024-45720 and CVE-2024-46901.
How many security advisories has Git published?
The git project's list holds 32 advisories published from December 2019 to July 2025, none in 2026 as of 23 October 2026: 3 critical, 16 high, 5 moderate, 8 low.
Does SVN support signed commits?
No. Authorship comes from server authentication through svn:author, and teams that need signatures sign release artifacts separately.
Can Git restrict access to a folder?
Not for reading; a clone gets every object it can reach, so you must split the repository. Writes to paths can be restricted with pre-receive or update hooks or platform rules.
Is SHA-1 in Git still a security problem?
Less than in 2017. Since 2.13.0 Git uses hardened SHA-1 that detects the SHAttered technique, but Git's own documentation still calls SHA-1 weak, and SHA-256 interoperability across tools is limited.
Which Git vulnerability is actively exploited?
CVE-2025-48384, code execution through broken config quoting during recursive clones, added to the CISA KEV catalog on 25 August 2025.
Is Subversion still maintained in 2026?
Yes. Subversion 1.15.0 was released on 8 October 2026 per the project's news page, and 1.14 is the long-term support line.
Fix it without waiting for upstream
Fixes for Git and Subversion themselves come from the projects or your distribution, and Safeguard does not replace server hardening, authz files or hooks. Where it helps is the inventory around them: the base images, build agents and dependencies that keep outdated versions long after a fix ships, which you can trace with SBOM-based incident response.
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.
To try it, download Safeguard and read the CLI documentation.
See how Safeguard would help
The first demo is a real CLI session: you open the interactive terminal with safeguard and ask it to fix a lodash CVE. It reads the finding and advisory, asks before each command, edits package.json to lodash 4.17.21, runs npm install and npm test with your approval, and pushes nothing. The same approve-each-step flow applies when the outdated component is a Git or Subversion package pinned in a build image.
Click through it at your own pace, or open it full screen.
The second demo sets up the runner on your own machine, approves it with its device code, and scans from the terminal. Teams that keep Subversion or self-hosted Git inside a closed network can scan where the code and images live.
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 shows how you choose which tools Claude can use. Once connected, you can ask which projects contain a given Git or Subversion package version instead of checking image by image.
Click through it at your own pace, or open it full screen.
Quick check
Where do most Subversion advisories land, client or server?
Server. By our count, 44 of the 52 advisories on the Subversion security page affect server components such as mod_dav_svn, mod_authz_svn and svnserve.
Can core Git stop a user from reading one directory in a repository they can clone?
No. A clone receives every object reachable from the refs it fetches, so read restrictions below the repository level require splitting it.
Sources
- Apache Subversion security advisories
- Apache Subversion news and release history
- Apache Subversion SHA-1 collision advisory
- git/git security advisories, page 1
- git/git security advisories, page 2
- git/git security advisories, page 3
- git/git security advisories, page 4
- Git advisory GHSA-vwqx-4fm8-6qc9 (CVE-2025-48384)
- Advisory record GHSA-53gr-8h72-9w7p (CVE-2024-46901)
- CISA KEV entry mirror for CVE-2025-48384
- Git documentation: hash function transition
- Git documentation: signature format
- Git documentation: git-push
- Git documentation: git-receive-pack
- Git documentation: git-daemon
- Version Control with Subversion: path-based authorization
- Version Control with Subversion: svnserve
Last reviewed: 23 October 2026. Advisory counts reflect each project's published list on that date.