Default Integrity Level and Automation

Over on StackOverflow, danimajo asked for help in an interesting scenario. Basically, he’s trying to drive Internet Explorer through automation, but finds that when he navigates to an Intranet site, the hidden browser instance appears and he can no longer control it. What’s going on?

Background on Protected Mode

Internet Explorer’s Protected Mode is a security sandbox that relies upon the integrity level system in Windows. A process may have only one integrity level (IL), so if you navigate an IE instance between a Internet (Protected Mode, LowIL) and Intranet (non-Protected Mode, MediumIL) site, Internet Explorer must handle the navigation in a new process. In IE7 on Vista, this was very visible—a new browser window would open automatically. In IE8, with the introduction of Loosely-Coupled IE (LCIE), we can handle this more subtly.

Background on Loosely-Coupled IE

In LCIE, IE always has at least two processes—the browser Frame Manager process (which always runs at MediumIL unless you start IE as admin) and one or more browser Tab Content processes, which run at:

  • LowIL for Protected Mode sites
  • MediumIL for Intranet/Trusted sites
  • HighIL (if IE is started as Admin)

Because the Frame Manager process can “visually” host tabs of any integrity level, if the user navigates a page from a LowIL zone to a MediumIL zone, the Frame Manager process can silently swap out the current tab process with a tab process running at a different integrity level. This operation is called a “Virtual Tab switch.”

Losing Control

For compatibility with the most likely scenarios, Internet Explorer assumes that the default tab process will be a Low Integrity tab. Hence, when Internet Explorer is created by COM Automation, the tab process defaults to a Low Integrity tab. If the browser determines that the navigation requires a Medium Integrity Tab Content process, a virtual tab switch is performed. Now, here’s where things get interesting—because the script or code driving Internet Explorer via Automation has a reference to the now-irrelevant tab process, it loses control.

Regaining Control

Now, it’s possible for the caller to handle this situation, by trapping the NewProcess event and reacting accordingly. However, this requires a fair bit of code, and in some cases it might be desirable for an automation caller to simply evaluate its own needs (e.g. it is only configured to navigate to Intranet pages) and invoke an instance of Internet Explorer running at MediumIL to start with. In languages like C++ and C#, this is easy, just CoCreate an instance of CLSID_InternetExplorerMedium ("{D5E8041D-920F-45e9-B8FB-B1DEB82C6E5E}"). When using this CLSID, the object will default to a MediumIL Tab Content process. How this works under the covers is pretty simple: the registry key HKEY_CLASSES_ROOT\CLSID\{D5E8041D-920F-45e9-B8FB-B1DEB82C6E5E}\LocalServer32 contains a REG_EXPAND_SZ with the value "%ProgramFiles(x86)%\Internet Explorer\iexplore.exe" -startmediumtab

Unfortunately, as far as I can tell, there’s no way for scripting languages like VBScript or JavaScript running in CScript or WScript to pass a CLSID into CreateObject—it only accepts a ProgID. UPDATE: WndSks noted in the comments below that you can use the syntax Set IE = GetObject("new:{D5E8041D-920F-45e9-B8FB-B1DEB82C6E5E}")

There’s no ProgID that maps to CLSID_InternetExplorerMedium, but you can trivially create one with a simple registry update.

Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\InternetExplorer.ApplicationMedium]

[HKEY_CLASSES_ROOT\InternetExplorer.ApplicationMedium\CLSID]
@="{D5E8041D-920F-45e9-B8FB-B1DEB82C6E5E}"

After that, you can invoke a MediumIL instance of IE from script like so:

Set IE = CreateObject("InternetExplorer.ApplicationMedium")
' IE.Visible = false ' This is the default
IE.Navigate2 "https://intranetpage/"

So long as you navigate this instance only to pages that run outside of Protected Mode, your automation code will not lose its reference and the Internet Explorer window will remain invisible, unless you explicitly change the visible property.

-Eric