Vim devs fix system-pwning text editor bug

Diehard text editor users everywhere breathed a sigh of relief this week as the open source community fixed a bug in one of the most venerable *nix programs: Vim.

The battle between Vim’s predecessor Vi and rival text editor Emacs dates back to 1976 when they were both released. Since then, they have been quasi-religions in a holy hacker war.

Richard Stallman, who wrote Emacs, famously announced the Church of Emacs, with himself as its Saint. Heathens can opt for the Cult of Vi, although Vim (Vi improved) was released in 1981 with new features and has become the de facto program when referencing Vi.

Advocates of each snipe at the other, but just so long as you want God-like control over your text editor compared to modern mass market word processors, both will serve you well and it’s all in good fun.

This week, though, a researcher found a dangerous flaw in Vim. Armin Razmjou (@rawsec) discovered a high-severity bug in the text editor that could let a remote attacker break out of the editor’s sandbox and execute arbitrary code on the host.

The attack exploits a vulnerability in a Vim feature called modelines, which lets you set variables specific to a file. As long as these statements are in the first few lines, Vim interprets them as instructions. They might tell Vim to display the file with a text width of 60 characters, for example. Or maybe you want to expand tabs to spaces to avoid another geek’s ire.

Vim is a powerful text editor that includes lots of scripting commands. Modelines is careful about what it executes. It runs many commands in a sandbox to avoid someone creating malicious text files that could alter the system. Razmjou discovered a way to make those commands run outside the sandbox.

His attach uses the :source! command followed by a filename to bypass the sandbox. It makes Vim read the file and execute commands as though the user had typed them manually.

An attacker using this technique could get a victim’s computer to do anything by persuading them to open the file. Razmjou proves it with two proof of concept programs.

The first PoC just runs a uname -a shell command that reports basic information about the OS kernel. The second is more sophisticated, opening a reverse shell on the victim’s computer (a reverse shell connects to the attacker’s machine). This code also rewrites the file when opened and hides the modeline to cover its tracks.

The bug also affects neovim, which is a refactored version of Vim with more functionality. The attacker has to do a little more work to own a system via neovim, though, because this program doesn’t allow the execute command that runs the file contents. Instead, attackers can exploit the assert_fails() or nvim-input() commands, both of which take inputs that can carry a payload.

Luckily, Vim worshippers everywhere can rejoice, because the bug has been cast out. Razmjou told the maintainers of both projects about the bug on 22 May 2019. The Vim community patched it the next day, with Neovim’s community patching it a week after notification. The bug has the code CVE-2019-12735, and NIST gives it a vulnerability rating of 8.6 (high) under CVSS 3.0.

Some versions of Linux, including Debian, ship with a custom version of the vimrc file that contains settings for the application, turning off modelines altogether, and those are safe, Razmjou says. Alternatively, you can also use the securemodelines plugin that replaces modelines, or disable modelineexpr in Vim to block expressions in modeline statements.