From b51a5f778499cf0f161b9c89a6f02b4663fc23e7 Mon Sep 17 00:00:00 2001 From: "mstoltz%netscape.com" Date: Wed, 30 May 2001 02:22:22 +0000 Subject: [PATCH] bug 77485 - exploit inserting a function into another window using targeted javascript URL links. Two-part fix: moving the call to GetCurrentDocumentOwner in nsDocShell::LoadInternal to before the target docshell is called, and changing nsScriptSecurityManager::GetFunctionObjectPrincipal to only get the principal from the function object's scope chain if the function object's principal is the system principal. r=jst, sr=vidur, a=asa. git-svn-id: svn://10.0.0.236/trunk@96045 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/caps/src/nsScriptSecurityManager.cpp | 25 ++++--- mozilla/docshell/base/nsDocShell.cpp | 74 ++++++++++---------- 2 files changed, 52 insertions(+), 47 deletions(-) diff --git a/mozilla/caps/src/nsScriptSecurityManager.cpp b/mozilla/caps/src/nsScriptSecurityManager.cpp index e7ef4ca68f4..5a411d9836e 100644 --- a/mozilla/caps/src/nsScriptSecurityManager.cpp +++ b/mozilla/caps/src/nsScriptSecurityManager.cpp @@ -28,8 +28,6 @@ #include "nsIURL.h" #include "nsIJARURI.h" #include "nspr.h" -#include "plstr.h" -#include "nsCOMPtr.h" #include "nsJSPrincipals.h" #include "nsSystemPrincipal.h" #include "nsCodebasePrincipal.h" @@ -39,7 +37,6 @@ #include "nsXPIDLString.h" #include "nsIJSContextStack.h" #include "nsDOMError.h" -#include "xpcexception.h" #include "nsDOMCID.h" #include "jsdbgapi.h" #include "nsIXPConnect.h" @@ -1105,17 +1102,25 @@ nsScriptSecurityManager::GetFunctionObjectPrincipal(JSContext *cx, nsIPrincipal **result) { JSFunction *fun = (JSFunction *) JS_GetPrivate(cx, obj); - JSScript *script = JS_GetFunctionScript(cx, fun); - if (script && JS_GetFunctionObject(fun) != obj) + + nsCOMPtr scriptPrincipal; + if (script) + if (NS_FAILED(GetScriptPrincipal(cx, script, getter_AddRefs(scriptPrincipal)))) + return NS_ERROR_FAILURE; + + if (script && (JS_GetFunctionObject(fun) != obj) && + (scriptPrincipal.get() == mSystemPrincipal)) { - // Scripted function has been cloned; get principals from obj's - // parent-linked scope chain. We do not get object principals for a - // cloned *native* function, because the subject in that case is a - // script or function further down the stack who is calling us. + // Function is brutally-shared chrome. For this case only, + // get a principal from the object's scope instead of the + // principal compiled into the function. return GetObjectPrincipal(cx, obj, result); } - return GetScriptPrincipal(cx, script, result); + + *result = scriptPrincipal.get(); + NS_IF_ADDREF(*result); + return NS_OK; } nsresult diff --git a/mozilla/docshell/base/nsDocShell.cpp b/mozilla/docshell/base/nsDocShell.cpp index 6891ff5b0a8..67a1e594b0e 100644 --- a/mozilla/docshell/base/nsDocShell.cpp +++ b/mozilla/docshell/base/nsDocShell.cpp @@ -4037,6 +4037,41 @@ nsDocShell::InternalLoad(nsIURI * aURI, nsresult rv; + nsCOMPtr owner(aOwner); + // + // Check to see if an owner should be inherited... + // + if (!owner) { + // If an owner was passed in, use it + // Otherwise, if the caller has allowed inheriting from the current document, + // or if we're being called from chrome (which has the system principal), + // then use the current document principal + if (!aInheritOwner) { + // See if there's system or chrome JS code running + nsCOMPtr secMan; + + secMan = do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv); + if (NS_SUCCEEDED(rv)) { + nsCOMPtr sysPrin; + nsCOMPtr subjectPrin; + + // Just to compare, not to use! + rv = secMan->GetSystemPrincipal(getter_AddRefs(sysPrin)); + if (NS_SUCCEEDED(rv)) { + rv = secMan->GetSubjectPrincipal(getter_AddRefs(subjectPrin)); + } + // XXX: Why can the subject principal be nsnull?? + if (NS_SUCCEEDED(rv) && + (!subjectPrin || sysPrin.get() == subjectPrin.get())) { + aInheritOwner = PR_TRUE; + } + } + } + if (aInheritOwner) { + GetCurrentDocumentOwner(getter_AddRefs(owner)); + } + } + // // Resolve the window target before going any further... // If the load has been targeted to another DocShell, then transfer the @@ -4129,7 +4164,7 @@ nsDocShell::InternalLoad(nsIURI * aURI, if (targetDocShell) { rv = targetDocShell->InternalLoad(aURI, aReferrer, - aOwner, + owner, aInheritOwner, aStopActiveDoc, nsnull, // No window target @@ -4223,41 +4258,6 @@ nsDocShell::InternalLoad(nsIURI * aURI, } } - nsCOMPtr owner(aOwner); - // - // Check to see if an owner should be inherited... - // - if (!owner) { - // If an owner was passed in, use it - // Otherwise, if the caller has allowed inheriting from the current document, - // or if we're being called from chrome (which has the system principal), - // then use the current document principal - if (!aInheritOwner) { - // See if there's system or chrome JS code running - nsCOMPtr secMan; - - secMan = do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv); - if (NS_SUCCEEDED(rv)) { - nsCOMPtr sysPrin; - nsCOMPtr subjectPrin; - - // Just to compare, not to use! - rv = secMan->GetSystemPrincipal(getter_AddRefs(sysPrin)); - if (NS_SUCCEEDED(rv)) { - rv = secMan->GetSubjectPrincipal(getter_AddRefs(subjectPrin)); - } - // XXX: Why can the subject principal be nsnull?? - if (NS_SUCCEEDED(rv) && - (!subjectPrin || sysPrin.get() == subjectPrin.get())) { - aInheritOwner = PR_TRUE; - } - } - } - if (aInheritOwner) { - GetCurrentDocumentOwner(getter_AddRefs(owner)); - } - } - NS_ENSURE_SUCCESS(StopLoad(), NS_ERROR_FAILURE); // Cancel any timers that were set for this loader. CancelRefreshURITimers(); @@ -4314,7 +4314,7 @@ nsDocShell::GetCurrentDocumentOwner(nsISupports ** aOwner) return NS_ERROR_FAILURE; rv = docViewer->GetDocument(*getter_AddRefs(document)); } - else //-- If there's no document loaded yet, look at the parent (frameset) + else //-- If there's no document loaded yet, look at the parent (frameset) { nsCOMPtr parentItem; rv = GetSameTypeParent(getter_AddRefs(parentItem));