
Vim/Neovim Arbitrary Code Execution via Modelines - tinix
https://github.com/numirias/security/blob/master/doc/2019-06-04_ace-vim-neovim.md
======
maxdamantus
I feel like security for CLI users is generally falling behind other systems.

On Android and iOS, any application is supposedly running in its own sandbox,
where it can't just randomly access files used by the rest of the system
(including other applications).

The web is obviously strongly based around a security model where a website
ultimately can't do much in terms of information access (eg, a properly
designed website's information is protected from other websites) .. as I
understand it, this was not always the case (we're not using ActiveX anymore,
right?).

In the desktop space, this pattern is supposedly supported by Flatpak, and I
think the macOS store (though I'm not sure about this—I haven't actually used
either).

Meanwhile, when a random developer decides to run `make` or `npm install` or
`mvn install` or even `vim foo.txt`, they're essentially trusting their entire
computer to whoever created the content in their working directory.

Will there be some revolution at some point that encourages people to somehow
isolate their commandline activities to different realms, thus limiting the
scope of any attack like this?

~~~
ajross
> any application is supposedly running in its own sandbox,

But that fails for developers (which is more or less synonymous with "CLI
users"). Development is all about data and fine grained tools, not apps.

You check out a file with git, then edit it with vim, and build it with gcc,
which pulls in headers generated with a python script, itself having been
configured with, I dunno, cmake gadgetry. Where do you draw the boundaries
here?

I mean, you can draw a big circle around all your development activities.
Products have been invented that do that. They're called "IDE's", and are sort
of the metaphorical opposite of the command line tools we're discussing, and
not really a solution to the people choosing to use this environment.

Alternatively, you can view the whole development system as a sandbox. Do your
work in a separate VM or docker instance, for example. Some people actually do
that (in particular folks with windows desktops who need linux tooling will
recognize this), and while it's not generally considered a security technique,
it certainly could be.

~~~
hathawsh
I see what you're saying, but I think we can do better.

I would really like some simple way to limit what build scripts can do. For
example, they shouldn't be able to read and write arbitrary files in my home
directory, even though they should be able to read /usr/lib and the like. They
shouldn't be able to contact the Internet (or even the LAN) without explicit
permission. They shouldn't be able to do anything with my display unless I
permit it.

Is there some command available for Linux that lets me set up a quick sandbox
so I can detect and stop trojans in build scripts? Virtual machines, chroots,
containers, and Docker are all good but they don't solve this problem. SELinux
has the potential to solve this but it's extremely complex. Instead of
"./configure && make", I want to type something like "sandbox ./configure &&
sandbox make"; sandboxed build scripts should work the same as if they're
outside the sandbox.

~~~
vesinisa
What you describe is called Mandatory Access Control, which is in contrast and
supplements standard UNIX Discretionary Access Control (user/file
permissions). It is implemented on Linux with AppArmor in addition to SELinux.

I would guess the biggest hurdle in using such systems is the complexity and
expertise required in drafting the specific rules that should apply in your
threat model.

~~~
ibotty
If you craft rules for your cmdline tool you will run into problems pretty
soon despite the complexity. Better is using a wrapper that is confined. See
e.g. SELinux' sandbox(8) which is more or less a "multiwrapper" in that it
sets the context explicitly and not implicitly by being confined.

------
cjhanks
Which OS' are compiling `nc` with `-DGAPING_SECURITY_HOLE` ?

~~~
cjhanks
Jeez, what's with the down votes? Look at the netcat documentation, that's
what the configuration option for "-e" is called.

[https://ps.uci.edu/~franklin/doc/netcat.html](https://ps.uci.edu/~franklin/doc/netcat.html)
[https://stackoverflow.com/questions/15351646/how-to-re-
compi...](https://stackoverflow.com/questions/15351646/how-to-re-compile-
netcat-with-options)

~~~
jontro
How is it related to the vim vulnerability?

~~~
cjhanks
That was the proof-of-concept they used.

------
gbrown_
I have never understood the appeal of modelines. Why on earth would you put
editor specific configuration _inline_ with the file you are editing?

Thankfully I've had 'set nomodeline' in my config ever since I found out about
this insane option.

~~~
tom_
I use them in Emacs occasionally. It's handy for stuff with ambiguous names.
Makefiles (which dialect?), whatever.pl (Perl? Prolog?),
whatever.asm/whatever.s (which architecture? Which assembler?), etc.

Also comes in handy for working with files that have an incorrect extension,
for whatever reason, or different formatting from all the other files of that
type that you work with. (Per-project formatting stuff can often by solved
with .dir-locals.el, but not always.)

~~~
gbrown_
How do others feel about this when they open the files? Or are they not part
of a shared project?

~~~
tom_
Nobody seems to care, and I can easily put them back in if somebody deletes
them.

------
hannob
This should be put into perspective: The default vimrc configuration file
disables the modelines option and contains a warning that it is a security
risk.

I.e. this likely only affects a small number of users and the devs have done
as much as they can about a risky feature: Off by default and whoever changes
the option should know about the risks.

Of course it's still a valid vulnerability and it's good that it's been found
and fixed. But it's likely not a big deal.

------
cyphar
I remember reading ~10 years ago that mode-lines were considered to be
insecure (you are parsing arbitrary data as configuration options) and have
always had them disabled in my .vimrc. I'm surprised they haven't been
disabled by default (even in neovim).

EDIT: I probably was reading about CVE-2007-2438, another mode-line based RCE
attack.

------
ploxiln
This is a well known problem - thus the "securemodelines" plugin:
[https://github.com/ciaranm/securemodelines](https://github.com/ciaranm/securemodelines)

~~~
Izkata
Seems so, Ubuntu's defaults (at least in 16.04) set nomodeline with a comment
about security vulnerabilities.

------
bla3
It's mildly interesting that the neovim patch for this [1] is just an import
of the upstream vim patch [2], but with the test removed.

1:
[https://github.com/neovim/neovim/commit/4553fc5e](https://github.com/neovim/neovim/commit/4553fc5e)
2:
[https://github.com/vim/vim/commit/5357552](https://github.com/vim/vim/commit/5357552)

~~~
ryanar
I wonder if it is because neovim's testing is setup differently and they
wanted to port the patch immediately rather than spend time which they might
not have had at the moment to rewrite the test. I suppose the patch was tested
upstream, though you would want the test in neovim to prevent a future
regression.

~~~
justinnhli
A different PR is still open, that presumably would include the test:
[https://github.com/neovim/neovim/pull/10052](https://github.com/neovim/neovim/pull/10052)

------
tombert
Well crap, now I have yet another reason to lose sleep tonight. I always
thought Vim and text-files were safe.

I do find something endlessly interesting in these kinds of vulnerabilities,
for no other reason than the fact that I can appreciate the hunt for them. I
wouldn't really think to look at Vim as an attack vector, and even if I did, I
wouldn't even know where to start.

~~~
cyphar
Given that most administrators use vim to edit everything in the system and
often open random files, I would think vim is the most obvious thing to attack
(just like printers in corporate networks).

Just do "set nomodeline" and move on. I've had it disabled for the past ~10
years because of previous CVEs like this (such as CVE-2007-2438).

~~~
lloeki
or use
[https://github.com/ciaranm/securemodelines](https://github.com/ciaranm/securemodelines)
like I did for the past aeon

------
hamburglar
My system vimrc has:

    
    
      set modelines=0
    

and a comment referencing CVE-2007-2438, which was another sandbox escape via
modelines.

Seems prudent.

------
bch
nvi nipped this in the bud from inception:

modelines, modeline [off]

Read the first and last few lines of each file for ex commands.

 _This option will never be implemented._ [0]

[0] [https://netbsd.gw.com/cgi-bin/man-
cgi?vi+1.i386+NetBSD-8.0](https://netbsd.gw.com/cgi-bin/man-
cgi?vi+1.i386+NetBSD-8.0)

------
tluyben2
In which case would I open a file with vim like that? Or can it be hidden in
innocent looking files? I always first cat a file.

And never heard of modeline even though using vim for over 20 years.

~~~
paxswill
The second PoC hides the modeline when printed with `cat`.

~~~
tluyben2
Sorry, missed that one, thanks for pointing out.

------
jalgos_eminator
Very interesting exploit. Makes me feel good that I disable modelines because
my company always sets columns=96, however I usually open multiple files with
:vsp and I have to manually change the columns to what my terminal actually
is.

I would be interested to hear the historical reason for having such generic
modeline execution in the first place. It seems a little out of place in text
file editing.

~~~
gbrown_
> Makes me feel good that I disable modelines because my company always sets
> columns=96

Your company places this as a modeline in all its source files? If so why does
your place of work enforce modelines in its source?

~~~
jalgos_eminator
They don't "enforce" it, but all the code written by the two largest
contributors always has it. Its a startup, so those two contributors wrote the
majority of the codebase.

~~~
dmix
You mean they include editor configuration in all of their source code files?
Not just some special cases?

~~~
jalgos_eminator
# vim:set columns=96 expandtab nocindent nosmartindent ff=unix:

This is in basically every source code file just below the shebang.

~~~
dmix
I've never seen anyone do this. There are so many better solutions to this
problem and it's a heavy-handed/messy solution that is difficult to
change/maintain.

I'd push back on this hard if I was told to do it.

~~~
jalgos_eminator
I'm not told to do it, but I don't write hardly any of the code in the repo.
So when I have to go inspect one of their source files, which I do many times
per day, then it gets me. Usually if I'm on some VM that doesn't have my own
.vimrc in it. It is what it is, just a minor annoyance and a few key strokes
to fix (":set columns=xxx", then "C-w =").

------
isr
Scratching my head a bit but ... isn't this old news (the underlying issue,
not the github doc)?

The modelines issue (this exact issue) was widely publicised well over a
decade ago (long enough that I don't remember when).

I vaguely recall it showing up in an early gentoo security alert (pre-2005?)
which is how I became aware of it.

How does this become a new security issue now?

~~~
marshray
Simple: Modelines come from a time before we understood that ordinary user
applications working with ordinary files needed to be engineered securely.

~~~
isr
I think you missed my question :)

I understand the security concerns (arbitrary code execution just by loading
an arbitrary file into vim).

My question was: this issue was caught, diagnosed, widely publicised and the
configuration fix for it was widely deployed - nearly 15 (fifteen!) years ago.

So why is it cropping up as a "new" security issue now?

------
gfiorav
I'd like to note here that while the vim versions of OS distros get updated
every now and then, Bram does a fantastic job of releasing multiple times per
week and vim is easy to compile.

I compile it every week (I use it as my IDE -- term buffers and all).

Just in case someone here is a heavy user and is worried about this.

[https://github.com/vim/vim](https://github.com/vim/vim)

------
AzzieElbab
No !!! Not my vim

------
Pmop
I guess we have a winner for Editor Wars.

~~~
NegativeLatency
Emacs has similar functionality
[https://www.gnu.org/software/emacs/manual/html_node/emacs/Sp...](https://www.gnu.org/software/emacs/manual/html_node/emacs/Specifying-
File-Variables.html)

~~~
nonbirithm
The default behavior on Emacs is to warn you that file-local variables can be
unsafe and prompt you to execute them. However I developed the habit of mostly
ignoring it since they're usually in my own files.

[https://www.gnu.org/software/emacs/manual/html_node/emacs/Sa...](https://www.gnu.org/software/emacs/manual/html_node/emacs/Safe-
File-Variables.html)

~~~
NikkiA
The scary part for me (albeit that I'm an emacs user not really a vim user)
here is that the modeline string is hidden from the victim in their vim
window, so not only have they enabled the RCE they aren't aware of it. I'm not
sure if emacs file-local variables can be exploited in the same way (they
probably can but I'm just unaware of it)

------
fatbird
If you're heartbroken about this, it's only because you were too smug before.

~~~
fatbird
Before I go completely grey here, I'll clarify as a decades long user of
vim/neovim: no software should be so near and dear to your heart that you get
complacent about the risks it poses, most especially security risks.

Heartbreak at this announcement means you were assuming it wasn't a vector for
security weaknesses.

