Problem


Although Microsoft Edge, Chrome, and Firefox store encrypted passwords in the user profile location, these can be easily decrypted by another program without requiring user authentication or approval. Notably, Windows does not trigger a User Account Control (UAC) dialog, nor does it request a PIN, facial recognition, or two-factor authentication (2FA) before decrypting the passwords. Consequently, an untrusted program, not flagged by Microsoft Defender or other security software, can easily access your passwords.

The screenshot below demonstrates a utility specifically designed to extract all your stored passwords from Microsoft Edge, Chrome, and Firefox.

In this blog post, I will demonstrate the simplest method to prevent untrusted programs from accessing your browser passwords.

Solution


Create a new user

First, we need to create a new user on the system. Start PowerShell as Administrator, and run the following command:

net user <username> <password> /add

replace <username> and <password> with your own values.

Please DO NOT, NEVER, EVER, add this account to Administrators group.

Run untrusted App as this user

Holding Shift while right click the untrusted program and select "Run as different user".

Enter the credentials of the newly created user

Now the program won't be able to get any of your browser passwords.

Make an App always run as different user every time

If you use the untrusted app very often, you can make it automatically run as different user every time without typing username and password.

To achieve this, create or modify the short cut of the exe file, change the "Target" as below, for example, I would like to run WeChat as user old6 every time.

C:\Windows\System32\runas.exe /savecred /user:old6 "C:\Program Files\Tencent\WeChat\WeChat.exe"

In this command, runas.exe /savecred /user:old6 will let user input the password for user old6 only the first time. Then, you can just double click the shortcut to start the App as user old 6 every time automatically.

Explain


Microsoft Edge, Chrome and Firefox stores encrypted password in current user's profile folder. For example, for Microsoft Edge, the storage location is: 

C:\Users\<username>\AppData\Local\Microsoft\Edge\User Data\Default\Login Data

This file is in SQLite database format. You can open it by SQLite browser. You can see the encrypted password_value field for each website where your password is stored.

To decrypt the password into clear text, a program will call Data Protection Application Programming Interface (DPAPI) on Windows. This is by design a silent process that does not require Administrator permission or any user interaction. 

You can find hidden credential files in these two locations:

Get-ChildItem -Hidden C:\Users\<username>\AppData\Local\Microsoft\Credentials\
Get-ChildItem -Hidden C:\Users\<username>\AppData\Roaming\Microsoft\Credentials\

Then find master keys by SID

Get-ChildItem C:\Users\<username>\AppData\Roaming\Microsoft\Protect\
Get-ChildItem -Hidden C:\Users\<username>\AppData\Roaming\Microsoft\Protect\{SID}

There are plenty of articles online teach you how to decrypt passwords by DPAPI, I will not go through the details in this post.

However, there is one security limit by the system, which is the DPAPI could only decrypt logged in user's data, which in most case is just a valid program running as the current user. 

DPAPI uses a user-specific key to encrypt and decrypt data. This key is derived from the user's login credentials. Therefore, data encrypted by one user cannot be decrypted by another user unless they have access to the original user's credentials or the decryption key. 

When you run a program under a different user account, that program operates with the permissions and environment of that user. This includes using the DPAPI keys associated with that user account, not your main account. As a result, the program should not be able to decrypt data encrypted under your account. 

However, an administrator account can still have method to call DPAPI to decrypt password of another user that is currently logged in on the machine. This is how I come to the idea of letting untrusted program run as different user that is not administrator. 

Reference