Skip to content
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

WebView2 can't run as SYSTEM - CreateCoreWebView2Controller fails with error 0x800700aa - The requested resource is in use. #1907

Closed
yuriy-sha opened this issue Nov 3, 2021 · 47 comments
Labels
bug Something isn't working tracked We are tracking this work internally.

Comments

@yuriy-sha
Copy link

yuriy-sha commented Nov 3, 2021

Description
I was trying to launch the WebView2 from the credential provider (LogonUI) process (which is executed in the context of SYSTEM user) and noticed that it stopped working recently.
I am getting the following error in the callback while calling the method CreateCoreWebView2Controller: 0x800700aa - The requested resource is in use.
However, the same stuff works perfectly when being executed in the context of logged in user.

There is no issue if I downgrade WebView2 Runtime to the older version 94.0.992.31.

Note: CreateCoreWebView2EnvironmentWithOptions is called with nullptr for browserExecutableFolder and nullptr for environmentOptions parameters. userDataFolder points to the directory in the Local App Data folder.
Passing nullptr for userDataFolder parameter does not help unfortunately - the same issue persists.

Could you please help me to understand what's wrong and how I can fix it on my side?

Version
SDK: 1.0.1020.30
Runtime: 95.0.1020.40
Framework: Win32
OS: Win10

AB#37319893

@yuriy-sha yuriy-sha added the bug Something isn't working label Nov 3, 2021
@jayvdlaan
Copy link

I have noticed this issue as well when I upgraded to the latest WebView2 runtime. I was using WebView2 in a credential provider (same as @yuriy-sha) when it stopped working after the update. Same error and everything, only difference is that I'm running the credential provider on Windows 11 and not Windows 10.

I also think it's worth noting that it doesn't seem to be the credential provider that's at fault here, since I tested running a WebView2 application as SYSTEM by using Process Hacker and it yielded the same result.

@jayvdlaan
Copy link

I did some more digging and found out that the msedgewebview2 binary contains some code that intentionally prevents it from executing under the SYSTEM user profile. The functionality in question can be found in the WinMain of said application with the particular function that's checking this called: base::win::IsCurrentProcessRunningAsLocalSystem. I'd like to know why this was explicity disabled by Microsoft and whether this could be worked around in any way.

@champnic
Copy link
Member

Hey @yuriy-sha and @Teitoku42 - I found the change that introduced this behavior, and looks like it was checked in for security reasons. I'll see if we can either turn it off when running as WebView2 or maybe give app devs a way to turn off this check. Thanks!

@champnic champnic added the tracked We are tracking this work internally. label Nov 11, 2021
@niryanowsky
Copy link

What is the check inside base::win::IsCurrentProcessRunningAsLocalSystem? I try impersonation but it didnt work for me.
Do you know when will be a fix for this?

@jayvdlaan
Copy link

@niryanowsky Here is the pseudocode for IsCurrentProcessRunningAsLocalSystem:

__int64 __fastcall base::win::IsCurrentProcessRunningAsLocalSystem(base::win *this)
{
  BOOL *p_IsMember; // rsi
  BOOL v2; // eax
  BOOL IsMember; // [rsp+28h] [rbp-60h] BYREF
  DWORD cbSid; // [rsp+2Ch] [rbp-5Ch] BYREF
  char pSid[64]; // [rsp+30h] [rbp-58h] BYREF
  int v7; // [rsp+70h] [rbp-18h]

  cbSid = 68;
  memset(pSid, 0, sizeof(pSid));
  v7 = 0;
  LODWORD(p_IsMember) = 0;
  if ( CreateWellKnownSid(WinLocalSystemSid, 0i64, pSid, &cbSid) )
  {
    p_IsMember = &IsMember;
    IsMember = 0;
    v2 = CheckTokenMembership(0i64, pSid, &IsMember);
    LOBYTE(p_IsMember) = v2 && IsMember;
  }
  return (unsigned int)p_IsMember;
}

@champnic
Copy link
Member

After discussing this further with our security team, we've come to the decision to continue to disallow running WebView2 in the context of SYSTEM, as this poses too great a risk if compromised. We won't be doing a quick workaround like a flag at this time. However, we are looking into other solutions for this scenario. Many apologies for this disruptive change, we should have blocked this sooner.

@champnic champnic changed the title CreateCoreWebView2Controller fails with error 0x800700aa - The requested resource is in use. WebView2 can't run as SYSTEM - CreateCoreWebView2Controller fails with error 0x800700aa - The requested resource is in use. Dec 15, 2021
@yuriy-sha
Copy link
Author

yuriy-sha commented Dec 20, 2021

@champnic Thanks for the feedback.
Is there any way I can workaround the issue? For example, by impersonating the calling thread by the currently logged in user? Or by creating the restricted token disabling SYSTEM SID and then impersonating the calling thread? Will that work?

@JeyaGuru127
Copy link

I was facing the exact error when I was trying to launch a webview2 from Credential Provider. I have an urgent requirement to run webview2 as system user for credential provider so kindly tell me whether there is any workaround for achieving it.

@AndrewMagpie
Copy link

I too am experiencing the same thing in my Credential Provider.
For An FYI, CEF allows LOCALSYTEM access. I didnt want to go there, but I'm not left with a choice.

Would be nice to know of the security risks the security team have, @champnic ?

@dfedotenko
Copy link

Hi, @champnic

To follow up on this topic. The security concern is understandable. At the same time, there are important cases such as SBL (aka Prelogon) which require use of CredentialsProvider framework. Preventing from using webview in cases like Prelogon or other CredentialsProvider-based cases, makes it impossible to offer web-based OIDC/SAML.

Could there be a reconsideration of the security concern and can Microsoft team allow usage of webview with system user to address such specific scenarios? Resorting to IE based webview or using special non OIDC or non-SAML based AAA flows are really cumbersome workarounds.

@champnic
Copy link
Member

champnic commented May 4, 2022

Yes, we are considering what the path forwards is here. One potential option is to make enabling running as SYSTEM an opt-in option/flag, so that we know the dev is purposefully choosing to enable this behavior and is hopefully doing it while aware of the security implications of running potentially untrusted code.

@dfedotenko
Copy link

Hi, @champnic

Thank you! How can we stay informed on the progress of such decision and whether/when it can be made?

@champnic
Copy link
Member

champnic commented May 4, 2022

We'll use this issue to track and update when we have more info. We haven't dug into this issue deeply yet, but it's relatively high on our backlog. Thanks!

@dfedotenko
Copy link

Thank you @champnic ! I will continue watching this issue for updates. Hopefully, Webview2 team will be able to offer an opt-in mechanism soon!

@lightheart33
Copy link

Hi, @champnic

After having spent a month disabling and preventing all the "dangerous" things,
I fully agree with the Security concerns. However we have to do something prelogon,
and preventing Webview2 fully is a complete showstopper for us,
it might be high up on your backlog, but its the Prime problem on my list.

The idea with an opt-in option/flag is a possibility, with a large WARNING sign attached.

I would like to suggest another alternative, how about "downgrading" the access token to a "safer" token?
For example a token which has lesser privileges and permissions than the LocalSystem start token.

One could for example remove all the Administrator privileges, here in a shorter "pseudocode" form:
OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE | TOKEN_QUERY, &systemToken))
DuplicateTokenEx(systemToken, TOKEN_DUPLICATE | TOKEN_WRITE | TOKEN_QUERY | TOKEN_IMPERSONATE , ..., &dupToken)
// The integrity level could of course also be reduced to for example S-1-16-8192
CreateWellKnownSid(WinBuiltinAdministratorsSid, 0i64, pAdminSid, &cbAdminSid))
SID_AND_ATTRIBUTES sidArray[1] = {Sid: pAdminSid, Attributes: SE_GROUP_USE_FOR_DENY_ONLY}
CreateRestrictedToken(dupToken, 0, 1, &sidArray[0], 0, 0, 0, 0, &lesserToken)
The "downgraded" lesserToken is now a restricted token with Admin (SidsToDisable) disabled.

LocalSystem start token:
localSystem Token before

lesserToken:
lesserToken after

And since your WebView2 UI Thread is single-threaded, you could use the lesserToken for impersonation:
// Webview2 initialization:
ImpersonateLoggedOnUser(lesserToken);
// Everything inside Webview2 UI Thread gets executed without Admin rights...
// Webview2 close/cleanup:
RevertToSelf();

Please consider, and I hope the WebView2 Team can find a compromise that makes the Security Group happy,
and at the same time allow WebView2 to be used in System context. Thank you! :)

@champnic
Copy link
Member

champnic commented Jul 1, 2022

Thanks for the suggestions here @lightheart33 - we'll consider this when we start working on this scenario.

@thesab576
Copy link

@champnic
We have a couple of large multinational enterprise customer using our solution and they want to completely get rid of IE technology which is currently being in use. Unfortunately this issue is a blocker to migrate to WebView2. Would like to avoid introducing CEF... Do you have a rough schedule when a solution as outlined above could realistically be expected?

Thank you @lightheart33 : would have been great if this soloution were there from the beginning!

@mpalanis
Copy link

@champnic
We are also looking for the same change. We would like to move away from the IE and use Edge Webview. This is blocking us to launch the Webview from Credential Provider. Is there any way we can launch the WebView from the Credential Provider using user impersonation?.

@mpalanis
Copy link

Anyone find any alternative to run from the system user?

@lightheart33
Copy link

@mpalanis Unfortunately not, and I have tried many things with access tokens.
But when I try to create the Webview2 controller prelogon I also get a different error code 0x80080005 (Server execution failed), perhaps its because I am attempting using a different "User Folder", where I know the system could write EBWebView.
I suspect I have not yet run into IsCurrentProcessRunningAsLocalSystem mentioned above.

@tochukwuIbeEkeocha
Copy link
Contributor

Hello all,

So upon further investigation it seems like a switch/command-line arg that enables this may have already been implemented. Try running your WebVew2 applications with the following --enable-features=allow-run-as-system. I believe you could use this API to do so.

If the issue still persists, could you provide a repro application where this issue is present, it would be helpful to understand your use case.

@lightheart33
Copy link

Hello @tochukwulbeEkeo,

Thank a lot for looking into this, but be warned, it might not be easy.

I have tried your suggestion with --enable-features=allow-run-as-system,
unfortunately it didn't solve the issue for the Windows prelogon case,
attempting calling CreateCoreWebView2Controller and CreateCoreWebView2ControllerWithOptions,
both landed in the OnCreateWebViewControllerCompleted handler with error code 0x80080005 (Server execution failed?).

The use case Simply explained:
Windows Prelogon: From a custom windows credential provider start an Application which uses WebView2,
the browser should open, because the user need to perform certain things before Windows Logon.

Observations:
I have for Windows Prelogon observed that the WebView2 environment is created successfully,
but when trying to create the controller it returns with an error, only a short window blink and then WebView2 closes again.
Now even without your allow-run-as-system, I have tried inside an user session to use psexec to first open a system command prompt, and then running the application with WebView2, there everything works fine, even in system context it is started nicely. However in the windows prelogon case, where the application is also running in System Context, because it was launched from a custom credential provider, the behavior is different, the controller returns in the callback with an error 0x80080005. I have later discovered that the System Context created with psexec, has a lot more privileges than the System Context which is used Windows Prelogon.

At one time I thought it could perhaps not create the EBWebView, so I started it with an User Data Folder under C:\Windows\Temp\Testfolder, and starting the application in windows prelogon it creates the EBWebView folder,
with a Crashpad folder inside, unfortunately the files inside the Crashpad folder are few and small:
image

Another clue could be what @yuriy-sha wrote in the beginning, for I have been able to reproduce this myself with SDK:
Building with WebView2 SDK 1.10.1020.30 => WebView2 controller cannot be created windows prelogon
Building with WebView2 SDK 1.0.992.28 => WebView2 controller can be created windows prelogon
while using the corresponding fixed runtime versions.

I cannot seem to get closer to the WebView2 version where the issue was build in, as I don't have the fixed version
for any in between, but comparing the SDK differences could perhaps help in locating the real issue.

Please write if I can provide any other relevant information, or trying out things...

@lightheart33
Copy link

@tochukwulbeEkeo:
You asked for a way to reproduce it, here is a tested one using only Microsoft Samples.
With these step-by-step instructions you can try it out yourself, and locate the real issue.

Instructions:

To reproduce the issue, you need a Windows Credential Provider:

  1. Download the Microsoft Windows Credential Provider Samples:
    https://www.microsoft.com/en-us/download/details.aspx?id=4057

  2. Build the project SampleCredentialProvider (Release, x64) => SampleCredentialProvider.dll

    note 1: Although the project is VS2008, it can easily be upgraded and build with VS2017
    (Platform Toolset: Visual Studio 2017 (v141), Windows SDK Version 8.1),

    note 2: Solely for testing purposes one can launch a cmd.exe process from inside
    the method CSampleCredential::GetSerialization.
    This can be achieved by commenting out the existing implementation,
    and instead use CreateProcessW to launch a process with:
    L"C:\\Windows\\System32\\cmd.exe" (lpApplicationName), NULL (lpCommandLine), ... ,
    NORMAL_PRIORITY_CLASS | CREATE_DEFAULT_ERROR_MODE (dwCreationFlags), ...
    and then wait for the process to finish, before returning E_FAIL.

  3. Obtain the Microsoft Visual C++ Redistributable packages for 2015-2022 (x64).
    https://aka.ms/vs/17/release/vc_redist.x64.exe

  4. Copy SampleCredentialProvider.dll, Register.reg (from project) together with VC_redist.x64.exe.
    to a Virtual Maschine (VM),

  5. VM: From an Administrator command prompt:
    5.1 Install the Microsoft Visual C++ Redistributable package (VC_redist.x64.exe),
    5.2 Perform Register.reg (File Properties: Unblock)

  6. VM: Copy SampleCredentialProvider.dll to C:\Windows\System32

  7. VM: Switch User - You can then see the two Sample Credential Providers (Administrator and Guest)

Sample CP

2 Sample CP

Select Guest and Press the Arrow => Opens up a command prompt in system context:

Command Prompt as System

Observation: This system user has less privileges than a system user opened with psexec inside an Administrator session.

  1. VM: Obtain and install the latest WebView2 runtime (Evergreen).

Now we need an Application with WebView2, we can just use the one from the MicrosoftEdge/WebView2Samples,
downloadable from here: https://github.com/MicrosoftEdge/WebView2Samples

  1. Build the project WebView2APISample (Release, x86) => WebView2APISample.exe

  2. VM: Copy WebView2APISample.exe, WebView2Loader.dll and the assets folder to a new test folder C:\Temp\Testfolder
    perhaps WebView2APISample.exe (File Properties: Unblock)

image

  1. VM: From inside an user session execute WebView2APISample.exe

From Inside User Session

Close afterwards the WebView2APISample.exe again, and delete folder
C:\Temp\Testfolder\WebView2APISampole.exe.WebView2\EBWebView2

  1. VM: Windows Prelogon from cmd.exe execute WebView2APISample.exe (without allow-run-as-system):

Failed to create WebVIew2

Observation: It created a folder WebView2APISample.exe.WebView2\EBWebView2, but which only has a Crashpad folder.

image

  1. VM: Windows Prelogon from cmd.exe execute WebView2APISample.exe (with allow-run-as-system):

Allow run as system

The result is unfortunately the same, and as you clearly can see the error is 0x80080005,
and this is by only using Microsoft Samples!

I hope this helps in locating and solving the real issue.

@tochukwuIbeEkeocha
Copy link
Contributor

tochukwuIbeEkeocha commented Nov 1, 2022

Hello all.

A quick progress update. First off , I made a mistake when explaining how to specify the flag that allows you to run Webview2 as system. The proper command line flag/switch usage is as follows: --allow-run-as-system not --enable-features=allow-run-as-system.

This should already work if all you need to do is run as system under the context of a logged in user. However, for those building credential providers where there is no logged in user, other issues still exist. We are currently working on resolving them.

@tochukwuIbeEkeocha
Copy link
Contributor

Hello,

Quick questions for those of you who are building Credential Providers. How essential is being able to download content to the user's machine, what kind of data are you planning to download?

@AndrewMagpie
Copy link

Its very important to download content, with the page having access to websockets.

@lightheart33
Copy link

Hello,
I have disabled all download completely, because a file-dialog can be used to obtain a command prompt in system context with. Communication over a websocket would however be needed.

@tochukwuIbeEkeocha
Copy link
Contributor

tochukwuIbeEkeocha commented Nov 4, 2022

I could be mistaken, but WebSocket usage shouldn't require access to store data as a file in a directory on the user's machine. If you're use case does require this, could you elaborate on the type of data you will be storing, and why you need to persist it on the user's machine @AndrewMagpie.

@AndrewMagpie
Copy link

I need to connect to a web service that has page content and status updates by WebSockets.
No file-dialog is required.

@dfedotenko
Copy link

@tochukwuIbeEkeocha Hi!

Could you let us know what the MSFT team is prepared to support? :)
I agree that some of not most use-cases could be satisfied by keeping the data in run time memory until the actual user signs in and then access data storage for persistence.

But perhaps there could be cases where some writing to a temp file (perhaps with explicit (non-DPAPI) crypto for extra protection)....

@tochukwuIbeEkeocha
Copy link
Contributor

Hey,

There will be no support for downloads to the user's machine.

@rruprai1
Copy link

@tochukwuIbeEkeocha Is there any updated documentation you can point to that will outline what is/isn't allowed with webview2 when used in a credential provider?

@tochukwuIbeEkeocha
Copy link
Contributor

Hello everyone. After talking about all the risks and intended features, we have unfortunately decided not to support this use case at all. Third party credential providers are not supposed to be able to implement custom UI, rather you are encouraged to use built in APIs that the Credential Provider feature exposes. See these for example; ICredentialProvider and ICredentialProvderCredential

@rruprai1
Copy link

rruprai1 commented Jan 5, 2023

@tochukwuIbeEkeocha Does the switch --allow-run-as-system remain or will it be removed?

@tochukwuIbeEkeocha
Copy link
Contributor

@rruprai1 From what I understand the flag will remain, however it isn't intended to and does not provide support for running WV2 as a credential provider.

@rruprai1
Copy link

rruprai1 commented Jan 6, 2023

@tochukwuIbeEkeocha Thanks for that info. What would be MS guidance for creating a credential provider that supports OIDC?

@AndrewMagpie
Copy link

"Third party credential providers are not supposed to be able to implement custom UI"

Yet Microsoft themselves do it with Web-based logon?

@rruprai1
Copy link

@Teitoku42 What's the level of support then for Edge to be run in the logon process, not to log into windows, but to fetch tokens for a 3rd party app?

@champnic
Copy link
Member

champnic commented Feb 1, 2023

Not currently supported. We've reached out to the credential provider folks for more details on these scenarios, but have yet to hear back from them.

@manoharc1999
Copy link

@tochukwuIbeEkeocha and @champnic
Im planning to use this flag (allow-run-as-system) for one of my application.
When i checked the documentation it says it is not recommended to use this flag in production application.
The flag is very much crucial for my application to work and im afraid it might get removed.
Can this flag be moved in to official support?

@champnic
Copy link
Member

@manoharc1999 The documentation is correct. Due to security concerns, we are not planning to add official support for that flag, and recommend you don't use it.

@manoharc1999
Copy link

manoharc1999 commented Apr 26, 2024

@champnic
Is there any other work around without this flag. It is very crucial for my application to be allowed to run as system process.
I understand the security implications from this, but since this is by developer control, can it be added to support. Im pretty sure this will help lot of developers.

For my application im trying to launch a webview2 window in background even before users logs in. And this worked only when i passed the above flag. If there is any alternative approach for this i would be very happy to know.
Else I would have to make serious design changes moving away from webview2.
The main reason i choose to is majority of my web code can be reused and can be shipped to production on fly without making native app change.

@manoharc1999
Copy link

manoharc1999 commented Apr 28, 2024

@champnic & @tochukwuIbeEkeocha
Hope you guys can please consider this and have discussions with the team.

@manoharc1999
Copy link

@champnic & @tochukwuIbeEkeocha
Has there been any reconsiderations on this? If not many months of development would go for a toss.

Hopefully this flag could be under official support but can be enabled only by developers choice.

@manoharc1999
Copy link

I would be open to know if there are any workarounds for loading web app before user logs in. My web app does not have any UI and will run in background.

@mpalanis
Copy link

I would be open to know if there are any workarounds for loading web app before user logs in. My web app does not have any UI and will run in background.

I had similar issue. I moved away from the WebView2 to CEF.

@manoharc1999
Copy link

Unfortunately migrating to cef is not solution for me.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working tracked We are tracking this work internally.
Projects
None yet
Development

No branches or pull requests