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)

Ouverte Adaptée aux débutants
#1,653 0 commentaires 0 réactions 0 personnes assignées Voir sur GitHub

Personne n'a encore pris cette issue.

Langage dominant
Vim Script
Étoiles
7.9k
Forks
691
Métriques de merge des PR
Aucune PR mergée en 30 j

Description

[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

Guide de contribution

Ouvrir le guide de contribution

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Piste de recherche

Commencez par runtime/pack/dist/opt/netrw/autoload/netrw.vim à s:NetrwBookHistSave() et comparez-le avec le commit Vim upstream f08ab2f4d7d2947c8dd6c179ae08ee6146a2694b. Mettez à jour le runtime inclus, puis construisez MacVim et vérifiez qu’un nom de répertoire contenant une apostrophe est persisté en toute sécurité sans exécuter de Vimscript injecté.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Évaluation

Stack technique
vim
Domaine
security
Type d'issue
Bug
Difficulté
2/5
Temps estimé
Une demi-journée
Activité
Calme
Clarté
Clairement spécifiée
Accessibilité débutants
72/100

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.