#520 Allow ShellExecute as User (not elevated)

2.0 Series
open
nobody
None
3
2014-08-22
2013-08-26
Eric Lawrence
No

Most installers run elevated due to RequestExecutionLevel or the Windows Compat Shim.

When an NSIS installer runs, all of the Exec/ExecShell commands run at the Integrity Level of the installer.

The problem is that this means that Exec/ExecShell invocations run as Admin.

You really don't want to launch a web browser at Admin-level integrity (surfing the web without the security sandbox) and launching the installed application on exit can be problematic because the first run of the app occurs at Admin and all future runs run at MediumIL.

The workaround here would be to offer a way for scripts to explicitly Exec/ExecShell at MediumIL. While there's no one API exposed to do this, there are two major techniques that work (both used by Microsoft and others) which can be found here:

http://msdn.microsoft.com/en-us/library/dd940355(v=vs.85)

and here:

http://blogs.msdn.com/b/aaron_margosis/archive/2009/06/06/faq-how-do-i-start-a-program-as-the-desktop-user-from-an-elevated-app.aspx

The code involved is relatively straightforward but would be very difficult to mimic from a install script without having a feature built-in to NSIS for this.

(MSI-based installers typically can avoid this problem by having only part of the MSI running at Admin, then performing "user-level" actions outside of that portion).

Discussion

  • Anders
    Anders
    2013-08-29

    IMHO if you have RequestExecutionLevel admin (or "not set" since MS forces a shim on us) you are doing a machine/all users type install and because of various UAC issues you should not call Exec[Shell] on a URL nor start your app on the finish page.

    As far as using the token of the current shell, it is a ugly hack and does not work if you throw runas.exe into the mix where you could end up with explorer=user1, setupParent=user2 and elevatedSetup=user3 (If user2 was not a elevated admin).

    A better approach is to not request elevation in the manifest, store this token and start yourself as a child while requesting elevation and handing over the token so CreateProcessAsUser can be used. One gotcha here is that elevation is broken when UAC is not turned on, it does not work like NT5 with the runas dialog but just starts the process normally!

    If you feel the Explorer token hijack is a good solution it should be easy to write a plugin for it. I wrote the UAC plugin that does it the other way in the early Vista days but using it is hard since it hooks into NSIS in weird ways and bending the rules a bit...

     
  • Eric Lawrence
    Eric Lawrence
    2013-08-29

    you should not call Exec[Shell] on a URL nor start your app

    Sure, it's fair to say that you could avoid this problem by not offering functionality that users want or expect from their installers. But that seems a bit short-sighted.

    "As far as using the token of the current shell, it is a ugly hack"

    I agree. However, it's the "ugly hack" recommended by Microsoft, and since it's their OS, they probably know best.

     
  • Anders
    Anders
    2013-08-30

    If you remember in the early Vista days MS also recommended using the task scheduler and various other tricks which I believe are no longer recommended since most of these hacks have issues.

    The dual process model I guess MS calls "Administrator Broker Model" http://msdn.microsoft.com/en-us/library/windows/desktop/dd550641 & http://msdn.microsoft.com/en-us/library/bb530410.aspx (Includes the broken task scheduler example and other UAC stuff) and I'm pretty sure there was a page for the one .exe dual process model as well but I cannot find the correct page on MSDN right now...