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:
parent
1e0b92d55f
commit
b51a5f7784
@ -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
|
||||||
|
|||||||
@ -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));
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user