microsoft / WindowsAppSDK

The Windows App SDK empowers all Windows desktop apps with modern Windows UI, APIs, and platform features, including back-compat support, shipped via NuGet.
https://docs.microsoft.com/windows/apps/windows-app-sdk/
MIT License
3.85k stars 326 forks source link

UWP => WinUI3 migration: PasswordVault cannot be accessed anymore #4393

Open TomPMoleman opened 6 months ago

TomPMoleman commented 6 months ago

Describe the bug

We are storing a randomly generated key inside the PasswordVault in order to encrypt and decrypt user data serialized to an xml (for improved security). This is working fine for both the UWP and the WinUi3 applications on their own. However, if the user was updating from UWP to WinUi3 application (package friendly name, etc. are identical, whereas the OS also handles this as an update!) the previously stored credentials are no longer retrievable! Thus any encrypted serialization data in place prior to the update is now lost and no longer usable.

Steps to reproduce the bug

  1. store credentials in PasswordVault within UWP app
  2. migrate codebase to WinUi3 (PaswordVault class is still present)
  3. install app update
  4. try to access the previously stored credentials in the very same app => Please note, that no entry will be found.

Expected behavior

After upgrading app, credentials should still be fetchable.

Screenshots

The below image depicts the 'Credential Manager' (the above entry is from UWP, and the bottom one was generated within the very same app after migrating to WinUi3):

image

NuGet package version

Windows App SDK 1.5.3: 1.5.240428000

Packaging type

Packaged (MSIX)

Windows version

Windows 11 version 22H2 (22621, 2022 Update)

IDE

Visual Studio 2022

Additional context

No response

DarranRowe commented 6 months ago

The PasswordVault documentation does indicate that there is a difference in behaviour between an application in an AppContainer and one not in an AppContainer.

There are two avenues of investigation that you can follow here. 1) Is your WinUI 3 based application running in an AppContainer? If not, do you observe any difference if you do run it in an AppContainer? 2) Because PasswordVault is a Windows component. You can remove WinUI 3 completely from the equation. If you package a desktop application, do you observe similar behaviour? In particular, it comes down to whether or not you see any changes if the application runs in an AppContainer or not.

Remember, desktop applications, when packaged, don't run in an AppContainer by default, where UWP applications do. It is also possible that there is a difference in the heavyweight AppContainer that UWP uses versus the lightweight AppContainer that desktop applications use.

jonwis commented 6 months ago

What is the package identity of your WinAppSDK WinUI3 application?

The vault uses package identity to isolate creds between applications. If your WinAppSDK app is unpackaged, you likely won't see the creds from the prior application.

TomPMoleman commented 6 months ago

Hi @DarranRowe & @jonwis,

Thanks a lot for your assistance as well as your valuable feedback.

As vault resource and user name in the screenshot might suggest, the affected app is some sort of document management application. Thus, whilst migrating the UWP app to WinUi3, I was facing some issues upon letting the app run in partial trust which as a consequence prevented the AppContainer's usage. Especially when it came down to missing file picker support (resulting in 'System.UnauthorizedAccessException' as stated in some tickets (e.g. #3447 & Xaml #9557)), that was a complete showstopper...

Thanks, BR Thomas

DarranRowe commented 6 months ago

@jonwis Is the documentation for PasswordVault correct and complete? I have been seeing the same thing, even to the point where a completely unpackaged desktop application running as admin isn't able to retrieve the credentials written by an application running in an AppContainer. An unpackaged application will retrieve the credentials for a packaged application not running in an AppContainer though, indicating that it is the AppContainer and not the package that matters.

The only thing I haven't tried yet is to impersonate using a token created by NtCreateLowBoxToken to see if that helps. That would be a bit awful if that is how you are supposed to obtain the AppContainer credentials.

--Edit-- Nope, impersonating results in PasswordVault.Retrieve failing. The error in the debug output is:

Exception thrown at 0x00007FFD74DD53AC (KernelBase.dll) in pvsample.exe: WinRT originate error - 0x8007000E : 'Cannot open Vault'.