macvim-dev / macvim-dev/macvim

[Security] MacVim affected by GHSA-crm5-rh6j-2c7c — netrw NetrwBookHistSave() code injection via crafted directory name (vim < 9.2.0495)

Abierto Apto para principiantes
#1,653 0 comentarios 0 reacciones 0 asignados Ver en GitHub

Nadie ha tomado este issue todavía.

Lenguaje dominante
Vim Script
Estrellas
7.9k
Forks
691
Métricas de merge de PR
Sin PR fusionados en 30 d

Descripción

[Security] MacVim affected by GHSA-crm5-rh6j-2c7c — netrw NetrwBookHistSave() code injection via crafted directory name (vim < 9.2.0495)

Summary

MacVim bundles the vim runtime at version 9.2 (patches 1-321 in the current build), which is
below the patched version 9.2.0495 that fixes a code injection vulnerability in the netrw
plugin's s:NetrwBookHistSave() function.

Vulnerability Details

  • GHSA: GHSA-crm5-rh6j-2c7c
  • Upstream fix: vim 9.2.0495 (commit f08ab2f4d7d2947c8dd6c179ae08ee6146a2694b)
  • Affected code: runtime/pack/dist/opt/netrw/autoload/netrw.vims:NetrwBookHistSave()
  • Vulnerability type: CWE-94 — Improper Control of Generation of Code (Code Injection)

Root Cause

In s:NetrwBookHistSave(), the directory history is serialized to ~/.vim/.netrwhist using
a single-quoted Vimscript string literal without escaping embedded single quotes:

" runtime/pack/dist/opt/netrw/autoload/netrw.vim line 2961 (macvim r183)
call setline(lastline,'let g:netrw_dirhist_'.cnt."='".g:netrw_dirhist_{cnt}."'")

This generates lines of the form:

let g:netrw_dirhist_1='/some/path'

If the directory name (stored in g:netrw_dirhist_{cnt}) contains a single quote ', the
generated Vimscript breaks out of the string literal. For example, a directory named:

x'|let g:injected=1|let y='z

would generate:

let g:netrw_dirhist_1='x'|let g:injected=1|let y='z'

When ~/.vim/.netrwhist is later sourced by netrw (at vim startup via the VimLeave
autocommand that calls NetrwBookHistRead), the injected Vimscript executes.

Attack Scenario
  1. An attacker creates a directory named with an embedded single-quote followed by
    Vimscript commands:
    mkdir -p "target/x'|call system('id > /tmp/pwned')|let y='z"
    
  2. The victim opens this directory in netrw (:Explore) inside MacVim and then quits vim.
  3. s:NetrwBookHistSave() writes the crafted path to ~/.vim/.netrwhist unescaped.
  4. The next time MacVim starts and opens netrw, NetrwBookHistRead() sources .netrwhist,
    executing the injected call system('id > /tmp/pwned') command.

This provides persistent arbitrary command execution — the payload is written once and
fires on every subsequent vim startup.

Affected MacVim Code

" netrw.vim line 2961 (macvim r183)
call setline(lastline,'let g:netrw_dirhist_'.cnt."='".g:netrw_dirhist_{cnt}."'")

The directory path g:netrw_dirhist_{cnt} is interpolated directly into a single-quoted
string without any escaping.

Affected MacVim Version

MacVim r183 (vim 9.2 patches 1-321) — current HEAD as of 2026-05-18.

The fix commit f08ab2f4d7d2947c8dd6c179ae08ee6146a2694b from vim/vim is not present
in the macvim-dev/macvim repository.

Suggested Fix

Merge or cherry-pick vim/vim patches up to at least 9.2.0495.

The fix replaces the unescaped string interpolation with Vimscript's built-in string()
function, which properly double-quotes the value and escapes embedded single quotes:

" Fixed (vim 9.2.0495):
call setline(lastline,'let g:netrw_dirhist_'.cnt.'='.string(g:netrw_dirhist_{cnt}))

string() produces a safely quoted Vimscript literal (e.g., "x'|cmd" for a path
containing '), so the value round-trips safely through source.

References

Guía de contribución

Abrir la guía de contribución

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Línea de trabajo

Comienza con runtime/pack/dist/opt/netrw/autoload/netrw.vim en s:NetrwBookHistSave() y compáralo con el commit de Vim upstream f08ab2f4d7d2947c8dd6c179ae08ee6146a2694b. Actualiza el runtime incluido, después compila MacVim y verifica que un nombre de directorio que contenga una comilla simple se persista de forma segura sin ejecutar Vimscript inyectado.

Escrito por el modelo de indexación a partir del texto del issue.

Evaluación

Stack tecnológico
vim
Área
security
Tipo de issue
Error
Dificultad
2/5
Tiempo estimado
Medio día
Estado de actividad
Tranquilo
Claridad
Bien especificado
Aptitud para principiantes
72/100

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.