
Analyse technique de CVE-2026-52885 : une condition de course TOCTOU dans Notepad++ v8.9.6.2 permettant l'exécution arbitraire de commandes via un contournement de l'intégrité HMAC. Inclut la cause racine, le scénario d'attaque, le PoC et l'analyse du correctif.
| GHSA | GHSA-qm4c-qg8p-qfcr |
| CVE | CVE-2026-52885 |
| Gravité | Élevée |
| Affecté | v8.9.6.2 |
| Corrigé | v8.9.6.4 |
| Commit du correctif | 4f7563c |
| Fichier affecté | PowerEditor/src/NppCommands.cpp :4328–4359 |
| Plateforme | Windows 11 Pro x64 |
| Privilège requis | Utilisateur standard (accès en écriture à shortcuts.xml) |
| Chercheur | v3s9er |
| Divulgué | 2026-06-05 |
Notepad++ v8.9.6.2 a introduit un contrôle d'intégrité HMAC-SHA256 sur shortcuts.xml pour empêcher l'injection d'entrées UserCommand arbitraires.
Le contrôle présente une faille TOCTOU : la HMAC est vérifiée contre le fichier sur disque au moment du déclenchement, mais la commande qui s'exécute est lue à partir du vecteur _userCommands en mémoire, chargé au démarrage. Ces deux sources ne sont jamais resynchronisées.
Un attaquant disposant d'un accès en écriture à shortcuts.xml peut y placer une commande malveillante avant le lancement, laisser Notepad++ la charger en mémoire, restaurer le fichier légitime sur le disque, puis déclencher la commande. La vérification HMAC réussit (le disque est propre), mais la charge utile malveillante s'exécute (la mémoire est obsolète).
Le mécanisme d'intégrité valide le shortcuts.xml actuellement sur disque, tandis que l'exécution des commandes utilise une représentation en mémoire chargée précédemment. Les deux sources de données étant indépendantes, un attaquant peut modifier le fichier avant le démarrage, le laisser être analysé en mémoire, puis restaurer le fichier d'origine avant l'exécution de la commande — ce qui permet à la vérification HMAC de réussir pendant que la charge utile malveillante s'exécute.
NppCommands.cpp lignes 4328–4359 :
// TIME OF CHECK — reads on-disk file
std::string currentHMAC = computeHMAC(
getMachineGUID(),
getFileContent(nppParams.getShortcutsPath().c_str())
);
if (currentHMAC != nppGUI._shortcutsXmlHmacInConfig) { return; }
// validated against DISK
// TIME OF USE — reads in-memory vector (loaded at startup, never refreshed)
int i = id - ID_USER_CMD;
const vector<UserCommand>& cmds = nppParams.getUserCommandList();
UserCommand ucmd = cmds[i];
Command cmd(string2wstring(ucmd.getCmd(), CP_UTF8));
cmd.run(_pPublicInterface->getHSelf()); // executes payload from MEMORY
| Opération | Source | Moment |
|---|---|---|
| VÉRIFICATION (HMAC) | Fichier sur disque | Au moment du déclenchement |
| UTILISATION (exécution) | Vecteur mémoire | Chargé au démarrage |
| FENÊTRE | Contrôlée par l'attaquant | Démarrage → Déclenchement |
Pré-condition : accès en écriture à shortcuts.xml
notepad++.exe%AppData%\Notepad++\Étapes :
shortcuts.xml sur le disque avec une version malveillante (cmd = calc.exe)_userCommands est rempli à partir du fichier malveillantshortcuts.xml légitime sur le disque — la HMAC correspond désormais à config.xmlWM_COMMAND(21000) (ID_USER_CMD+0) ou appuyer sur Ctrl+Alt+P_userCommands[0] depuis la mémoire → calc.exe s'exécuteRésultat : exécution de commandes contrôlées par l'attaquant avec les privilèges de l'utilisateur courant. Pas d'admin, pas d'UAC, pas d'avertissement utilisateur.
| Temps | Événement | État |
|---|---|---|
| T+0.0s | L'attaquant écrit un shortcuts.xml MALVEILLANT | disk=MALICIOUS |
| T+0.0s | L'attaquant lance Notepad++ | disk=MALICIOUS |
| T+0.1s | Notepad++ lit shortcuts.xml → _userCommands[0]="calc.exe" | mem=MALICIOUS |
| T+4.2s | Notepad++ entièrement chargé | mem=MALICIOUS |
| T+4.2s | L'attaquant restaure le shortcuts.xml LÉGITIME | disk=LEGIT / mem=MAL |
| T+4.7s | L'attaquant envoie WM_COMMAND(21000) | |
| T+4.7s | Vérification HMAC : lit le fichier LÉGITIME depuis le disque → RÉUSSIT | VÉRIFICATION OK |
| T+4.7s | Exécution : lit _userCommands[0] depuis la MÉMOIRE → calc.exe | EXPLOITATION |
| T+4.7s | calc.exe lancé (PID 35932) | CONFIRMÉ |
| Type | Exécution arbitraire de commandes |
| Admin requis | Non |
| Invite UAC | Non |
| Détectabilité | Faible — le disque présente un fichier légitime en permanence ; la charge utile n'existe qu'en mémoire |
| CVSS (est.) | AV:L / AC:H / PR:L / UI:N / S:U / C:H / I:H / A:H |
Voir poc_8962_toctou.ps1.
Prérequis :
doLocalConf.xml présent dans le répertoire de Notepad++ (mode portable)config.xml avec une HMAC valide pour le shortcuts.xml légitime.\poc_8962_toctou.ps1 -NppPath "C:\path\to\notepad++.exe"
Vérifié : calc.exe lancé (PID 35932), le disque présente un shortcuts.xml légitime en permanence.
Le correctif (commit 4f7563c) déplace la validation HMAC au démarrage, en même temps que l'analyse initiale du fichier. La vérification et l'utilisation opèrent désormais sur le même objet au même moment, ce qui élimine la fenêtre TOCTOU.
| v8.9.6.2 (vulnérable) | v8.9.6.4 (corrigé) | |
|---|---|---|
| Vérification HMAC | Au moment du déclenchement, relit le disque | Au démarrage, mêmes octets que lors de l'analyse |
| Source de la commande | Mémoire chargée au démarrage | Mémoire validée au démarrage |
| Fenêtre TOCTOU | Démarrage → Déclenchement | Éliminée |