caps/include/nsScriptSecurityManager.h
	caps/src/nsScriptSecurityManager.cpp
	modules/libpref/src/init/all.js
Fix
24565 nsScriptSecurityManager::GetSecurityLevel() is a performance
24567 re-write DOM glue security checks to avoid NS_WITH_SERVICE()
r=waterson

Files:
	dom/src/base/nsGlobalWindow.cpp
	layout/base/src/nsDocument.cpp
	layout/base/src/nsGenericElement.cpp
Fix assertion failure for 1-character property names.


Files:
	dom/src/jsurl/nsJSProtocolHandler.cpp
	webshell/src/nsDocLoader.cpp
Fix 18653 "javascript:" URLs cross windows problems (probably regressi
r=nisheeth

Files:
	layout/events/src/nsEventListenerManager.cpp
Fix
23834 document.onkeypress allows sniffing keystrokes
24152 document.onclick shows links from other window
r=joki


git-svn-id: svn://10.0.0.236/trunk@58429 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
norris%netscape.com 2000-01-23 04:23:14 +00:00
parent 162b271993
commit e4653042f2
13 changed files with 223 additions and 172 deletions

View File

@ -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<nsIPrincipal>* 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;

View File

@ -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<nsICodebasePrincipal> codebase = do_QueryInterface(principal, &rv);
if (NS_FAILED(rv))
return rv;
nsCOMPtr<nsICodebasePrincipal> 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<nsIPrincipal> 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<nsIPrincipal> 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;
}

View File

@ -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<nsIAtom> atom = getter_AddRefs(NS_NewAtom(mPropName));
nsIEventListenerManager *mManager = nsnull;

View File

@ -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<nsIAtom> atom = getter_AddRefs(NS_NewAtom(propName));
nsIEventListenerManager *manager = nsnull;

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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<nsIURI> referringUri;
if (originalURI) {
referringUri = originalURI;
} else {
nsCOMPtr<nsIWebShell> 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<nsIURI> 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;
}

View File

@ -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<nsIAtom> atom = getter_AddRefs(NS_NewAtom(mPropName));
nsIEventListenerManager *mManager = nsnull;

View File

@ -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<nsIAtom> atom = getter_AddRefs(NS_NewAtom(propName));
nsIEventListenerManager *manager = nsnull;

View File

@ -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);
}

View File

@ -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");

View File

@ -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<nsIChannel> pChannel;
nsCOMPtr<nsIInterfaceRequestor> requestor (do_QueryInterface(aContainer));
// Create a referrer URI
nsCOMPtr<nsIURI> 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,

View File

@ -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<nsIChannel> pChannel;
nsCOMPtr<nsIInterfaceRequestor> requestor (do_QueryInterface(aContainer));
// Create a referrer URI
nsCOMPtr<nsIURI> 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,