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