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. UPDATEWndSks 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



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 “

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.


Comments (18)

  1. RichB says:

    Will it work if you pass a clsid: moniker to GetObject()?…/aa392394(v=vs.85).aspx

  2. EricLaw says:

    @RichB: That doesn't appear to work. I'm far from an expert on scripting though.

  3. WndSks says:

    Set IE = GetObject("new:{D5E8041D-920F-45e9-B8FB-B1DEB82C6E5E}")

    IE.Visible = true

  4. EricLaw says:

    Thanks, @WndSks– your syntax does indeed work on Win7.

  5. danimajo says:

    Thanks Eric! Your answer was awesome and really helpfull!

  6. Tony says:

    Thanks a ton…  I created a function to go out and re-capture the lost IE8 windows.  It worked pretty good, but would always cause the window to appear once the tie was broken.


    I’m  have a problem in UI.

    In application contact us anchor tag is there,if we click on contact us anchor tag it open outlook, but application is logging out.

    first we thought that it is IE7 problem,

    in IE7 if we enable Protected mode which is available in tools, it works fine.

    same IE7 is using one of my team member, in his system application works fine,if we enable or disable Protected mode, application works good.

    in another application,same operating system  same Contact-us link works good, means no operating system problem.

    then what might be the problem for this.

    IE7 Version is using by all the team members, it works good for some members and for others to work good, they need to enable to protected mode.

    Can you please help me on this issue.

  8. Mark Sunter-Storey says:

    I found this very useful to understand the inexplicable problem with my internet automation. I first used WndSks GetObject which worked, but then I noticed I could use

    Set IE=new InternetExplorerMedium

    from Microsoft Internet Controls (Feb 2013)

  9. Dpb says:

    Can someone please share the sample of how to trap the 'NewProcess' event?

  10. LCeL says:

    Thank you @EricLaw and @skSdnW! Sorted me right out!

  11. MC says:

    Eric, thanks for your description above.  I've been fighting this issue for a while and haven't found a description of what's going on until now.  However I've tried to implement the suggestions above and my code still fails.  Note that I need to have IE.Visible=False.  Can you tell me if there is some reason that setting that flag to False causes the solutions above to not be applicable?

    I've tried:

       Set IEbrowser = CreateObject("InternetExplorer.application")

       Set IEbrowser = New InternetExplorerMedium

       Set IEbrowser = GetObject("new:{D5E8041D-920F-45e9-B8FB-B1DEB82C6E5E}")

    And all fail on me. Note that I'm not a developer so my skills are challenged. Thanks for any thoughts you have on this.

    [EricLaw]: What are you trying to accomplish overall? Are you using VBScript or something else? Of the three strings you mention, only the 3rd might potentially work from VBScript. I wouldn't expect setting Visible to have any effect, but it would be simple enough for you to try changing that and see if it makes any difference.

  12. DF says:

    This post saved me so much time, great stuff.  Using  Set IE = GetObject("new:{D5E8041D-920F-45e9-B8FB-B1DEB82C6E5E}") instead of SET IE = createobject( internetexplorer.application ) resovled my issues with IE8 vs IE7 on my company's intranet.  

    This post also gave me a better understanding and insight into IE security.

  13. Niirmal says:

    Eric, You are a champ!!!!!!

    The problem that was hampering my work for the last 2 weeks is simply got resolved by this post and with your suggestion of using sing  Set IE = GetObject("new:{D5E8041D-920F-45e9-B8FB-B1DEB82C6E5E}")…

    Thanks a Lot Eric!!!!!!!!! :)

  14. R.D. Holland says:

    I followed the link in the article regarding the NewProcess event. Since I already implement a DWebBrowserEvents2 to handle navigation errors and OnQuit event I added code to handle NewProcess. My intent was to swap out my IWebBrowser2 interface pointer with the one the event documentation claims will be passed into the event handler.

    What I have found is that I get three arguments. The first is a "byref BOOL" (value is VARIANT_FALSE) and the third is an I4 (value as expected is one). However even though the second argument is of type VT_DISPATCH, the value is NULL.

    [EricLaw] Which version of IE? What zone/integrity are you navigating from and what zone/integrity are you navigating to? Can you share your code-snippet?

  15. R.D. Holland says:

    I was leaving the about blank internet zone and going to an intranet zone. I have "enabled protected mode" on the internet zone checked and it is unchecked on local intranet, which I have set to the lowest security level.

    // I should be able to use the regular IE and catch the NewProcess event and use the pointer to the dispatch in the second arg that the MSDN says is "pWb2", leading me to believe I can get my web browser 2 intf from the dispatch. But when I tested this code, the arg was set to VT_DISPATCH but there was no Dispatch pointer in the arg!!! So turning off for now.

    // To test I set UAC to high and reboot. Then I go to IE security settings and for "local intranet", I uncheck the "Enable Protected mode" box and check that box for "Internet". I get this event and then a quit event but as I said, this event gets no disp pointer passed in.

    // If I resolve this, then I can quit reacting to OnQuit (or set a flag since right after this event the quit event arrives and ignore quit) or I can just quit handling OnQuit and restart IE if I get any errors when I try to Navigate. I got errors in all the APIs once OnQuit fired …

    void NewProcess(long lCauseFlag,IDispatch *pWB2,VARIANT_BOOL *Cancel);

    VARIANT * vt_CauseFlag = pDispParams->rgvarg[2].pvarVal;
    DWORD  dwStatusCode =  vt_CauseFlag->lVal;
    IDispatchPtr pWB2 = pDispParams->rgvarg[1].pdispVal;
    if( pWB2 ) {
    if( m_bForProgrammingSolidEdge ) {
      pWB2->QueryInterface(IID_IWebBrowser2, (LPVOID*)& s_WebBrowser );
    } else {
      pWB2->QueryInterface(IID_IWebBrowser2, (LPVOID*)&s_ProgrammingSolidEdgeWebBrowser );

    Eric, When I step through the event with VS 2012 debugger it shows me rgvarg[1] is of type VT_DISPATCH and the variant value is zero. Everything else looks just fine. I have to kill the IE instance using task manager as I am disconnected from the tab process as after the new proc event I get the OnQuit event.

    [EricLaw] Do you find the dispatch pointer provided if you are crossing an integrity boundary in the other direction (namely, navigating from Intranet to Internet?

  16. R.D. Holland says:

    Eric, Since I cannot navigate from the intranet because my webbrowser2 interface is invalid once the process is terminated I did the following. I went to IE options/security and turned protected mode off on the internet and turned it on for the intranet. Now when I startup and navigate to my intranet site I don't get the NewProces event (as expected). Then when I navigate to an internet site I get the NewProcess event (expected) and the dispatch pointer is still not passed to my event handler. This is IE11 on Windows 8.

  17. Pedro Rodrigues says:

    I'm having the same problem as R.D. Holland. No matter what I do, the pWB2 argument of the NewProcess event is always null. Is this a bug? Is there any other way to get the pointer to the new process?

  18. NoelBlanc says:

    Same thing for us, NewProcesss is null.

    We use IE9 (mode IE9, intranet page) and Windows7(32).

    Does exist a special configuration for IE that i forget ?

    the second solution (-startmediumtab) seems to not share "session cookies" between "Ie". So the new page is used without the "session cookie" getting/existing in the first "ie". We don't want to use it.

    Help, please.