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.
This commit is contained in:
mstoltz%netscape.com 2001-05-30 02:22:22 +00:00
Родитель 4d16e8ca6e
Коммит 00ba04ac0e
2 изменённых файлов: 52 добавлений и 47 удалений

Просмотреть файл

@ -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<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
// 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

Просмотреть файл

@ -4037,6 +4037,41 @@ nsDocShell::InternalLoad(nsIURI * aURI,
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...
// 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<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);
// 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<nsIDocShellTreeItem> parentItem;
rv = GetSameTypeParent(getter_AddRefs(parentItem));