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
This commit is contained in:
mstoltz%netscape.com 2001-05-30 02:22:22 +00:00
parent 1e0b92d55f
commit b51a5f7784
2 changed files with 52 additions and 47 deletions

View File

@ -28,8 +28,6 @@
#include "nsIURL.h" #include "nsIURL.h"
#include "nsIJARURI.h" #include "nsIJARURI.h"
#include "nspr.h" #include "nspr.h"
#include "plstr.h"
#include "nsCOMPtr.h"
#include "nsJSPrincipals.h" #include "nsJSPrincipals.h"
#include "nsSystemPrincipal.h" #include "nsSystemPrincipal.h"
#include "nsCodebasePrincipal.h" #include "nsCodebasePrincipal.h"
@ -39,7 +37,6 @@
#include "nsXPIDLString.h" #include "nsXPIDLString.h"
#include "nsIJSContextStack.h" #include "nsIJSContextStack.h"
#include "nsDOMError.h" #include "nsDOMError.h"
#include "xpcexception.h"
#include "nsDOMCID.h" #include "nsDOMCID.h"
#include "jsdbgapi.h" #include "jsdbgapi.h"
#include "nsIXPConnect.h" #include "nsIXPConnect.h"
@ -1105,17 +1102,25 @@ nsScriptSecurityManager::GetFunctionObjectPrincipal(JSContext *cx,
nsIPrincipal **result) nsIPrincipal **result)
{ {
JSFunction *fun = (JSFunction *) JS_GetPrivate(cx, obj); JSFunction *fun = (JSFunction *) JS_GetPrivate(cx, obj);
JSScript *script = JS_GetFunctionScript(cx, fun); JSScript *script = JS_GetFunctionScript(cx, fun);
if (script && JS_GetFunctionObject(fun) != obj)
nsCOMPtr<nsIPrincipal> 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 // Function is brutally-shared chrome. For this case only,
// parent-linked scope chain. We do not get object principals for a // get a principal from the object's scope instead of the
// cloned *native* function, because the subject in that case is a // principal compiled into the function.
// script or function further down the stack who is calling us.
return GetObjectPrincipal(cx, obj, result); return GetObjectPrincipal(cx, obj, result);
} }
return GetScriptPrincipal(cx, script, result);
*result = scriptPrincipal.get();
NS_IF_ADDREF(*result);
return NS_OK;
} }
nsresult nsresult

View File

@ -4037,6 +4037,41 @@ nsDocShell::InternalLoad(nsIURI * aURI,
nsresult rv; nsresult rv;
nsCOMPtr<nsISupports> 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<nsIScriptSecurityManager> secMan;
secMan = do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv);
if (NS_SUCCEEDED(rv)) {
nsCOMPtr<nsIPrincipal> sysPrin;
nsCOMPtr<nsIPrincipal> 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... // Resolve the window target before going any further...
// If the load has been targeted to another DocShell, then transfer the // If the load has been targeted to another DocShell, then transfer the
@ -4129,7 +4164,7 @@ nsDocShell::InternalLoad(nsIURI * aURI,
if (targetDocShell) { if (targetDocShell) {
rv = targetDocShell->InternalLoad(aURI, rv = targetDocShell->InternalLoad(aURI,
aReferrer, aReferrer,
aOwner, owner,
aInheritOwner, aInheritOwner,
aStopActiveDoc, aStopActiveDoc,
nsnull, // No window target nsnull, // No window target
@ -4223,41 +4258,6 @@ nsDocShell::InternalLoad(nsIURI * aURI,
} }
} }
nsCOMPtr<nsISupports> 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<nsIScriptSecurityManager> secMan;
secMan = do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv);
if (NS_SUCCEEDED(rv)) {
nsCOMPtr<nsIPrincipal> sysPrin;
nsCOMPtr<nsIPrincipal> 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); NS_ENSURE_SUCCESS(StopLoad(), NS_ERROR_FAILURE);
// Cancel any timers that were set for this loader. // Cancel any timers that were set for this loader.
CancelRefreshURITimers(); CancelRefreshURITimers();
@ -4314,7 +4314,7 @@ nsDocShell::GetCurrentDocumentOwner(nsISupports ** aOwner)
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
rv = docViewer->GetDocument(*getter_AddRefs(document)); 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<nsIDocShellTreeItem> parentItem; nsCOMPtr<nsIDocShellTreeItem> parentItem;
rv = GetSameTypeParent(getter_AddRefs(parentItem)); rv = GetSameTypeParent(getter_AddRefs(parentItem));