Uhhh, guys? This looks real bad

"GNU Emacs: Multiple Remote Code Execution Vectors on File Open"

https://github.com/califio/publications/blob/main/MADBugs/vim-vs-emacs-vs-claude/Emacs.md

#emacs

publications/MADBugs/vim-vs-emacs-vs-claude/Emacs.md at main · califio/publications

Publications from Calif. Contribute to califio/publications development by creating an account on GitHub.

GitHub
@jameshowell Uh oh, this probably effects every version of Emacs, right?
@thuna @jameshowell and probably lots of other IDEs!

@jameshowell nice find, but looks more like an git issue to me. emacs is the culprit as it executes `git ls-files` but a user can do the same and wont expect that this executes attacker controlled scripts. Other IDE's probably also calling git ls-files.

The suggested fix is also overly specific. other git mechanisms execute scripts stored in .git too (hooks, diff/merge engines, signing).

Bottom line is: clone git, don't ship/touch/unpack untrusted archives that have a .git included.

@cehteh Ni, this is an Emacs problem. It's the one calling git unprompted. If it can't do that safely, it's up to Emacs to not*

@jameshowell

@tfb @jameshowell

Arguable that cripples the usefulness (anyone checked #Magit, may have the same problem).

The suggested fix is inadequate at least.

A rather drastic fix would be that git itself maintains a list of trusted repositories (the ones it cloned or initialized itself), plus a UI to add/remove/gc from this list. then only executing content from these .git's and rejects everything else.

One could implement that for emacs alone, keeping a list of trusted git repos and reject git on untrusted one. But thats not a fix on the root of the problem.

@cehteh @jameshowell This is 100% on Emacs to fix, because it is Emacs that is unprompted running git on a repository

I agree that git's design here is the problem, but to run an unsafe tool without asking isn't acceptable. Yes that will reduce the usefulness of vc-mode, but so what? A state of "this is inside a git-controlled workarea, and you'll have to do something to get more information" is really the only safe automatic use of git

@tfb @cehteh @jameshowell Git should have a "--safe" flag, or at least a "--read-only" option. Emacs just needs to read some information like the current revision off disk, not modify anything. Prompting users all the time would be a serious annoyance.

@pkal @tfb @jameshowell

That would be a easy solution. Some git repositories won't be readable then (see gitcrypt for example), but i think thats ok and a low hanging fruit. Also with --safe you have the contrary situation that you may not be able to verify commit signatures 😩

@cehteh Once the someone has decided to interact with a git checkout as such, it's probably fine to assume they intend to do so.

The really nasty corner here IMO is that you might not be aware that you're finding a file in a working copy, nor that editing a file from it might involve executing something outside of Emacs

@pkal @jameshowell

@pkal @cehteh @jameshowell I agree, but git doesn't have such a flag. Maybe Emacs needs its own read-only git implementation, like how it has rcs2log and hexl
@tfb @cehteh @jameshowell I wonder if Emacs could approximate this by always starting Git with --config options that would overwrite exploits of this kind.

@pkal @tfb @jameshowell

That is what Claude suggested as fix, but incomplete. It would be a pretty bad practice to do so because then one has to chase whatever git implements and sanitize it, always leaving a gap for exploits. Furthermore some repositories only work when certain things are enabled. not running git at all when the repository is not trusted (maintaining a list in emacs or git) or having a --safe/--untrusted flag in git would be one solution. There are other possible solutions could be that configs must be signed. I would probably prefer some hybrid approach, having a global .gitdirs with patterns like .gitignore and flags what to do with .git's that match (trust, dont trust, check signature (and add)) etc. but all comes with some drawbacks (performance)

@tfb @cehteh @jameshowell this won't make me popular, but I think there's a git problem _and_ an emacs problem.

Git knows that .git/config is dangerous. It will refuse to do operations that depend on it, if you cd into a git checkout owned by a different user and try to run (even readonly) git commands there. But its starting assumption is that if a git checkout _is_ owned by the current user, then it's trustworthy. And receiving a git repo from someone else in a tarball invalidates that assumption.

An intermediate git user might know about executable things in .git/hooks and realise that, say, 'git commit' is equivalent to running code out of the tarball someone just sent you. But they might still not know about core.fsmonitor (I didn't until today), and think that 'git status' or 'git log' still ought to be safe. And even a novice user, who hasn't learned about git hooks yet, doesn't deserve to be pwned for their ignorance.

I *have* run git commands by hand on .git directories in tarballs people sent me. (Normally in the context of recruitment coding tests a few years ago – if the candidate's solution tarball includes git history then that gives useful insights.) So I'd have been vulnerable to an attack via core.fsmonitor even if I were not an Emacs user at all.

The Emacs issue makes this worse, because even if you knew the git repo was potentially hostile and were carefully not running git commands in it, oops, emacs has run one anyway on your behalf. Worse still, if you didn't even _know_ there was a .git directory there, because it doesn't show up in the default 'ls', emacs *has* noticed, and started using it without you having the chance to decide whether to trust it.

@cehteh @tfb @jameshowell

I think a solution may be this tar argument.

--exclude-vcs Exclude version control system directories.

The problem is if someone slips you an untrusted .git/config it can execute code on your system.

but untrusted .git/ directories can run arbitrary code through a number of other mechanisms as well.

It's probably not a great idea to unpack something without reviewing its contents first.

I'm pretty sure if you git clone, the config file only contains settings you set.

@alienghic The solution can't be "just don't download a nefarious zip/tarball". Also think about how an Emacs user would look at the contents of an archive before unpacking : using Emacs, which will helpfully unarchive it to temp storage and run git on it when you look at a file.

The solution needs to be Emacs not running unsafe commands unbidden.

@cehteh @jameshowell

@tfb @cehteh @jameshowell

I am an emacs user, I download archives and extract them with the shell. This issue reminds me that a .git directory contains code and shouldn't be trusted.

Git probably should have a some mark that when you move a git repo to another machine anything that can execute code is blocked until you mark the repo as trusted.

@alienghic @cehteh @tfb @jameshowell Git actually has something similar, if the repository is owned by another user, it won't even parse the config. See the `safe.directory` option. Wondering if that could be useful here..

@jameshowell

2026-03-30: Maintainers declined to address the issue, attributing it to Git

wtaf, that's an outrageous position for something they're shipping turned on by default

@tfb @jameshowell given they don't publish those mails, I'll defer judgment for now. I would not be surprised if the mail does in fact address the concern, just not the way the reporters wanted.
@tfb @jameshowell I agree. If I open the file with 'less', there's no remote code execution; if I myself run 'git ls-files', then that's my problem. But if I have no idea what git even is, and just open a readme in emacs, I don't expect that to run any code. #emacs
@jameshowell I trust the maintainers over Claude

@jameshowell We should have a poll about whose fault this is

(my vote: 50% breaking-in-while-already-inside-the-door, 40% git, 10% emacs)

@jameshowell has this been reported to maintainers?

why is it called "multiple vulnerabilities"? i only see one.

@mekeor @jameshowell seems to have been. the document says the maintainers concluded that it is a git issue

@jameshowell Agreed with other replies that this is not an Emacs issue. (IIRC the same 'vulnerability' is also alleged in vim, based on some screenshots of a discord(?) conversation I saw earlier.)

The user has downloaded a git repository without verifying it. It's surprising that the git repository executes code and that it's malicious; but that seems to me like it's either the user's problem (don't download unverified git repos in tarballs) or git's (require more verification before executing code).

Edit: I mistakenly assumed that running git when opening a file is not emacs' default behaviour but on a second look it seems that it is. Nevertheless I think this is still not an emacs (or vim) problem.

Does it? The attacker needs to be able to control the contents of your .git directory, which is not copied by git clone. Git cloning a repository will not leave you vulnerable, this is why the PoC gets the reproducer with wget.

Getting a git repo without a 'git clone' is a vector for this kind of attack: git hooks can run arbitrary code, so if you copy a .git directory in full from an untrusted source, you're vulnerable. Your security model needs to be that a .git directory can execute arbitrary code. Downloading it, rather than cloning it, is not secure.

In other news, if someone is sitting in your living room, they can unlock your front door from the inside, so your locks must be defective!


@ori I don't know, have none of the tarballs you have downloaded ever contained a .git?

On MacOS, you have metadata on downloaded files and get warned when you try to execute it. Maybe FLOSS also needs that, in desktops and shells like Emacs.

[ I wonder what #HaikuOS does ]

@jameshowell
I wonder if these sorts of attacks apply to things like starship that query a directory for git properties upon changing to the directory.