Showing posts with label pop-up blocker. Show all posts
Showing posts with label pop-up blocker. Show all posts

Wednesday, December 5, 2007

the importance of context: security and the dom

This is a re-posting of a post originally published on 2004-07-22. The original can be found here. This version has been updated to match what is currently reality.

Almost every navigation in Internet Explorer results in a flurry of security checks. Many of these checks are fairly obvious things, such as checking the URL of the current location (the context URL) and the pending navigation's destination URL to see if their zones, domains, protocols, etc are the same, different, acceptable, etc. When I worked on Internet Explorer, I spent a significant amount of time debugging strange combinations and ways of navigating. I will not bore you with the details; my goal is to emphasize the importance of context. I will mainly speak to the Internet Explorer Pop-up Blocker's dependence on the context URL.

The Pop-up Blocker is dependent on the context URL. When the page attempts to open a new window, the HTML rendering engine queries the Pop-up Blocker. The Pop-up Blocker looks in the white list to see if this page is exempt from new window management. If, for some reason, the context URL provided is NULL, then obviously it cannot be matched to a domain in the white list.

So let us examine the following:
var oSpan = document.createElement("span");
oSpan.innerHTML =
"<a href="http://www.blogger.com/" target="'_blank'">Microsoft.com</a>";

When the anchor causes the browser to navigate, it will see the _blank and attempt to open a new window. This attempt will have to be verified by Pop-up Blocker. But the span is not parented to anything, thus it has no context. Elements with no context get the default context, which is about:blank, which confers no rights.

The moral of this story is always remember to parent your dynamically created elements to something in the document:

document.appendChild(oSpan);


It's been pointed out that the W3C specification says something about what should happen here and that IE does something wrong (or fails to do something). That may be the case. I was not responsible for the code the implemented the DOM.

Furthermore, adding about:blank to your white list doesn't work either, since it has no domain and the whitelist requires domains.

Sunday, December 2, 2007

the internet explorer pop-up manager and your webbrowser control host

This is a re-posting of a post originally published on 2004-01-26. The original can be found here. This version has been updated to match what is currently reality.

Overview
With the introduction of Windows XP Service Pack 2, Internet Explorer 6 (and up) introduced a built-in pop-up window manager. If your program is going to host the webbrowser control, you may or may not want the pop-up blocker's functionality. This post will describe how to alter, override or enable the pop-up blocker's functionality for application.

Implement INewWindowManager
The basic Implement INewWindowManager. The webbrowser control will QueryInterface its site for this method. You should implement this in the same place you (would) implement IDocHostUIHandler.

When webbrowser control detects a new window is being requested, it will call the EvaluateNewWindow() method on the interface. Just about any method for opening a new window should trigger this call. What follows is boiler-plate for various scenarios:

I Do Not Want Any Pop-up Management
This is the easy case, since pop-up management is opt-in. Simply do nothing. The webbrowser control will query you for INWM. If the query fails, no pop-up management will occur. This decision was made so that applications that already exist would not have to change when Windows XP Service Pack 2 shipped.

I Want Exactly What Internet Explorer Does
This is easy too. Simply implement INWM::ENW() and return E_NOTIMPL. You will get all the same functionality, including checking against the user's white list and action according to the user's preferences.

CMyObject::EvaluateNewWindow(...)
{
return E_NOTIMPL;
}
When the webbrowser control sees the failure code, it will fall back to the default pop-up management.

I Want My Own Logic
Implement INWM::ENW() and use the parameters to decide whether or not to block the new window. Return S_FALSE to block the window and S_OK to allow it:

CMyObject::EvaluateNewWindow(...)
{
HRESULT hr = S_OK;
if (/* your logic here */)
{
hr = S_FALSE;
}
else if (/* more of your logic here */)
{
hr = S_FALSE;
}
// ... and so on ...

// Now update your UI.
switch(hr)
{
case S_OK:
OnPopupNotBlocked(...);
break;

case S_FALSE:
OnPopupBlocked(...);
break;
}

return hr;
}
Developer's Note
I will admit right now, this is the first public interface I ever designed. I was young and stupid and the Interface was not subject to a lot of review by people with more expertise. If I was doing it all over again, I would probably not have done it this way. But it works.