diff --git a/mozilla/caps/include/nsScriptSecurityManager.h b/mozilla/caps/include/nsScriptSecurityManager.h index 12c5b84f04f..2e042d348f7 100644 --- a/mozilla/caps/include/nsScriptSecurityManager.h +++ b/mozilla/caps/include/nsScriptSecurityManager.h @@ -30,6 +30,8 @@ #include "nsDOMPropEnums.h" #include "nsCOMPtr.h" +class nsIPref; + #define NS_SCRIPTSECURITYMANAGER_CID \ { 0x7ee2a4c0, 0x4b93, 0x17d3, \ { 0xba, 0x18, 0x00, 0x60, 0xb0, 0xf1, 0x99, 0xa2 }} @@ -50,8 +52,6 @@ public: static nsScriptSecurityManager * GetScriptSecurityManager(); - nsObjectHashtable *mOriginToPolicyMap; - private: void LookupPrincipal(nsCOMPtr* aPrincipal); @@ -67,10 +67,11 @@ private: PRBool* result); PRInt32 GetSecurityLevel(nsIPrincipal *principal, nsDOMProp domProp, - PRBool isWrite, char **capability); + PRBool isWrite, nsCString &capability); NS_IMETHOD - GetPrefName(nsIPrincipal *principal, nsDOMProp domProp, char **result); + GetPrefName(nsIPrincipal *principal, nsDOMProp domProp, + nsCString &result); NS_IMETHOD CheckXPCPermissions(JSContext *cx); @@ -87,6 +88,8 @@ private: static int JSEnabledPrefChanged(const char *pref, void *data); + nsObjectHashtable *mOriginToPolicyMap; + nsIPref *mPrefs; nsIPrincipal *mSystemPrincipal; nsSupportsHashtable *mPrincipals; PRBool mIsJavaScriptEnabled; diff --git a/mozilla/caps/src/nsScriptSecurityManager.cpp b/mozilla/caps/src/nsScriptSecurityManager.cpp index 423a031b34f..f369ccde94d 100644 --- a/mozilla/caps/src/nsScriptSecurityManager.cpp +++ b/mozilla/caps/src/nsScriptSecurityManager.cpp @@ -1,4 +1,4 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * The contents of this file are subject to the Netscape Public * License Version 1.1 (the "License"); you may not use this file @@ -14,7 +14,7 @@ * * The Initial Developer of the Original Code is Netscape * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1998-1999 Netscape Communications Corporation. All + * Copyright (C) 1998-2000 Netscape Communications Corporation. All * Rights Reserved. * * Contributor(s): @@ -363,9 +363,17 @@ nsScriptSecurityManager::CheckScriptAccess(JSContext *cx, if (NS_FAILED(GetSubjectPrincipal(cx, getter_AddRefs(principal)))) { return NS_ERROR_FAILURE; } - nsXPIDLCString capability; + PRBool equals; + if (!principal || + NS_SUCCEEDED(principal->Equals(mSystemPrincipal, &equals)) && equals) + { + // We have native code or the system principal: just allow access + *aResult = PR_TRUE; + return NS_OK; + } + nsCAutoString capability; PRInt32 secLevel = GetSecurityLevel(principal, domProp, isWrite, - getter_Copies(capability)); + capability); switch (secLevel) { case SCRIPT_SECURITY_UNDEFINED_ACCESS: // If no preference is defined for this property, allow access. @@ -480,18 +488,6 @@ nsScriptSecurityManager::CheckLoadURI(nsIURI *aFromURI, } } - // Temporary: allow a preference to disable this check - nsresult rv; - NS_WITH_SERVICE(nsIPref, prefs, kPrefServiceCID, &rv); - if (NS_FAILED(rv)) - return NS_ERROR_FAILURE; - PRBool enabled; - if (NS_SUCCEEDED(prefs->GetBoolPref("security.checkuri", &enabled)) && - !enabled) - { - return NS_OK; - } - return NS_ERROR_DOM_BAD_URI; } @@ -598,10 +594,10 @@ nsScriptSecurityManager::CanExecuteScripts(nsIPrincipal *principal, if (GetBit(hasDomainPolicyVector, NS_DOM_PROP_JAVASCRIPT_ENABLED)) { // We may have a per-domain security policy for JavaScript execution - nsXPIDLCString capability; + nsCAutoString capability; PRInt32 secLevel = GetSecurityLevel(principal, NS_DOM_PROP_JAVASCRIPT_ENABLED, - PR_FALSE, getter_Copies(capability)); + PR_FALSE, capability); if (secLevel != SCRIPT_SECURITY_UNDEFINED_ACCESS) { *result = (secLevel == SCRIPT_SECURITY_ALL_ACCESS); return NS_OK; @@ -880,8 +876,9 @@ nsScriptSecurityManager::CanSetProperty(JSContext *aJSContext, /////////////////// nsScriptSecurityManager::nsScriptSecurityManager(void) - : mOriginToPolicyMap(nsnull), mSystemPrincipal(nsnull), - mPrincipals(nsnull), mIsJavaScriptEnabled(PR_FALSE), + : mOriginToPolicyMap(nsnull), mPrefs(nsnull), + mSystemPrincipal(nsnull), mPrincipals(nsnull), + mIsJavaScriptEnabled(PR_FALSE), mIsMailJavaScriptEnabled(PR_FALSE) { NS_INIT_REFCNT(); @@ -893,6 +890,7 @@ nsScriptSecurityManager::nsScriptSecurityManager(void) nsScriptSecurityManager::~nsScriptSecurityManager(void) { delete mOriginToPolicyMap; + NS_IF_RELEASE(mPrefs); NS_IF_RELEASE(mSystemPrincipal); delete mPrincipals; } @@ -1004,19 +1002,6 @@ nsScriptSecurityManager::CheckPermissions(JSContext *aCx, JSObject *aObj, if (*aResult) return NS_OK; - // Temporary: only enforce if security.checkdomprops pref not disabled - nsresult rv; - NS_WITH_SERVICE(nsIPref, prefs, kPrefServiceCID, &rv); - if (NS_FAILED(rv)) - return NS_ERROR_FAILURE; - PRBool enabled; - if (NS_SUCCEEDED(prefs->GetBoolPref("security.checkdomprops", &enabled)) && - !enabled) - { - *aResult = PR_TRUE; - return NS_OK; - } - /* ** Access tests failed, so now report error. */ @@ -1030,30 +1015,22 @@ nsScriptSecurityManager::CheckPermissions(JSContext *aCx, JSObject *aObj, return NS_ERROR_DOM_PROP_ACCESS_DENIED; } - PRInt32 nsScriptSecurityManager::GetSecurityLevel(nsIPrincipal *principal, nsDOMProp domProp, - PRBool isWrite, char **capability) + PRBool isWrite, + nsCString &capability) { - nsXPIDLCString prefName; - if (NS_FAILED(GetPrefName(principal, domProp, getter_Copies(prefName)))) + nsCAutoString prefName; + if (NS_FAILED(GetPrefName(principal, domProp, prefName))) return SCRIPT_SECURITY_NO_ACCESS; PRInt32 secLevel; char *secLevelString; nsresult rv; - NS_WITH_SERVICE(nsIPref, prefs, kPrefServiceCID, &rv); - if (NS_FAILED(rv)) - return NS_ERROR_FAILURE; - rv = prefs->CopyCharPref(prefName, &secLevelString); + rv = mPrefs->CopyCharPref(prefName, &secLevelString); if (NS_FAILED(rv)) { - nsAutoString s = (const char *) prefName; - s += (isWrite ? ".write" : ".read"); - char *cp = s.ToNewCString(); - if (!cp) - return SCRIPT_SECURITY_NO_ACCESS; - rv = prefs->CopyCharPref(cp, &secLevelString); - Recycle(cp); + prefName += (isWrite ? ".write" : ".read"); + rv = mPrefs->CopyCharPref(prefName, &secLevelString); } if (NS_SUCCEEDED(rv) && secLevelString) { if (PL_strcmp(secLevelString, "sameOrigin") == 0) @@ -1064,7 +1041,7 @@ nsScriptSecurityManager::GetSecurityLevel(nsIPrincipal *principal, secLevel = SCRIPT_SECURITY_NO_ACCESS; else { // string should be the name of a capability - *capability = secLevelString; + capability = secLevelString; secLevelString = nsnull; secLevel = SCRIPT_SECURITY_CAPABILITY_ONLY; } @@ -1083,19 +1060,6 @@ nsScriptSecurityManager::CheckXPCPermissions(JSContext *aJSContext) if (NS_FAILED(IsCapabilityEnabled("UniversalXPConnect", &ok))) ok = PR_FALSE; if (!ok) { - // Check the pref "security.checkxpconnect". If it exists and is - // set to false, don't report an error. - nsresult rv; - NS_WITH_SERVICE(nsIPref, prefs, kPrefServiceCID, &rv); - if (NS_SUCCEEDED(rv)) { - PRBool enabled; - if (NS_SUCCEEDED(prefs->GetBoolPref("security.checkxpconnect", - &enabled)) && - !enabled) - { - return NS_OK; - } - } static const char msg[] = "Access denied to XPConnect service."; JS_SetPendingException(aJSContext, STRING_TO_JSVAL(JS_NewStringCopyZ(aJSContext, msg))); @@ -1110,24 +1074,24 @@ static char *domPropNames[] = { NS_IMETHODIMP -nsScriptSecurityManager::GetPrefName(nsIPrincipal *principal, nsDOMProp domProp, - char **result) +nsScriptSecurityManager::GetPrefName(nsIPrincipal *principal, + nsDOMProp domProp, nsCString &result) { - nsresult rv; static const char *defaultStr = "default"; - nsAutoString s = "security.policy."; + result = "security.policy."; if (!GetBit(hasDomainPolicyVector, domProp)) { - s += defaultStr; + result += defaultStr; } else { PRBool equals = PR_TRUE; if (principal && NS_FAILED(principal->Equals(mSystemPrincipal, &equals))) return NS_ERROR_FAILURE; if (equals) { - s += defaultStr; + result += defaultStr; } else { - nsCOMPtr codebase = do_QueryInterface(principal, &rv); - if (NS_FAILED(rv)) - return rv; + nsCOMPtr codebase = do_QueryInterface(principal); + if (!codebase) + return NS_ERROR_FAILURE; + nsresult rv; nsXPIDLCString origin; if (NS_FAILED(rv = codebase->GetOrigin(getter_Copies(origin)))) return rv; @@ -1137,15 +1101,14 @@ nsScriptSecurityManager::GetPrefName(nsIPrincipal *principal, nsDOMProp domProp, policy = (nsCString *) mOriginToPolicyMap->Get(&key); } if (policy) - s += *policy; + result += *policy; else - s += defaultStr; + result += defaultStr; } } - s += '.'; - s += domPropNames[domProp]; - *result = s.ToNewCString(); - return *result ? NS_OK : NS_ERROR_OUT_OF_MEMORY; + result += '.'; + result += domPropNames[domProp]; + return NS_OK; } static nsDOMProp @@ -1176,18 +1139,13 @@ DeleteEntry(nsHashKey *aKey, void *aData, void* closure) return PR_TRUE; } -struct PolicyEnumeratorInfo { - nsIPref *prefs; - nsScriptSecurityManager *secMan; -}; - void nsScriptSecurityManager::enumeratePolicyCallback(const char *prefName, void *data) { if (!prefName || !*prefName) return; - PolicyEnumeratorInfo *info = (PolicyEnumeratorInfo *) data; + nsScriptSecurityManager *mgr = (nsScriptSecurityManager *) data; unsigned count = 0; const char *dots[5]; const char *p; @@ -1210,14 +1168,14 @@ nsScriptSecurityManager::enumeratePolicyCallback(const char *prefName, const char *sitesName = dots[2] + 1; int sitesLength = dots[3] - sitesName; if (PL_strncmp("sites", sitesName, sitesLength) == 0) { - if (!info->secMan->mOriginToPolicyMap) { - info->secMan->mOriginToPolicyMap = + if (!mgr->mOriginToPolicyMap) { + mgr->mOriginToPolicyMap = new nsObjectHashtable(nsnull, nsnull, DeleteEntry, nsnull); - if (!info->secMan->mOriginToPolicyMap) + if (!mgr->mOriginToPolicyMap) return; } char *s; - if (NS_FAILED(info->prefs->CopyCharPref(prefName, &s))) + if (NS_FAILED(mgr->mPrefs->CopyCharPref(prefName, &s))) return; char *q=s; char *r=s; @@ -1230,7 +1188,7 @@ nsScriptSecurityManager::enumeratePolicyCallback(const char *prefName, nsCString *value = new nsCString(policyName, policyLength); if (!value) break; - info->secMan->mOriginToPolicyMap->Put(&key, value); + mgr->mOriginToPolicyMap->Put(&key, value); q = r + 1; } r++; @@ -1244,55 +1202,59 @@ nsScriptSecurityManager::enumeratePolicyCallback(const char *prefName, int domPropLength = dots[4] - domPropName; nsDOMProp domProp = findDomProp(domPropName, domPropLength); if (domProp < NS_DOM_PROP_MAX) { - SetBit(info->secMan->hasPolicyVector, domProp); + SetBit(mgr->hasPolicyVector, domProp); if (!isDefault) - SetBit(info->secMan->hasDomainPolicyVector, domProp); + SetBit(mgr->hasDomainPolicyVector, domProp); return; } } NS_ASSERTION(PR_FALSE, "DOM property name invalid or not found"); } +struct EnumeratePrincipalsInfo { + // this struct doesn't own these objects; consider them parameters on + // the stack + nsSupportsHashtable *ht; + nsIPref *prefs; +}; + void nsScriptSecurityManager::enumeratePrincipalsCallback(const char *prefName, - void *aPrincipals) + void *voidParam) { - nsresult rv; - NS_WITH_SERVICE(nsIPref, prefs, kPrefServiceCID, &rv); - if (NS_FAILED(rv)) return; - - char* data; - if (NS_FAILED(prefs->CopyCharPref(prefName, &data))) return; - - static char codebaseName[] = "[Codebase "; - static char certificateName[] = "[Certificate "; - nsCOMPtr principal; - if (PL_strncasecmp(data, codebaseName, sizeof(codebaseName)-1) == 0) - { - nsCodebasePrincipal *codebase = new nsCodebasePrincipal(); - NS_ADDREF(codebase); - if (!codebase) return; - rv = codebase->Init(data); - if (NS_FAILED(rv)) return; - principal = do_QueryInterface((nsBasePrincipal*)codebase); - NS_RELEASE(codebase); - } - else if (PL_strncasecmp(data, certificateName, sizeof(certificateName)-1) == 0) - { - nsCertificatePrincipal *certificate = new nsCertificatePrincipal(); - NS_ADDREF(certificate); - if (!certificate) return; - rv = certificate->Init(data); - if (NS_FAILED(rv)) return; - principal = do_QueryInterface((nsBasePrincipal*)certificate); - NS_RELEASE(certificate); - } - else - return; - nsCRT::free(data); - nsSupportsHashtable* principals = (nsSupportsHashtable*)aPrincipals; - nsIPrincipalKey key(principal); - principals->Put(&key, principal); + EnumeratePrincipalsInfo *info = (EnumeratePrincipalsInfo *) voidParam; + + char* data; + if (NS_FAILED(info->prefs->CopyCharPref(prefName, &data))) + return; + + static char codebaseName[] = "[Codebase "; + static char certificateName[] = "[Certificate "; + nsCOMPtr principal; + if (PL_strncasecmp(data, codebaseName, sizeof(codebaseName)-1) == 0) { + nsCodebasePrincipal *codebase = new nsCodebasePrincipal(); + if (codebase) { + NS_ADDREF(codebase); + if (NS_SUCCEEDED(codebase->Init(data))) + principal = do_QueryInterface((nsBasePrincipal*)codebase); + NS_RELEASE(codebase); + } + } else if (PL_strncasecmp(data, certificateName, + sizeof(certificateName)-1) == 0) + { + nsCertificatePrincipal *certificate = new nsCertificatePrincipal(); + if (certificate) { + NS_ADDREF(certificate); + if (NS_SUCCEEDED(certificate->Init(data))) + principal = do_QueryInterface((nsBasePrincipal*)certificate); + NS_RELEASE(certificate); + } + } + nsCRT::free(data); + if (principal) { + nsIPrincipalKey key(principal); + info->ht->Put(&key, principal); + } } static const char jsEnabledPrefName[] = "javascript.enabled"; @@ -1301,22 +1263,17 @@ static const char jsMailEnabledPrefName[] = "javascript.allow.mailnews"; int nsScriptSecurityManager::JSEnabledPrefChanged(const char *pref, void *data) { - nsresult rv; - NS_WITH_SERVICE(nsIPref, prefs, kPrefServiceCID, &rv); - if (NS_FAILED(rv)) - return NS_ERROR_FAILURE; - nsScriptSecurityManager *secMgr = (nsScriptSecurityManager *) data; - if (NS_FAILED(prefs->GetBoolPref(jsEnabledPrefName, - &secMgr->mIsJavaScriptEnabled))) + if (NS_FAILED(secMgr->mPrefs->GetBoolPref(jsEnabledPrefName, + &secMgr->mIsJavaScriptEnabled))) { // Default to enabled. secMgr->mIsJavaScriptEnabled = PR_TRUE; } - if (NS_FAILED(prefs->GetBoolPref(jsMailEnabledPrefName, - &secMgr->mIsMailJavaScriptEnabled))) + if (NS_FAILED(secMgr->mPrefs->GetBoolPref(jsMailEnabledPrefName, + &secMgr->mIsMailJavaScriptEnabled))) { // Default to enabled. secMgr->mIsMailJavaScriptEnabled = PR_TRUE; @@ -1338,29 +1295,30 @@ nsScriptSecurityManager::InitFromPrefs() if (NS_FAILED(rv)) return NS_ERROR_FAILURE; + mPrefs = prefs; + NS_ADDREF(mPrefs); + // Set the initial value of the "javascript.enabled" pref JSEnabledPrefChanged(jsEnabledPrefName, this); // set callbacks in case the value of the pref changes prefs->RegisterCallback(jsEnabledPrefName, JSEnabledPrefChanged, this); prefs->RegisterCallback(jsMailEnabledPrefName, JSEnabledPrefChanged, this); - - PolicyEnumeratorInfo info; - info.prefs = prefs; - info.secMan = this; prefs->EnumerateChildren("security.policy", nsScriptSecurityManager::enumeratePolicyCallback, - (void *) &info); - if (!mPrincipals) - { - mPrincipals = new nsSupportsHashtable(31); - if (!mPrincipals) - return NS_ERROR_OUT_OF_MEMORY; - } + (void *) this); + if (!mPrincipals) { + mPrincipals = new nsSupportsHashtable(31); + if (!mPrincipals) + return NS_ERROR_OUT_OF_MEMORY; + } + EnumeratePrincipalsInfo info; + info.ht = mPrincipals; + info.prefs = mPrefs; prefs->EnumerateChildren("security.principal", nsScriptSecurityManager::enumeratePrincipalsCallback, - (void *)mPrincipals); + (void *) &info); return NS_OK; } diff --git a/mozilla/content/base/src/nsDocument.cpp b/mozilla/content/base/src/nsDocument.cpp index e023b4e8a4b..c037e9041e6 100644 --- a/mozilla/content/base/src/nsDocument.cpp +++ b/mozilla/content/base/src/nsDocument.cpp @@ -2517,7 +2517,8 @@ PRBool nsDocument::SetProperty(JSContext *aContext, JSObject *aObj, jsval aID if (JS_TypeOfValue(aContext, *aVp) == JSTYPE_FUNCTION && JSVAL_IS_STRING(aID)) { nsAutoString mPropName, mPrefix; mPropName.SetString(JS_GetStringChars(JS_ValueToString(aContext, aID))); - mPrefix.SetString(mPropName.GetUnicode(), 2); + if (mPropName.Length() > 2) + mPrefix.SetString(mPropName.GetUnicode(), 2); if (mPrefix == "on") { nsCOMPtr atom = getter_AddRefs(NS_NewAtom(mPropName)); nsIEventListenerManager *mManager = nsnull; diff --git a/mozilla/content/base/src/nsGenericElement.cpp b/mozilla/content/base/src/nsGenericElement.cpp index eb31f880f32..d6162323564 100644 --- a/mozilla/content/base/src/nsGenericElement.cpp +++ b/mozilla/content/base/src/nsGenericElement.cpp @@ -1125,7 +1125,8 @@ nsGenericElement::SetProperty(JSContext *aContext, JSObject *aObj, jsval aID, js if (JS_TypeOfValue(aContext, *aVp) == JSTYPE_FUNCTION && JSVAL_IS_STRING(aID)) { nsAutoString propName, prefix; propName.SetString(JS_GetStringChars(JS_ValueToString(aContext, aID))); - prefix.SetString(propName.GetUnicode(), 2); + if (propName.Length() > 2) + prefix.SetString(propName.GetUnicode(), 2); if (prefix == "on") { nsCOMPtr atom = getter_AddRefs(NS_NewAtom(propName)); nsIEventListenerManager *manager = nsnull; diff --git a/mozilla/content/events/src/nsEventListenerManager.cpp b/mozilla/content/events/src/nsEventListenerManager.cpp index d98202133c0..d2ceeab96ab 100644 --- a/mozilla/content/events/src/nsEventListenerManager.cpp +++ b/mozilla/content/events/src/nsEventListenerManager.cpp @@ -51,6 +51,10 @@ #include "nsIContent.h" #include "nsCOMPtr.h" #include "nsIServiceManager.h" +#include "nsIScriptSecurityManager.h" +#include "nsDOMPropEnums.h" +#include "nsDOMError.h" +#include "nsIJSContextStack.h" static NS_DEFINE_IID(kIEventListenerManagerIID, NS_IEVENTLISTENERMANAGER_IID); static NS_DEFINE_IID(kIDOMEventListenerIID, NS_IDOMEVENTLISTENER_IID); @@ -574,6 +578,33 @@ nsresult nsEventListenerManager::RegisterScriptEventListener(nsIScriptContext *a nsIAtom *aName, REFNSIID aIID) { + // Check that we have access to set an event listener. Prevents snooping attacks across + // domains by setting onkeypress handlers, for instance. + // You'd think it'd work just to get the JSContext from aContext, but that's actually the + // JSContext whose private object parents the object in aScriptObjectOwner. + nsresult rv; + NS_WITH_SERVICE(nsIJSContextStack, stack, "nsThreadJSContextStack", + &rv); + if (NS_FAILED(rv)) + return rv; + JSContext *cx; + if (NS_FAILED(stack->Peek(&cx))) + return nsnull; + JSObject *jsobj; + if (NS_FAILED(rv = aScriptObjectOwner->GetScriptObject(aContext, (void**)&jsobj))) + return rv; + NS_WITH_SERVICE(nsIScriptSecurityManager, securityManager, + NS_SCRIPTSECURITYMANAGER_PROGID, &rv); + if (NS_FAILED(rv)) + return rv; + PRBool ok; + if (NS_FAILED(rv = securityManager->CheckScriptAccess(cx, jsobj, + NS_DOM_PROP_EVENTTARGET_ADDEVENTLISTENER, PR_TRUE, &ok))) + { + return rv; + } + if (!ok) + return NS_ERROR_DOM_PROP_ACCESS_DENIED; return SetJSEventListener(aContext, aScriptObjectOwner, aName, aIID, PR_FALSE); } diff --git a/mozilla/dom/src/base/nsGlobalWindow.cpp b/mozilla/dom/src/base/nsGlobalWindow.cpp index 214f6e1100b..87179eadc78 100644 --- a/mozilla/dom/src/base/nsGlobalWindow.cpp +++ b/mozilla/dom/src/base/nsGlobalWindow.cpp @@ -2138,7 +2138,7 @@ GlobalWindowImpl::RunTimeout(nsTimeoutImpl *aTimeout) } err = timeout->timer->Init(nsGlobalWindow_RunTimeout, timeout, - delay32, NS_PRIORITY_LOWEST); + delay32); if (NS_OK != err) { NS_RELEASE(temp); NS_RELEASE(tempContext); @@ -2298,7 +2298,7 @@ GlobalWindowImpl::SetTimeoutOrInterval(JSContext *cx, } err = timeout->timer->Init(nsGlobalWindow_RunTimeout, timeout, - (PRInt32)interval, NS_PRIORITY_LOWEST); + (PRInt32)interval); if (NS_OK != err) { DropTimeout(timeout); return err; @@ -2992,7 +2992,8 @@ GlobalWindowImpl::AddProperty(JSContext *aContext, JSObject *aObj, jsval aID, js nsString mPropName; nsAutoString mPrefix; mPropName.SetString(JS_GetStringChars(JS_ValueToString(aContext, aID))); - mPrefix.SetString(mPropName.GetUnicode(), 2); + if (mPropName.Length() > 2) + mPrefix.SetString(mPropName.GetUnicode(), 2); if (mPrefix == "on") { return CheckForEventListener(aContext, mPropName); } diff --git a/mozilla/dom/src/jsurl/nsJSProtocolHandler.cpp b/mozilla/dom/src/jsurl/nsJSProtocolHandler.cpp index 71a0c44c9f7..d5d72fedfa9 100644 --- a/mozilla/dom/src/jsurl/nsJSProtocolHandler.cpp +++ b/mozilla/dom/src/jsurl/nsJSProtocolHandler.cpp @@ -232,7 +232,11 @@ nsJSProtocolHandler::NewChannel(const char* verb, if (NS_FAILED(securityManager->GetSubjectPrincipal(getter_AddRefs(principal)))) return NS_ERROR_FAILURE; if (!principal) { - // No scripts currently executing; get principal from referrer of link + // No scripts currently executing; get principal from referrer of link + nsCOMPtr referringUri; + if (originalURI) { + referringUri = originalURI; + } else { nsCOMPtr webShell; webShell = do_QueryInterface(globalOwner); if (!webShell) @@ -241,11 +245,12 @@ nsJSProtocolHandler::NewChannel(const char* verb, if (NS_FAILED(webShell->GetURL(&url))) return NS_ERROR_FAILURE; nsString urlStr(url); - nsCOMPtr uri; - if (NS_FAILED(NS_NewURI(getter_AddRefs(uri), urlStr, nsnull))) - return NS_ERROR_FAILURE; - if (NS_FAILED(securityManager->GetCodebasePrincipal(uri, getter_AddRefs(principal)))) + + if (NS_FAILED(NS_NewURI(getter_AddRefs(referringUri), urlStr, nsnull))) return NS_ERROR_FAILURE; + } + if (NS_FAILED(securityManager->GetCodebasePrincipal(referringUri, getter_AddRefs(principal)))) + return NS_ERROR_FAILURE; } diff --git a/mozilla/layout/base/src/nsDocument.cpp b/mozilla/layout/base/src/nsDocument.cpp index e023b4e8a4b..c037e9041e6 100644 --- a/mozilla/layout/base/src/nsDocument.cpp +++ b/mozilla/layout/base/src/nsDocument.cpp @@ -2517,7 +2517,8 @@ PRBool nsDocument::SetProperty(JSContext *aContext, JSObject *aObj, jsval aID if (JS_TypeOfValue(aContext, *aVp) == JSTYPE_FUNCTION && JSVAL_IS_STRING(aID)) { nsAutoString mPropName, mPrefix; mPropName.SetString(JS_GetStringChars(JS_ValueToString(aContext, aID))); - mPrefix.SetString(mPropName.GetUnicode(), 2); + if (mPropName.Length() > 2) + mPrefix.SetString(mPropName.GetUnicode(), 2); if (mPrefix == "on") { nsCOMPtr atom = getter_AddRefs(NS_NewAtom(mPropName)); nsIEventListenerManager *mManager = nsnull; diff --git a/mozilla/layout/base/src/nsGenericElement.cpp b/mozilla/layout/base/src/nsGenericElement.cpp index eb31f880f32..d6162323564 100644 --- a/mozilla/layout/base/src/nsGenericElement.cpp +++ b/mozilla/layout/base/src/nsGenericElement.cpp @@ -1125,7 +1125,8 @@ nsGenericElement::SetProperty(JSContext *aContext, JSObject *aObj, jsval aID, js if (JS_TypeOfValue(aContext, *aVp) == JSTYPE_FUNCTION && JSVAL_IS_STRING(aID)) { nsAutoString propName, prefix; propName.SetString(JS_GetStringChars(JS_ValueToString(aContext, aID))); - prefix.SetString(propName.GetUnicode(), 2); + if (propName.Length() > 2) + prefix.SetString(propName.GetUnicode(), 2); if (prefix == "on") { nsCOMPtr atom = getter_AddRefs(NS_NewAtom(propName)); nsIEventListenerManager *manager = nsnull; diff --git a/mozilla/layout/events/src/nsEventListenerManager.cpp b/mozilla/layout/events/src/nsEventListenerManager.cpp index d98202133c0..d2ceeab96ab 100644 --- a/mozilla/layout/events/src/nsEventListenerManager.cpp +++ b/mozilla/layout/events/src/nsEventListenerManager.cpp @@ -51,6 +51,10 @@ #include "nsIContent.h" #include "nsCOMPtr.h" #include "nsIServiceManager.h" +#include "nsIScriptSecurityManager.h" +#include "nsDOMPropEnums.h" +#include "nsDOMError.h" +#include "nsIJSContextStack.h" static NS_DEFINE_IID(kIEventListenerManagerIID, NS_IEVENTLISTENERMANAGER_IID); static NS_DEFINE_IID(kIDOMEventListenerIID, NS_IDOMEVENTLISTENER_IID); @@ -574,6 +578,33 @@ nsresult nsEventListenerManager::RegisterScriptEventListener(nsIScriptContext *a nsIAtom *aName, REFNSIID aIID) { + // Check that we have access to set an event listener. Prevents snooping attacks across + // domains by setting onkeypress handlers, for instance. + // You'd think it'd work just to get the JSContext from aContext, but that's actually the + // JSContext whose private object parents the object in aScriptObjectOwner. + nsresult rv; + NS_WITH_SERVICE(nsIJSContextStack, stack, "nsThreadJSContextStack", + &rv); + if (NS_FAILED(rv)) + return rv; + JSContext *cx; + if (NS_FAILED(stack->Peek(&cx))) + return nsnull; + JSObject *jsobj; + if (NS_FAILED(rv = aScriptObjectOwner->GetScriptObject(aContext, (void**)&jsobj))) + return rv; + NS_WITH_SERVICE(nsIScriptSecurityManager, securityManager, + NS_SCRIPTSECURITYMANAGER_PROGID, &rv); + if (NS_FAILED(rv)) + return rv; + PRBool ok; + if (NS_FAILED(rv = securityManager->CheckScriptAccess(cx, jsobj, + NS_DOM_PROP_EVENTTARGET_ADDEVENTLISTENER, PR_TRUE, &ok))) + { + return rv; + } + if (!ok) + return NS_ERROR_DOM_PROP_ACCESS_DENIED; return SetJSEventListener(aContext, aScriptObjectOwner, aName, aIID, PR_FALSE); } diff --git a/mozilla/modules/libpref/src/init/all.js b/mozilla/modules/libpref/src/init/all.js index 8e8858c4fb4..1746056fa8f 100644 --- a/mozilla/modules/libpref/src/init/all.js +++ b/mozilla/modules/libpref/src/init/all.js @@ -301,10 +301,6 @@ pref("mime.table.allow_remove", true); pref("browser.registration.enable", false); pref("browser.registration.url", ""); -pref("security.checkuri", true); -pref("security.checkdomprops", true); -pref("security.checkxpconnect", true); - pref("signed.applets.codebase_principal_support", false); pref("security.policy.default.barprop.visible.write", "UniversalBrowserWrite"); diff --git a/mozilla/uriloader/base/nsDocLoader.cpp b/mozilla/uriloader/base/nsDocLoader.cpp index 8182eeb7fd6..5e06aff2fd7 100644 --- a/mozilla/uriloader/base/nsDocLoader.cpp +++ b/mozilla/uriloader/base/nsDocLoader.cpp @@ -45,6 +45,7 @@ #include "nsIURILoader.h" #include "nsCURILoader.h" +#include "nsIIOService.h" // XXX ick ick ick #include "nsIContentViewerContainer.h" @@ -346,9 +347,19 @@ nsDocLoaderImpl::LoadDocument(nsIURI * aUri, if (NS_SUCCEEDED(rv)) { nsCOMPtr pChannel; nsCOMPtr requestor (do_QueryInterface(aContainer)); + + // Create a referrer URI + nsCOMPtr referrer; + if (aReferrer) { + nsAutoString tempReferrer(aReferrer); + char* referrerStr = tempReferrer.ToNewCString(); + pNetService->NewURI(referrerStr, nsnull, getter_AddRefs(referrer)); + Recycle(referrerStr); + } + rv = pNetService->NewChannelFromURI(aCommand, aUri, mLoadGroup, requestor, - aType, nsnull /* referring uri */, 0, 0, - getter_AddRefs(pChannel)); + aType, referrer /* referring uri */, 0, 0, + getter_AddRefs(pChannel)); if (NS_FAILED(rv)) return rv; // uhoh we were unable to get a channel to handle the url!!! // figure out if we need to set the post data stream on the channel...right now, diff --git a/mozilla/webshell/src/nsDocLoader.cpp b/mozilla/webshell/src/nsDocLoader.cpp index 8182eeb7fd6..5e06aff2fd7 100644 --- a/mozilla/webshell/src/nsDocLoader.cpp +++ b/mozilla/webshell/src/nsDocLoader.cpp @@ -45,6 +45,7 @@ #include "nsIURILoader.h" #include "nsCURILoader.h" +#include "nsIIOService.h" // XXX ick ick ick #include "nsIContentViewerContainer.h" @@ -346,9 +347,19 @@ nsDocLoaderImpl::LoadDocument(nsIURI * aUri, if (NS_SUCCEEDED(rv)) { nsCOMPtr pChannel; nsCOMPtr requestor (do_QueryInterface(aContainer)); + + // Create a referrer URI + nsCOMPtr referrer; + if (aReferrer) { + nsAutoString tempReferrer(aReferrer); + char* referrerStr = tempReferrer.ToNewCString(); + pNetService->NewURI(referrerStr, nsnull, getter_AddRefs(referrer)); + Recycle(referrerStr); + } + rv = pNetService->NewChannelFromURI(aCommand, aUri, mLoadGroup, requestor, - aType, nsnull /* referring uri */, 0, 0, - getter_AddRefs(pChannel)); + aType, referrer /* referring uri */, 0, 0, + getter_AddRefs(pChannel)); if (NS_FAILED(rv)) return rv; // uhoh we were unable to get a channel to handle the url!!! // figure out if we need to set the post data stream on the channel...right now,