Breaking Git with a carriage return and cloning RCE

dgl.cx

373 points by dgl 22 days ago


armchairhacker - 22 days ago

> The result of all this, is when a submodule clone is performed, it might read one location from path = ..., but write out a different path that doesn’t end with the ^M.

How does this achieve “remote code execution” as the article states? How serious is it from a security perspective?

> I'm not sharing a PoC yet, but it is an almost trivial modification of an exploit for CVE-2024-32002. There is also a test in the commit fixing it that should give large hints.

EDIT: from the CVE-2024-32002

> Repositories with submodules can be crafted in a way that exploits a bug in Git whereby it can be fooled into writing files not into the submodule's worktree but into a .git/ directory. This allows writing a hook that will be executed while the clone operation is still running, giving the user no opportunity to inspect the code that is being executed.

So a repository can contain a malicious git hook. Normally git hooks aren’t installed by ‘git clone’, but this exploit allows one to, and a git hook can run during the clone operation.

10000truths - 22 days ago

This is a big problem with using ad-hoc DSLs for config - there's often no formal specification for the grammar, and so the source of truth for parsing is spread between the home-grown serialization implementation and the home-grown deserialization implementation. If they get out of sync (e.g. someone adds new grammar to the parser but forgets to update the writer), you end up with a parser differential, and tick goes the time bomb. The lesson: have one source of truth, and generate everything that relies on it from that.

acheong08 - 22 days ago

Reproduced the issue after a bit: https://github.com/acheong08/CVE-2025-48384 Then immediately went to update my git version. Still not up on Arch yet. Will refrain from pulling anything but I bet it'll take quite a while for most people to upgrade. Putting it in any reasonable popular repo where there are perhaps automated pulls will be interesting.

JdeBP - 22 days ago

Reading someone quote Jon Postel in the context of CR+LF brings back memories.

* https://jdebp.uk/FGA/qmail-myths-dispelled.html#MythAboutBar...

"that may not be the most sensible advice now", says M. Leadbeater today. We were saying that a lot more unequivocally, back in 2003. (-:

As Mark Crispin said then, the interpretations that people put on it are not what M. Postel would have agreed with.

Back in the late 1990s, Daniel J. Bernstein did the famous analysis that noted that parsing and quoting when converting between human-readable and machine-readable is a source of problems. And here we are, over a quarter of a century later, with a quoter that doesn't quote CRs (and even after the fix does not look for all whitespace characters).

Amusingly, git blame says that the offending code was written 19 years ago, around the time that Daniel J. Bernstein was doing the 10 year retrospective on the dicta about parsing and quoting.

* https://github.com/git/git/commit/cdd4fb15cf06ec1de588bee457...

* https://cr.yp.to/qmail/qmailsec-20071101.pdf

I suppose that we just have to keep repeating the lessons that were already hard learned in the 20th century, and still apply in the 21st.

deanc - 22 days ago

Would homebrew itself be problematic here? Does it do recursive cloning?

At least a cursory glance at the repo suggests it might: https://github.com/Homebrew/brew/blob/700d67a85e0129ab8a893f...

Lockal - 22 days ago

"trivial modification of an existing exploit"...

Why git does not use Landlock? I know it is Linux-only, but why? "git clone" should only have r/o access to config directory and r/w to clone directory. And no subprocesses. In every exploit demo: "Yep, <s>it goes to a square hole</s> it launches a calculator".

capitol_ - 22 days ago

I'm confused about the timeline here, the tag for 2.50.1 is from 2025-06-16 ( https://github.com/git/git/tags ). And the date for 2.50.1 on https://git-scm.com is also 2025-06-16.

But it seems like almost no distributions have patched it yet

https://security-tracker.debian.org/tracker/CVE-2025-48386 (debian as an example)

And the security advisory is from yesterday: https://github.com/git/git/security/advisories/GHSA-4v56-3xv...

Did git backdate the release?

- 22 days ago
[deleted]
tempodox - 21 days ago

It's often the most inconspicuous stuff that leads to highly undesirable consequences.

lossolo - 22 days ago

It seems like Homebrew still provides a vulnerable version, the same goes for Debian Bookworm.

mrheosuper - 22 days ago

it's 2025 and we still can't decide to use /r, /n or /r/n.

therealmarv - 22 days ago

guess I have to wait a bit more... no update to git 2.50.1 on Homebrew yet.

unit149 - 21 days ago

[dead]

smaudet - 22 days ago

Is it just me or is the font an eyestrain on this blog?

sugarpimpdorsey - 22 days ago

[flagged]

b0a04gl - 22 days ago

why tf is git still running submodule hooks during clone at all. like think. youre cloning a repo which you didnt write it or audit it. and git just... runs a post checkout hook from a submodule it just fetched off the internet. even with this CRLF bug fixed, thats still bananas

TacticalCoder - 22 days ago

[flagged]

dwrodri - 22 days ago

[flagged]

dwheeler - 22 days ago

Ah yes, yet ANOTHER vulnerability caused because Linux and most Unixes allow control characters in filenames. This ability's primary purpose appears to be to enable attacks and to make it significantly more difficult to write correct code. For example, you're not supposed to exchange filenames a line at a time, since filenames can contain newlines.

See my discussion here: https://dwheeler.com/essays/fixing-unix-linux-filenames.html

One piece of good news: POSIX recently added xargs -0 and find -print0, making it a little easier to portably handle such filenames. Still, it's a pain.

I plan to complete my "safename" Linux module I started years ago. When enabled, it prevents creating filenames in certain cases such as those with control characters. It won't prevent all problems, but it's a decent hardening mechanism that prevents problems in many cases.

HappMacDonald - 22 days ago

I completely disagree with author's (oft quoted here in comments) statement:

> I find this particularly interesting because this isn't fundamentally a problem of the software being written in C. These are logic errors that are possible in nearly all languages

For Christ's sake, Turing taught us that any error in one language is possible in any other language. You can even get double free in Rust if you take the time to build an entire machine emulator and then run something that uses Malloc in the ensuing VM. Rust and similar memory safe languages can emulate literally any problem C can make a mine field out of.. but logic errors being "possible" to perform are significantly different from logic errors being the first tool available to pull out of one's toolbox.

Other comments have cited that in non-C languages a person would be more likely to reach for a security-hardened library first, which I agree might be helpful.. but replies to those comments also correctly point out that this trades one problem for another with dependency hell, and I would add on top of that the issue that a widely relied upon library can also increase the surface area of attack when a novel exploit gets found in it. Libraries can be a very powerful tool but neither are they a panacea.

I would argue that the real value in a more data-safe language (be that Rust or Haskell or LISP et al) is in offering the built-in abstractions which lend themselves to more carefully modeling data than as a firehose of octets which a person then assumes they need to state-switch over like some kind of raw Turing machine.

"Parse, don't validate" is a lot easier to stick to when you're coding in a language designed with a precept like that in mind vs a language designed to be only slightly more abstract than machine code where one can merely be grateful that they aren't forced to use jump instructions for every control flow action.

IshKebab - 22 days ago

Zero surprise there's a bug in git's quoting. That code is mental.

jftuga - 22 days ago

I wrote a CLI program to determine and detect the end-of-line format, tabs, bom, and nul characters. It can be installed via Homebrew or you can download standalone binaries for all platforms:

https://github.com/jftuga/chars