Fixing bug 201132. Always use the JSPrincipals from the target object when compiling event handlers, never use the principals of the global object in which the event handler is compiled. r=mstoltz@netscape.com (and heikki@netscape.com), sr=brendan@mozilla.org

This commit is contained in:
jst%netscape.com 2003-04-13 04:05:29 +00:00
parent a7bfbefcd3
commit c2949137a8
2 changed files with 40 additions and 24 deletions

View File

@ -120,6 +120,7 @@ static PRBool sDidShutdown = PR_FALSE;
static PRInt32 sContextCount = 0;
static nsIScriptSecurityManager *sSecurityManager = nsnull;
void JS_DLL_CALLBACK
NS_ScriptErrorReporter(JSContext *cx,
@ -436,8 +437,6 @@ nsJSContext::nsJSContext(JSRuntime *aRuntime) : mGCOnDestruction(PR_TRUE)
nsJSContext::~nsJSContext()
{
mSecurityManager = nsnull; // Force release
// Cope with JS_NewContext failure in ctor (XXXbe move NewContext to Init?)
if (!mContext)
return;
@ -469,9 +468,12 @@ nsJSContext::~nsJSContext()
if (!sContextCount && sDidShutdown) {
// The last context is being deleted, and we're already in the
// process of shutting down, release the JS runtime service.
// process of shutting down, release the JS runtime service, and
// the security manager.
NS_IF_RELEASE(sRuntimeService);
NS_IF_RELEASE(sSecurityManager);
}
}
@ -930,25 +932,35 @@ nsJSContext::CompileEventHandler(void *aTarget, nsIAtom *aName,
const nsAString& aBody,
PRBool aShared, void** aHandler)
{
if (!sSecurityManager) {
NS_ERROR("Huh, we need a script security manager to compile "
"an event handler!");
return NS_ERROR_UNEXPECTED;
}
JSObject *target = (JSObject*)aTarget;
JSPrincipals *jsprin = nsnull;
nsCOMPtr<nsIScriptGlobalObject> global;
GetGlobalObject(getter_AddRefs(global));
if (global) {
// XXXbe why the two-step QI? speed up via a new GetGlobalObjectData func?
nsCOMPtr<nsIScriptObjectPrincipal> globalData = do_QueryInterface(global);
if (globalData) {
nsCOMPtr<nsIPrincipal> prin;
if (NS_FAILED(globalData->GetPrincipal(getter_AddRefs(prin))))
return NS_ERROR_FAILURE;
prin->GetJSPrincipals(&jsprin);
}
if (target) {
// Get the principal of the event target (the object principal),
// don't get the principal of the global object in this context
// since that opens up security exploits with delayed event
// handler compilation on stale DOM objects (objects that live in
// a document that has already been unloaded).
nsCOMPtr<nsIPrincipal> prin;
nsresult rv = sSecurityManager->GetObjectPrincipal(mContext, target,
getter_AddRefs(prin));
NS_ENSURE_SUCCESS(rv, rv);
prin->GetJSPrincipals(&jsprin);
NS_ENSURE_TRUE(jsprin, NS_ERROR_NOT_AVAILABLE);
}
char charName[64];
AtomToEventHandlerName(aName, charName, sizeof charName);
JSObject *target = (JSObject*)aTarget;
JSFunction* fun =
::JS_CompileUCFunctionForPrincipals(mContext, target, jsprin,
charName, 1, gEventArgv,
@ -957,10 +969,12 @@ nsJSContext::CompileEventHandler(void *aTarget, nsIAtom *aName,
//XXXbe filename, lineno:
nsnull, 0);
if (jsprin)
if (jsprin) {
JSPRINCIPALS_DROP(mContext, jsprin);
if (!fun)
}
if (!fun) {
return NS_ERROR_FAILURE;
}
JSObject *handler = ::JS_GetFunctionObject(fun);
if (aHandler)
@ -1522,14 +1536,12 @@ nsJSContext::ScriptEvaluated(PRBool aTerminated)
NS_IMETHODIMP
nsJSContext::GetSecurityManager(nsIScriptSecurityManager **aInstancePtr)
{
if (!mSecurityManager) {
nsresult rv = NS_OK;
*aInstancePtr = sSecurityManager;
mSecurityManager = do_GetService(kScriptSecurityManagerContractID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
if (!sSecurityManager) {
return NS_ERROR_NOT_AVAILABLE;
}
*aInstancePtr = mSecurityManager;
NS_ADDREF(*aInstancePtr);
return NS_OK;
@ -1732,6 +1744,10 @@ nsresult nsJSEnvironment::Init()
}
#endif /* OJI */
rv = nsServiceManager::GetService(kScriptSecurityManagerContractID,
NS_GET_IID(nsIScriptSecurityManager),
(nsISupports**)&sSecurityManager);
isInitialized = NS_SUCCEEDED(rv);
return rv;
@ -1754,9 +1770,10 @@ void nsJSEnvironment::ShutDown()
if (!sContextCount) {
// We're being shutdown, and there are no more contexts
// alive, release the JS runtime service.
// alive, release the JS runtime service and the security manager.
NS_IF_RELEASE(sRuntimeService);
NS_IF_RELEASE(sSecurityManager);
}
sDidShutdown = PR_TRUE;

View File

@ -144,7 +144,6 @@ private:
JSContext *mContext;
PRUint32 mNumEvaluations;
nsCOMPtr<nsIScriptSecurityManager> mSecurityManager; // [OWNER]
nsIScriptContextOwner* mOwner; /* NB: weak reference, not ADDREF'd */
nsScriptTerminationFunc mTerminationFunc;