Bug 519928 - IFRAME inside designMode disables JavaScript, breaking current clickjacking defenses; r=Olli.Pettay

This commit is contained in:
Ehsan Akhgari
2010-06-04 17:03:50 -04:00
parent a4bd3075f3
commit 3129224585
9 changed files with 220 additions and 69 deletions

View File

@@ -11166,3 +11166,97 @@ nsDocShell::GetPrintPreview(nsIWebBrowserPrint** aPrintPreview)
#ifdef DEBUG
unsigned long nsDocShell::gNumberOfDocShells = 0;
#endif
NS_IMETHODIMP
nsDocShell::GetCanExecuteScripts(PRBool *aResult)
{
NS_ENSURE_ARG_POINTER(aResult);
*aResult = PR_FALSE; // disallow by default
nsCOMPtr<nsIDocShell> docshell = this;
nsCOMPtr<nsIDocShellTreeItem> globalObjTreeItem =
do_QueryInterface(docshell);
if (globalObjTreeItem)
{
nsCOMPtr<nsIDocShellTreeItem> treeItem(globalObjTreeItem);
nsCOMPtr<nsIDocShellTreeItem> parentItem;
PRBool firstPass = PR_TRUE;
PRBool lookForParents = PR_FALSE;
// Walk up the docshell tree to see if any containing docshell disallows scripts
do
{
nsresult rv = docshell->GetAllowJavascript(aResult);
if (NS_FAILED(rv)) return rv;
if (!*aResult) {
nsDocShell* realDocshell = static_cast<nsDocShell*>(docshell.get());
if (realDocshell->mContentViewer) {
nsIDocument* doc = realDocshell->mContentViewer->GetDocument();
if (doc && doc->HasFlag(NODE_IS_EDITABLE) &&
realDocshell->mEditorData) {
nsCOMPtr<nsIEditingSession> editSession;
realDocshell->mEditorData->GetEditingSession(getter_AddRefs(editSession));
PRBool jsDisabled = PR_FALSE;
if (editSession &&
NS_SUCCEEDED(rv = editSession->GetJsAndPluginsDisabled(&jsDisabled))) {
if (firstPass) {
if (jsDisabled) {
// We have a docshell which has been explicitly set
// to design mode, so we disallow scripts.
return NS_OK;
}
// The docshell was not explicitly set to design mode,
// so it must be so because a parent was explicitly
// set to design mode. We don't need to look at higher
// docshells.
*aResult = PR_TRUE;
break;
} else if (lookForParents && jsDisabled) {
// If a parent was explicitly set to design mode,
// we should allow script execution on the child.
*aResult = PR_TRUE;
break;
}
// If the child docshell allows scripting, and the
// parent is inside design mode, we don't need to look
// further.
*aResult = PR_TRUE;
return NS_OK;
}
NS_WARNING("The editing session does not work?");
return NS_FAILED(rv) ? rv : NS_ERROR_FAILURE;
}
if (firstPass) {
// Don't be too hard on docshells on the first pass.
// There may be a parent docshell which has been set
// to design mode, so look for it.
lookForParents = PR_TRUE;
} else {
// We have a docshell which disallows scripts
// and is not editable, so we shouldn't allow
// scripts at all.
return NS_OK;
}
}
} else if (lookForParents) {
// The parent docshell was not explicitly set to design
// mode, so js on the child docshell was disabled for
// another reason. Therefore, we need to disable js.
return NS_OK;
}
firstPass = PR_FALSE;
treeItem->GetParent(getter_AddRefs(parentItem));
treeItem.swap(parentItem);
docshell = do_QueryInterface(treeItem);
#ifdef DEBUG
if (treeItem && !docshell) {
NS_ERROR("cannot get a docshell from a treeItem!");
}
#endif // DEBUG
} while (treeItem && docshell);
}
return NS_OK;
}