-
Notifications
You must be signed in to change notification settings - Fork 321
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
AppContainer for Win32 apps #219
Comments
Oh yeah, forgot to mention: you can't build an appx using PartialTrustApplication without adding |
I would like to add here that running a simple "Hello World" .NET Core 3.1 WPF app in the AppContainer utilizes around 20% of my CPU whereas running the exact same app without the AppContainer uses ~0% of the CPU (per Task Manager). Which makes using the AppContainer for this very basic Hello World WPF app rather impractical for now (other than being a cool experiment). It runs fine (~0%) for a WinUI 3.0 Preview 2 C++ Desktop app. |
This issue doesn't reproduce with a C++ app, and as long as the app doesn't try to do things which AppContainer disallows, actually works without problem. This might be a bug with .NET where some API call is denied by the sandbox, and it keeps retrying. |
I would like to add : Scope
Open Questions/Rationale:Why would anyone want to run win32 apps in other platforms? the main point is , it is not feasible/sustainable to rewrite my app from scratch just to run it on other platforms. also user adoption remains to be seen. Please , let us have just one App Technology which is both modern+privacy oriented and at the same time powerful when needed. aren't all win32 apps evil? |
I disagree, my feature request is purely about the sandboxing. Things like share targets, or running on other platforms, should be different feature requests. Privacy controls are already a could, and would be nice, but I do not consider them to be complete blockers. AppContainer implies low IL and by design you can't elevate your IL (huge source of security vulnerabilities to allow escalation). If you need higher IL, use a full trust process or helper. |
we are here for changes, right ? |
Yes but I'm not here to introduce security vulnerabilities, changes to how AppContainer works or ways to escape from it. Allowing low IL apps to elevate to medium or even high IL is all 3 at the same time. |
you say security vulnerabilities ? well, you are never truly secure on desktop and this is only asking through special user prompt only on desktop ): |
Just giving the possibility for it to happen opens for potential vulnerabilities. If you're suggesting something like UAC, you'll be glad to learn it had multiple vulnerabilities in the past that allows apps to bypass the prompt and get elevated silently. |
"getting elevation silently" should not work inside AppContainer. so no |
UAC was not supposed to allow that, but it did because of security vulnerabilities. Get my point? This will eventually repeat with a mechanism to elevate IL. I am strongly opposed to the idea. Full trust processes already have medium IL, so if you need medium IL, use those. They're safer since you are limited to only executables declared in your package as full trust, not any arbitrary exe in your package. If you want a mechanism for users to consent to launching a full trust process, open another issue for that. |
so you are basically assuming , like win32 had secure vulnerabilities AppContainer for win32 apps technology will have that too, without MS letting implement that in the first place (if they want).
this is an ask for win32 apps |
Yes, we are humans and make mistakes. Keep the AppContainer at low IL, and if you want higher IL, run outside the AppContainer. |
AppContainer is Low IL by definition. You can't "elevate" an AppContainer to Medium IL; then you're not in an AppContainer anymore. What I think we "should" support (opinion incoming, not a product plan) is the ability to launch the exact same app either in an AppContainer or not in an AppContainer, based on developer requests / user consent. So just like you can run a Win32 app at Medium IL most of the time and occasionally run it at High (elevated), so too should you be able to run an app at Low IL most of the time and occasionally run it at Medium (or High) if you need to. But then it's not in an AppContainer any more :-). (FWIW The reason |
@ptorr-msft Am I reading your reply correctly in the sense that I shouldn't expect anytime soon (say till summer next year) a fix to ship which addresses the high CPU utilization for .NET Core (.NET Framework presumably too) Win32 apps running in an AppContainer?
Yes, please! It would be great if the AppContainer will become greatly supported for Win32 apps (better VS support, documentation,...). If I as a Win32 developer could use UWP XAML (WinUI 3) + APPX (MSIX) + AppContainer for my Win32 apps, then this would be very nice indeed. We are already getting the former two so if AppContainer could follow, that would be very cool 🙂 |
Thanks for the IL clarification. I always strive to improve the security of my program, so when I stumbled upon the aforementioned Electron PR, my interest was piqued. After trying it and finding out that a lot of things don't work, I opened this issue in an attempt to make this more supported, for example by documenting what would work and what wouldn't. My idea was to run the entire GUI and program logic in a low IL/partial trust process, and broker the "bad" stuff (that most people don't need, Since Shell_NotifyIcon would need to be brokered I could certainly implement my own brokering for it in that full trust process, but obviously the OS/Project Reunion doing it for the developer would be much better (and more secure than everybody rolling their own).
I also think that developers should be able to limit their apps to low IL only (effectively what partial trust does today) @Felix-Dev I wouldn't expect a fix until that scenario is properly supported. |
Yes,Please! |
Yes. Technically AppContainer is a property parallel to IntegrityLevel, but it's only possible to be an AppContainer today if IL=Low (that's why most folks think of it as Elevated > MediumIL > LowIL > AppContainer, even though technically incorrect). AppContainer+MediumIL doesn't exist today, and it's an oxymoron (MediumIL...but sandboxed?!?! Must be some kind of quantum computing thing Schroedinger's Cat is programming... :P) @Felix-Dev we're keenly interested to learn of APIs folks are interested in that don't work in an AppContainer. Enabling more secure apps is a worthy goal but Windows is, as you might guess, pretty huge so feedback to help us know where to focus our efforts is invaluable. Most of the proposed 'Scope' are very broad and difficult to be actionable, but this is a good thread to discuss the issue and spin off more focused proposals for follow up. To that end:
Use in what way? Are the specific tray icon (or merely tray or icon) APIs or behavior you find aren't accessible in an AppContainer? More details would help understand the gap and shape of work involved to solve it. This sounds like a good candidate to spin off to a separate dedicated issue e.g. "Enable Tray Icon X Y Z in a Windows.PartialTrustApplication"
What sort of 'helper' are you thinking? Can you accomplish your goals if you define 2 applications in your package (PartialTrust 'app' + FullTrust 'helper')?
Do you have a code snippet? Is there more taskbar functionality you'd like to use but found blocked by AppContainer?
That's not quite true. Even if you can't do anything to the process, reading data (w/o authorization) is very much a security concern. It's a little unclear what specifically you're trying to accomplish here. Could you elaborate?
AppContainer's availabile via Windows.PartialTrustApplication, albeit with limitations. Some of those are by design, but just some. But it's hard to assess in the abstract. Specifics are much more actionable. P.S. Thanks for reporting the documentation gap. I've filed Microsoft-internal task 29686473 to address that. |
Today, I didn't open an issue specifically for that because I wanted to test the waters. No point in complaining about a specific API not working if the entire scenario was not something you'd want to support. For the rest of your comments: The app I'm mentioning here is TranslucentTB. It alters the appearance of the system taskbar by calling the undocumented SetWindowCompositionAttribute API using the taskbar's handle. The API doesn't work in AppContainer and that's totally fine. It offers the ability to have a different appearances depending on conditions (for example, when a window is maximized or the start menu is open). But since this kind of detection tends to not be 100% reliable, we offer a way to exclude some windows from this matching by class name, window title, or process name. We use PROCESS_QUERY_LIMITED_INFORMATION to get the process name with QueryFullProcessImageName to check against the blacklist, and don't store it. Currently in AppContainer this is broken. Maybe make this a capability? One of the "states" you can get is to restore the taskbar to its normal appearance. The most reliable way I've found to get that is to do Even if a lot that we do is questionable and has no place in AppContainer, I still see the value in AppContainer. I would like to run my GUI and most of the logic in AppContainer, and use a full trust process to broker operations not allowed by AppContainer. This way, I can reduce the possibility for accidental mistakes that could delete user data, and minimise the attack surface of my program (a bug in my logic wouldn't allow some other low IL application to go ham and elevate itself). The full trust helper's primary purpose would be managing the hooking of Windows Explorer, calling SetWindowCompositionAttribute on the taskbar handle, and sending WM_THEMECHANGED. |
@sylveon modulo the use of undocumented APIs (which we do not condone / support), that kind of app structure (low-privileged UI process driving a higher-privileged "do the real work" process) is good. And I assume your current UI is Electron-based? Given that you would need to rearchitect your app somewhat anyway (into the two different processes), is it feasible for you to move to a |
TranslucentTB is written using C++, so does not use Electron but rather a very basic GDI GUI. My in-development version is using XAML Islands, for a couple of reasons:
AppContainer for Win32 would minimize the amount of rearchitecting/rewriting I have to do here, only brokering the few APIs that don't work (rather than like half of User32), while keeping the logic in the main low trust executable. |
Based on suggestion on microsoft/WindowsAppSDK#219 Leads to the following error: 1>MakeAppx : error : Error info: error 80080204: App manifest validation error: Line 31, Column 24, Reason: The "windows.aboveLockScreen" Extension can't be declared with Partial Trust EntryPoint. 1>MakeAppx : error : Package creation failed. 1>MakeAppx : error : 0x80080204 - The specified package format is not valid: The package manifest is not valid.
Based on suggestion on microsoft/WindowsAppSDK#219 Leads to the following error: 1>MakeAppx : error : Error info: error 80080204: App manifest validation error: Line 31, Column 24, Reason: The "windows.aboveLockScreen" Extension can't be declared with Partial Trust EntryPoint. 1>MakeAppx : error : Package creation failed. 1>MakeAppx : error : 0x80080204 - The specified package format is not valid: The package manifest is not valid.
Based on suggestion on microsoft/WindowsAppSDK#219 Leads to the following error: 1>MakeAppx : error : Error info: error 80080204: App manifest validation error: Line 31, Column 24, Reason: The "windows.aboveLockScreen" Extension can't be declared with Partial Trust EntryPoint. 1>MakeAppx : error : Package creation failed. 1>MakeAppx : error : 0x80080204 - The specified package format is not valid: The package manifest is not valid.
Based on suggestion on microsoft/WindowsAppSDK#219 Leads to the following error: 1>MakeAppx : error : Error info: error 80080204: App manifest validation error: Line 31, Column 24, Reason: The "windows.aboveLockScreen" Extension can't be declared with Partial Trust EntryPoint. 1>MakeAppx : error : Package creation failed. 1>MakeAppx : error : 0x80080204 - The specified package format is not valid: The package manifest is not valid.
Based on suggestion on microsoft/WindowsAppSDK#219 Leads to the following error: 1>MakeAppx : error : Error info: error 80080204: App manifest validation error: Line 31, Column 24, Reason: The "windows.aboveLockScreen" Extension can't be declared with Partial Trust EntryPoint. 1>MakeAppx : error : Package creation failed. 1>MakeAppx : error : 0x80080204 - The specified package format is not valid: The package manifest is not valid.
@ptorr-msft @nickrandolph I'm struggling to change the packaging project to partial trust, is this still working? I've removed the And trying to set the entrypoint manually in the manifest seems to be ignored and overridden each time: And results in a validation error when building: Any ideas? (I'm trying to make my app partial trust, so that I can test AppCapabilities checks and requests for webcam, microphone, etc. When fullTrust is in effect all these capabilities are granted by default, without any way to request them) |
What is line 25, column 6 in your appxmanifest.xml? Offhand it sounds like your Application definition should get you what you want. This could be something else. There can be things in appxmanifest.xml that require runFullTrustCapability beyond the Application declaration itself e.g. `<Extension Category="windows.firewallRules"...> requires the package declares the runFullTrustCapability even though the firewall rules are just definitions to the firewall (that extension's not an activatable extension point). |
@DrusTheAxe The line 25 column 6 refers to the generated AppManifest.xml, containing: <?xml version="1.0" encoding="utf-8"?>
<Package xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10" xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10" xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities" IgnorableNamespaces="uap rescap build" xmlns:build="http://schemas.microsoft.com/developer/appx/2015/build">
<!--
THIS PACKAGE MANIFEST FILE IS GENERATED BY THE BUILD PROCESS.
Changes to this file will be lost when it is regenerated. To correct errors in this file, edit the source .appxmanifest file.
For more information on package manifest files, see http://go.microsoft.com/fwlink/?LinkID=241727
-->
<Identity Name="7827e4e6-37f5-413d-86dd-1b409ad905fd" Publisher="CN=Tor Arne Vestbø" Version="1.0.1.0" ProcessorArchitecture="x64" />
<Properties>
<DisplayName>PermissionsPackagingProject</DisplayName>
<PublisherDisplayName>Tor Arne Vestbø</PublisherDisplayName>
<Logo>Images\StoreLogo.png</Logo>
</Properties>
<Dependencies>
<TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.14393.0" MaxVersionTested="10.0.22000.0" />
<TargetDeviceFamily Name="Windows.Desktop" MinVersion="10.0.14393.0" MaxVersionTested="10.0.22000.0" />
<PackageDependency Name="Microsoft.VCLibs.140.00.Debug.UWPDesktop" MinVersion="14.0.30704.0" Publisher="CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US" />
</Dependencies>
<Resources>
<Resource Language="EN-US" />
</Resources>
<Applications>
<Application Id="App" Executable="permissions\permissions.exe" EntryPoint="Windows.FullTrustApplication">
<uap:VisualElements DisplayName="PermissionsPackagingProject" Description="PermissionsPackagingProject" BackgroundColor="transparent" Square150x150Logo="Images\Square150x150Logo.png" Square44x44Logo="Images\Square44x44Logo.png">
<uap:DefaultTile Wide310x150Logo="Images\Wide310x150Logo.png" />
<uap:SplashScreen Image="Images\SplashScreen.png" />
</uap:VisualElements>
</Application>
</Applications>
<Capabilities>
<Capability Name="internetClient" />
</Capabilities>
<build:Metadata>
<build:Item Name="Microsoft.Build.DesktopBridge.Tasks.dll" Version="17.3.32727.363" />
<build:Item Name="TargetFrameworkMoniker" Value=".NETFramework,Version=v4.5.1" />
<build:Item Name="VisualStudio" Version="17.0" />
<build:Item Name="VisualStudioEdition" Value="Microsoft Visual Studio Professional 2022" />
<build:Item Name="OperatingSystem" Version="10.0.22000.1 (WinBuild.160101.0800)" />
<build:Item Name="Microsoft.Build.AppxPackage.dll" Version="17.3.32728.75" />
<build:Item Name="ProjectGUID" Value="39ea0d78-5270-49c4-b6d6-5759506d77ee" />
<build:Item Name="makepri.exe" Version="10.0.22621.1 (WinBuild.160101.0800)" />
</build:Metadata>
</Package> Line 25 is the one with Yet the Package.appxmanifest that's part of the packaging project contains: <?xml version="1.0" encoding="utf-8"?>
<Package
xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10"
xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"
IgnorableNamespaces="uap rescap">
<Identity
Name="7827e4e6-37f5-413d-86dd-1b409ad905fd"
Publisher="CN=Tor Arne Vestbø"
Version="1.0.1.0" />
<Properties>
<DisplayName>PermissionsPackagingProject</DisplayName>
<PublisherDisplayName>Tor Arne Vestbø</PublisherDisplayName>
<Logo>Images\StoreLogo.png</Logo>
</Properties>
<Dependencies>
<TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.0.0" MaxVersionTested="10.0.0.0" />
<TargetDeviceFamily Name="Windows.Desktop" MinVersion="10.0.14393.0" MaxVersionTested="10.0.14393.0" />
</Dependencies>
<Resources>
<Resource Language="x-generate"/>
</Resources>
<Applications>
<Application Id="App"
Executable="$targetnametoken$.exe"
EntryPoint="Windows.PartialTrustApplication">
<uap:VisualElements
DisplayName="PermissionsPackagingProject"
Description="PermissionsPackagingProject"
BackgroundColor="transparent"
Square150x150Logo="Images\Square150x150Logo.png"
Square44x44Logo="Images\Square44x44Logo.png">
<uap:DefaultTile Wide310x150Logo="Images\Wide310x150Logo.png" />
<uap:SplashScreen Image="Images\SplashScreen.png" />
</uap:VisualElements>
</Application>
</Applications>
<Capabilities>
<Capability Name="internetClient" />
</Capabilities>
</Package> Where I've explicitly tried to override the entrypoint to |
My guess is the VS task transforming @Scottj1s @MikeHillberg @evelynwu-msft is there a way to do this with the current templates? Perhaps explicitly adding some property? This screen shot |
"packaging project" means |
Correct. Generated by the Visual Studio "Windows Application Packaging Project" wizard, following this guide https://learn.microsoft.com/en-us/windows/msix/desktop/desktop-to-uwp-packaging-dot-net |
@evelynwu-msft Yes, select the project reference node in the packaging project and it is available as a property: |
@sbanni That's not the case for me: I notice your project is a |
@torarnv Interesting, looks like vcxproj doesn't expose it, you should be able to achieve the same outcome by setting this property in the packaging project file:
|
Thanks for the hint @sbanni! I tried this, but doesn't look like it's accepted? |
Thanks a bunch @sbanni 🙌🏻👏🏻❤️ |
Proposal: AppContainer for Win32 apps
Summary
This proposal attempts to bring the advantages of app containers (limited permissions and file system access) to Win32, by documenting how a packaged Win32 app can be hosted in one, and allowing Win32-only APIs which are not currently allowed to be called from an AppContainer.
Currently, this can be achieved by using
EntryPoint="Windows.PartialTrustApplication"
in the appx manifest. By setting this, your Win32 app is launched in the AppContainer:But, this entry point is largely undocumented (its only reference on the entire internet is an electron PR), and some things are broken.
For example, tray icons (with
ShellNotifyIcon
) are simply not working, and return an access denied error.OpenProcess
, even with only thePROCESS_QUERY_LIMITED_INFORMATION
permission, also returns an access denied. This permission is mostly harmless and only allows a very limited subset of APIs, none of which can do anything harmful to the process. There is little to zero security implication in allowing this.As the screenshot above shows, I've tried doing this with my own app, and these are the two big limitations I've encountered (as well as the general lack of documentation around this topic).
Rationale
runFullTrust
restricted capabilityrunFullTrust
to apps that actually do need to run completely outside the container for legitimate reasons, rather than every Win32 app.Scope
Important Notes
My app uses, along the things mentioned prior:
SetWindowsHookEx
to inject Windows Explorer (this is required for core functionality to work correctly)PROCESS_VM_OPERATION
, to be able to inject a payload that the hooked DLL can read for contextual information (related: SetWinEventHook and SetWindowsHookEx does not provide a way to pass user data Windows-Dev-Performance#28)SetWinEventHook
to know changes that happen to the window layout (opened, moved, maximized, minimized, closed, etc).SendMessage
, to be able to trigger a refresh of the taskbar's theme in Windows Explorer.While
SetWinEventHook
seems to already work today in the AppContainer (hooray), other APIs mentioned would need to be moved to a full trust helper. If this proposal where to come to fruition, I would be one of the first to jump unboard and move that functionality to a helper process.This is part of the reason I suggested to introduce new restricted capabilities which would unblock some APIs, as simply unlocking specific APIs under request is far safer and simpler than making a full trust helper process.
Open Questions
Would it be beneficial for anybody to introduce a partial trust equivalent to
FullTrustProcessLauncher
?The text was updated successfully, but these errors were encountered: