Skip to content

Password Manager DLL Security

An analysis of DLL loading behavior across major password management applications on Windows, examining how these high-value targets handle library dependencies and whether they are susceptible to DLL hijacking attacks.

Why Password Managers Are High-Value DLL Hijacking Targets

Password managers occupy a unique position in the desktop software landscape. They handle the most sensitive data on a user's system: master passwords, vault decryption keys, and the cleartext credentials themselves. A successful DLL hijack against a password manager does not just grant code execution in the context of the process - it grants access to the decryption pipeline, the master key material in memory, and potentially every credential the user has stored.

Unlike a DLL hijack against a text editor or media player (where the attacker gains code execution but limited access to valuable data), hijacking a password manager's process provides immediate access to high-value secrets. The attacker's injected code runs in the same address space where the vault is decrypted, where the master password is processed, and where clipboard operations with credentials occur.

This makes password managers a priority target for sophisticated attackers, and it makes DLL loading hygiene a critical security property for password manager vendors.

DLL Search Order on Windows

When a Windows application calls LoadLibrary or LoadLibraryEx without specifying an absolute path, the operating system searches for the DLL in a defined sequence of directories. The default search order (with SafeDllSearchMode enabled, which is the default since Windows XP SP2) is:

  1. The directory from which the application was loaded
  2. The system directory (C:\Windows\System32)
  3. The 16-bit system directory (C:\Windows\System)
  4. The Windows directory (C:\Windows)
  5. The current working directory
  6. Directories listed in the PATH environment variable

The critical observation is that the application directory (step 1) is searched before the system directory (step 2). If an attacker can place a malicious DLL in the application's directory - or if the application is launched from a directory the attacker controls - the malicious DLL will be loaded instead of the legitimate system DLL.

Several factors complicate this further:

  • Current working directory - If a user double-clicks a file associated with the password manager (e.g., a vault file on a network share), the CWD may be set to the file's location, which could be attacker-controlled.
  • PATH pollution - Directories in the user's PATH that are writable by non-admin users (common in development environments) can serve as DLL planting locations.
  • Delay-loaded DLLs - Some DLLs are not loaded at process startup but later when a specific function is first called, expanding the window for exploitation.
  • Side-by-side (WinSxS) resolution - The SxS mechanism adds additional complexity and potential bypass paths.

Testing Methodology

The testing approach used Process Monitor (ProcMon) from the Sysinternals suite to observe DLL loading behavior during password manager startup and operation:

  1. Filter configuration - ProcMon was configured to filter for the target process name, showing only CreateFile operations with paths ending in .dll where the result was NAME NOT FOUND. These entries indicate the application searched for a DLL in a location where it did not exist - the classic indicator of a hijacking opportunity.

  2. Startup analysis - Each password manager was launched from a clean state and all DLL load attempts were recorded during the startup sequence.

  3. Operational analysis - After startup, common operations were performed (vault unlock, credential copy, autofill, browser extension communication) to identify DLLs loaded on demand.

  4. CWD manipulation - The password manager was launched with the current working directory set to a test folder containing monitoring shim DLLs to identify CWD-dependent loads.

  5. Validation - For any identified candidate DLLs, a benign proof-of-concept DLL was placed in the relevant directory to confirm that it was loaded and executed by the password manager process.

Observed Patterns

Testing across several major password managers revealed a spectrum of DLL loading discipline. Without naming specific unpatched products, the following patterns emerged:

Applications with strong DLL hygiene

A subset of the tested applications demonstrated mature DLL security practices:

  • All DLL loads used absolute paths pointing to the application's own installation directory or to known system directories.
  • The application set the SetDefaultDllDirectories flag to restrict the search order at process startup.
  • No DLL search failures were observed for missing libraries in the application directory or CWD.
  • Delay-loaded DLLs were either pinned to absolute paths or protected by manifest entries.

These applications appeared to have undergone specific hardening against DLL hijacking, likely informed by prior vulnerability reports or internal security audits.

Applications with partial protection

Several applications had addressed the most obvious hijacking vectors but left secondary paths open:

  • Core application DLLs were loaded with absolute paths, but certain plugin or extension DLLs were loaded by name only.
  • The CWD was not set to a safe location at startup, leaving CWD-based hijacking theoretically possible when the application was launched via file association.
  • Third-party runtime dependencies (Visual C++ runtime, OpenSSL, etc.) were loaded without full path qualification, relying on the system's search order.

Applications with minimal protection

A smaller number of applications showed limited awareness of DLL hijacking risks:

  • Multiple DLLs were loaded by name from the application directory without absolute path specification.
  • No use of SetDefaultDllDirectories or equivalent mitigations.
  • CWD-sourced DLLs were loaded during startup.
  • Some DLL search failures pointed to directories writable by standard users.

Electron-based applications

Password managers built on Electron inherited a distinct DLL loading profile. The Chromium runtime loads a substantial number of DLLs during startup, and the Electron framework adds its own. While Chromium itself has undergone extensive DLL hijacking hardening, the application-specific layer built on top of Electron did not always maintain the same standard. Custom native Node.js modules loaded via require() were a recurring area of concern.

Recommendations for Developers

Password manager developers should treat DLL hijacking as a critical-severity threat given the sensitivity of the data their applications handle. The following mitigations are recommended:

Call SetDefaultDllDirectories early. At the very start of the process entry point, call SetDefaultDllDirectories(LOAD_LIBRARY_SEARCH_SYSTEM32) to remove the application directory, CWD, and PATH from the default search order. Load application-specific DLLs explicitly with AddDllDirectory or full paths.

Use absolute paths for all LoadLibrary calls. Never rely on the search order to find a DLL. Construct the full path to each library at load time.

Set the CWD to a safe directory. Before any DLL loading occurs, set the current working directory to the application's installation directory or to System32.

Sign all DLLs and verify signatures at load time. Use Authenticode signatures on all shipped DLLs and verify signatures before loading. Windows provides WinVerifyTrust for this purpose.

Audit third-party dependencies. Runtime libraries, plugin frameworks, and native modules brought in through package managers may introduce DLL hijacking vectors. Audit the loading behavior of every dependency.

Test with Process Monitor regularly. DLL loading behavior can change with dependency updates, new features, or build system modifications. Include ProcMon-based DLL hijacking testing in the CI/CD pipeline or release checklist.

Consider Windows Defender Application Control (WDAC) compatibility. Ensure the application functions correctly under WDAC policies that restrict DLL loading to signed binaries, as enterprise environments increasingly deploy these protections.

Conclusion

The tested password managers exhibited a wide range of DLL loading security maturity. Given that a successful DLL hijack against a password manager provides access to the user's entire credential store, the bar for DLL hygiene in these applications should be as high as it is for operating system components. The mitigations are well-understood and straightforward to implement. There is little reason for a modern password manager to ship with exploitable DLL loading behavior.