
Analisi tecnica di CVE-2026-52885: una race condition TOCTOU in Notepad++ v8.9.6.2 che consente l'esecuzione arbitraria di comandi tramite bypass dell'integrità HMAC. Include causa principale, scenario di attacco, PoC e analisi della patch.
| GHSA | GHSA-qm4c-qg8p-qfcr |
| CVE | CVE-2026-52885 |
| Severity | Alta |
| Affected | v8.9.6.2 |
| Patched | v8.9.6.4 |
| Patch Commit | 4f7563c |
| Affected File | PowerEditor/src/NppCommands.cpp :4328–4359 |
| Platform | Windows 11 Pro x64 |
| Privilege Required | Utente standard (accesso in scrittura a shortcuts.xml) |
| Researcher | v3s9er |
| Disclosed | 2026-06-05 |
Notepad++ v8.9.6.2 ha introdotto un controllo di integrità HMAC-SHA256 su shortcuts.xml per prevenire l'iniezione di voci UserCommand arbitrarie.
Il controllo presenta una falla TOCTOU: l'HMAC viene verificato sul file su disco al momento dell'attivazione, ma il comando che viene eseguito è letto dal vettore in memoria _userCommands caricato all'avvio. Queste due fonti non vengono mai risincronizzate.
Un attaccante con accesso in scrittura a shortcuts.xml può inserire un comando dannoso prima dell'avvio, lasciare che Notepad++ lo carichi in memoria, ripristinare il file legittimo su disco e quindi attivare il comando. Il controllo HMAC passa (il disco è pulito), ma il payload dannoso viene eseguito (la memoria è obsoleta).
Il meccanismo di integrità valida l'attuale shortcuts.xml su disco, mentre l'esecuzione dei comandi usa una rappresentazione in memoria caricata in precedenza. Poiché le due fonti di dati sono indipendenti, un attaccante può modificare il file prima dell'avvio, consentirne l'analisi in memoria, quindi ripristinare il file originale prima dell'esecuzione del comando — facendo sì che il controllo HMAC passi mentre il payload dannoso viene eseguito.
NppCommands.cpp righe 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
| Operazione | Sorgente | Tempistica |
|---|---|---|
| CHECK (HMAC) | File su disco | Al momento dell'attivazione |
| USE (exec) | Vettore in memoria | Caricato all'avvio |
| GAP | Controllato dall'attaccante | Avvio → Attivazione |
Pre-condizione: accesso in scrittura a shortcuts.xml
notepad++.exe%AppData%\Notepad++\Passaggi:
shortcuts.xml su disco con una versione dannosa (cmd = calc.exe)_userCommands viene popolato dal file dannososhortcuts.xml legittimo su disco — ora l'HMAC corrisponde a config.xmlWM_COMMAND(21000) (ID_USER_CMD+0) o premere Ctrl+Alt+P_userCommands[0] dalla memoria → calc.exe viene eseguitoRisultato: esecuzione di comandi controllati dall'attaccante con i privilegi dell'utente corrente. Nessun admin, nessun UAC, nessun avviso per l'utente.
| Tempo | Evento | Stato |
|---|---|---|
| T+0.0s | L'attaccante scrive shortcuts.xml DANNOSO | disco=DANNOSO |
| T+0.0s | L'attaccante avvia Notepad++ | disco=DANNOSO |
| T+0.1s | Notepad++ legge shortcuts.xml → _userCommands[0]="calc.exe" | mem=DANNOSO |
| T+4.2s | Notepad++ completamente caricato | mem=DANNOSO |
| T+4.2s | L'attaccante ripristina shortcuts.xml LEGITTIMO | disco=LEGITTIMO / mem=DANNOSO |
| T+4.7s | L'attaccante invia WM_COMMAND(21000) | |
| T+4.7s | Controllo HMAC: legge il file LEGITTIMO da disco → PASSA | CHECK OK |
| T+4.7s | Esecuzione: legge _userCommands[0] dalla MEMORIA → calc.exe | EXPLOIT |
| T+4.7s | calc.exe avviato (PID 35932) | CONFERMATO |
| Tipo | Esecuzione Arbitraria di Comandi |
| Admin Richiesto | No |
| Prompt UAC | No |
| Rilevabilità | Bassa — il disco mostra il file legittimo per tutto il tempo; il payload è solo in memoria |
| CVSS (stima) | AV:L / AC:H / PR:L / UI:N / S:U / C:H / I:H / A:H |
Vedere poc_8962_toctou.ps1.
Requisiti:
doLocalConf.xml presente nella directory di Notepad++ (modalità portatile)config.xml con un HMAC valido per il shortcuts.xml legittimo.\poc_8962_toctou.ps1 -NppPath "C:\path\to\notepad++.exe"
Verificato: calc.exe avviato (PID 35932), il disco mostra shortcuts.xml legittimo per tutto il tempo.
La correzione (commit 4f7563c) sposta la validazione HMAC all'avvio, insieme all'analisi iniziale del file. Check e Use operano ora sullo stesso oggetto nello stesso momento, eliminando la finestra TOCTOU.
| v8.9.6.2 (vulnerabile) | v8.9.6.4 (corretto) | |
|---|---|---|
| Controllo HMAC | Al momento dell'attivazione, rilegge il disco | All'avvio, stessi byte dell'analisi |
| Sorgente del comando | Memoria caricata all'avvio | Memoria validata all'avvio |
| Finestra TOCTOU | Avvio → Attivazione | Eliminata |