Fixes for bugs 79796, 77203, and 54060. r=jband@netscape.com,

sr=brendan@mozilla.org


git-svn-id: svn://10.0.0.236/trunk@94546 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
mstoltz%netscape.com
2001-05-11 00:43:27 +00:00
parent 9a69a824ba
commit 28f5530d9c
7 changed files with 76 additions and 114 deletions

View File

@@ -64,7 +64,7 @@
#include "nsIWindowWatcher.h"
#include "nsIConsoleService.h"
#include "nsISecurityCheckedComponent.h"
#include "nsIPref.h"
#include "nsIPrefBranchInternal.h"
static NS_DEFINE_IID(kIIOServiceIID, NS_IIOSERVICE_IID);
static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID);
@@ -143,12 +143,10 @@ nsScriptSecurityManager::CheckPropertyAccess(PRUint32 aAction,
nsISupports* aObj,
nsIClassInfo* aClassInfo,
const char* aClassName,
const char* aProperty,
PRBool aSkipFrame)
const char* aProperty)
{
return CheckPropertyAccessImpl(aAction, nsnull, aJSContext, aJSObject, aObj,
aClassInfo, nsnull, aClassName, aProperty,
aSkipFrame, nsnull);
aClassInfo, nsnull, aClassName, aProperty, nsnull);
}
nsresult
@@ -157,13 +155,10 @@ nsScriptSecurityManager::CheckPropertyAccessImpl(PRUint32 aAction,
JSContext* aJSContext, JSObject* aJSObject,
nsISupports* aObj, nsIClassInfo* aClassInfo,
jsval aName, const char* aClassName,
const char* aProperty,
PRBool aSkipFrame, void** aPolicy)
const char* aProperty, void** aPolicy)
{
nsCOMPtr<nsIPrincipal> subjectPrincipal;
JSStackFrame *notused;
if (NS_FAILED(GetPrincipalAndFrame(aJSContext, aSkipFrame,
getter_AddRefs(subjectPrincipal), &notused)))
if (NS_FAILED(GetSubjectPrincipal(aJSContext, getter_AddRefs(subjectPrincipal))))
return NS_ERROR_FAILURE;
PRBool equals;
@@ -245,8 +240,7 @@ nsScriptSecurityManager::CheckPropertyAccessImpl(PRUint32 aAction,
getter_AddRefs(objectPrincipal))))
return NS_ERROR_FAILURE;
rv = CheckSameOrigin(aJSContext, subjectPrincipal, objectPrincipal,
aAction == nsIXPCSecurityManager::ACCESS_SET_PROPERTY,
aSkipFrame);
aAction == nsIXPCSecurityManager::ACCESS_SET_PROPERTY);
}
else
rv = NS_ERROR_DOM_SECURITY_ERR;
@@ -318,7 +312,7 @@ nsScriptSecurityManager::CheckPropertyAccessImpl(PRUint32 aAction,
}
}
}
rv = CheckXPCPermissions(aJSContext, aObj, objectSecurityLevel, aSkipFrame,
rv = CheckXPCPermissions(aJSContext, aObj, objectSecurityLevel,
"Permission denied to access property");
#ifdef DEBUG_mstoltz
if(NS_SUCCEEDED(rv))
@@ -331,8 +325,7 @@ nsScriptSecurityManager::CheckPropertyAccessImpl(PRUint32 aAction,
nsresult
nsScriptSecurityManager::CheckSameOrigin(JSContext *aCx, nsIPrincipal* aSubject,
nsIPrincipal* aObject, PRUint32 aAction,
PRBool aSkipFrame)
nsIPrincipal* aObject, PRUint32 aAction)
{
/*
** Get origin of subject and object and compare.
@@ -366,7 +359,7 @@ nsScriptSecurityManager::CheckSameOrigin(JSContext *aCx, nsIPrincipal* aSubject,
PRBool capabilityEnabled = PR_FALSE;
const char* cap = aAction == nsIXPCSecurityManager::ACCESS_SET_PROPERTY ?
"UniversalBrowserWrite" : "UniversalBrowserRead";
if (NS_FAILED(IsCapabilityEnabledImpl(cap, aSkipFrame, &capabilityEnabled)))
if (NS_FAILED(IsCapabilityEnabled(cap, &capabilityEnabled)))
return NS_ERROR_FAILURE;
if (capabilityEnabled)
return NS_OK;
@@ -411,7 +404,7 @@ nsScriptSecurityManager::GetSecurityLevel(JSContext* aJSContext,
//-- Look up the security policy for this property
nsCAutoString prefName;
if (NS_FAILED(GetPrefName(principal, aClassName, aPropertyName,
classPolicy, prefName)))
classPolicy, prefName)))
return SCRIPT_SECURITY_NO_ACCESS;
char *secLevelString;
rv = mSecurityPrefs->SecurityGetCharPref(prefName, &secLevelString);
@@ -420,6 +413,18 @@ nsScriptSecurityManager::GetSecurityLevel(JSContext* aJSContext,
prefName += (aAction == nsIXPCSecurityManager::ACCESS_SET_PROPERTY ? ".set" : ".get");
rv = mSecurityPrefs->SecurityGetCharPref(prefName, &secLevelString);
}
if (NS_FAILED(rv)) //-- No site policy for this property; look for a default policy
{
if (NS_FAILED(GetPrefName(principal, aClassName, aPropertyName,
nsnull, prefName)))
return SCRIPT_SECURITY_NO_ACCESS;
rv = mSecurityPrefs->SecurityGetCharPref(prefName, &secLevelString);
if (NS_FAILED(rv))
{
prefName += (aAction == nsIXPCSecurityManager::ACCESS_SET_PROPERTY ? ".set" : ".get");
rv = mSecurityPrefs->SecurityGetCharPref(prefName, &secLevelString);
}
}
if (NS_SUCCEEDED(rv) && secLevelString)
{
if (PL_strcmp(secLevelString, "sameOrigin") == 0)
@@ -571,7 +576,7 @@ nsScriptSecurityManager::CheckLoadURIFromScript(JSContext *cx, nsIURI *aURI)
// Get principal of currently executing script.
nsCOMPtr<nsIPrincipal> principal;
if (NS_FAILED(GetCallingPrincipal(cx, getter_AddRefs(principal))))
if (NS_FAILED(GetSubjectPrincipal(cx, getter_AddRefs(principal))))
return NS_ERROR_FAILURE;
// Native code can load all URIs.
@@ -689,6 +694,7 @@ nsScriptSecurityManager::CheckLoadURI(nsIURI *aSourceURI, nsIURI *aTargetURI,
};
nsXPIDLCString targetSpec;
const char* targetPage;
for (unsigned i=0; i < sizeof(protocolList)/sizeof(protocolList[0]); i++) {
if (nsCRT::strcasecmp(targetScheme, protocolList[i].name) == 0) {
PRBool doCheck = PR_FALSE;
@@ -707,9 +713,11 @@ nsScriptSecurityManager::CheckLoadURI(nsIURI *aSourceURI, nsIURI *aTargetURI,
// Allow loading about:blank, otherwise deny
if(NS_FAILED(targetUri->GetSpec(getter_Copies(targetSpec))))
return NS_ERROR_FAILURE;
return (PL_strcmp(targetSpec, "about:blank") == 0) ||
(PL_strcmp(targetSpec, "about:") == 0) ||
(PL_strcmp(targetSpec, "about:mozilla") == 0) ?
targetPage = targetSpec.get() + sizeof("about:") - 1;
return (PL_strcmp(targetPage, "blank") == 0) ||
(PL_strcmp(targetPage, "") == 0) ||
(PL_strcmp(targetPage, "mozilla") == 0) ||
(PL_strcmp(targetPage, "credits") == 0) ?
NS_OK : ReportErrorToConsole(aTargetURI);
case DenyProtocol:
// Deny access
@@ -1069,10 +1077,16 @@ nsScriptSecurityManager::GetFunctionObjectPrincipal(JSContext *cx,
nsIPrincipal **result)
{
JSFunction *fun = (JSFunction *) JS_GetPrivate(cx, obj);
if (JS_GetFunctionObject(fun) != obj)
// Function has been cloned; get principals from scope
return GetObjectPrincipal(cx, obj, result);
JSScript *script = JS_GetFunctionScript(cx, fun);
if (script && JS_GetFunctionObject(fun) != obj)
{
// 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.
return GetObjectPrincipal(cx, obj, result);
}
return GetScriptPrincipal(cx, script, result);
}
@@ -1093,20 +1107,11 @@ nsScriptSecurityManager::GetFramePrincipal(JSContext *cx,
nsresult
nsScriptSecurityManager::GetPrincipalAndFrame(JSContext *cx,
PRBool skipInnerFrame,
nsIPrincipal **result,
JSStackFrame **frameResult)
{
// Get principals from innermost frame of JavaScript or Java.
JSStackFrame *fp = nsnull; // tell JS_FrameIterator to start at innermost
if (skipInnerFrame) // Skip the innermost frame
{
fp = JS_FrameIterator(cx, &fp);
#ifdef DEBUG_mstoltz
if(!fp)
printf("####### JS stack weirdness in GetPrincipalAndFrame.\n");
#endif
}
for (fp = JS_FrameIterator(cx, &fp); fp; fp = JS_FrameIterator(cx, &fp))
{
if (NS_FAILED(GetFramePrincipal(cx, fp, result)))
@@ -1149,15 +1154,7 @@ nsScriptSecurityManager::GetSubjectPrincipal(JSContext *cx,
nsIPrincipal **result)
{
JSStackFrame *fp;
return GetPrincipalAndFrame(cx, PR_FALSE, result, &fp);
}
nsresult
nsScriptSecurityManager::GetCallingPrincipal(JSContext *cx,
nsIPrincipal **result)
{
JSStackFrame *fp;
return GetPrincipalAndFrame(cx, PR_TRUE, result, &fp);
return GetPrincipalAndFrame(cx, result, &fp);
}
nsresult
@@ -1262,14 +1259,6 @@ nsScriptSecurityManager::SavePrincipal(nsIPrincipal* aToSave)
NS_IMETHODIMP
nsScriptSecurityManager::IsCapabilityEnabled(const char *capability,
PRBool *result)
{
return IsCapabilityEnabledImpl(capability, PR_FALSE, result);
}
nsresult
nsScriptSecurityManager::IsCapabilityEnabledImpl(const char *capability,
PRBool aSkipFrame,
PRBool *result)
{
nsresult rv;
JSStackFrame *fp = nsnull;
@@ -1280,9 +1269,6 @@ nsScriptSecurityManager::IsCapabilityEnabledImpl(const char *capability,
*result = PR_TRUE;
return NS_OK;
}
if (aSkipFrame)
fp = JS_FrameIterator(cx, &fp);
do
{
nsCOMPtr<nsIPrincipal> principal;
@@ -1494,8 +1480,7 @@ nsScriptSecurityManager::EnableCapability(const char *capability)
}
nsCOMPtr<nsIPrincipal> principal;
if (NS_FAILED(GetPrincipalAndFrame(cx, PR_FALSE, getter_AddRefs(principal),
&fp)))
if (NS_FAILED(GetPrincipalAndFrame(cx, getter_AddRefs(principal), &fp)))
return NS_ERROR_FAILURE;
void *annotation = JS_GetFrameAnnotation(cx, fp);
PRBool enabled;
@@ -1527,8 +1512,7 @@ nsScriptSecurityManager::RevertCapability(const char *capability)
JSContext *cx = GetCurrentContextQuick();
JSStackFrame *fp;
nsCOMPtr<nsIPrincipal> principal;
if (NS_FAILED(GetPrincipalAndFrame(cx, PR_FALSE, getter_AddRefs(principal),
&fp)))
if (NS_FAILED(GetPrincipalAndFrame(cx, getter_AddRefs(principal), &fp)))
return NS_ERROR_FAILURE;
void *annotation = JS_GetFrameAnnotation(cx, fp);
principal->RevertCapability(capability, &annotation);
@@ -1542,8 +1526,7 @@ nsScriptSecurityManager::DisableCapability(const char *capability)
JSContext *cx = GetCurrentContextQuick();
JSStackFrame *fp;
nsCOMPtr<nsIPrincipal> principal;
if (NS_FAILED(GetPrincipalAndFrame(cx, PR_FALSE, getter_AddRefs(principal),
&fp)))
if (NS_FAILED(GetPrincipalAndFrame(cx, getter_AddRefs(principal), &fp)))
return NS_ERROR_FAILURE;
void *annotation = JS_GetFrameAnnotation(cx, fp);
principal->DisableCapability(capability, &annotation);
@@ -1656,8 +1639,7 @@ nsScriptSecurityManager::CanCreateWrapper(JSContext *aJSContext,
if (checkedComponent)
checkedComponent->CanCreateWrapper((nsIID *)&aIID, getter_Copies(objectSecurityLevel));
// XXX Do we skip a frame here or not? Need to find out
return CheckXPCPermissions(aJSContext, aObj, objectSecurityLevel, PR_TRUE,
return CheckXPCPermissions(aJSContext, aObj, objectSecurityLevel,
"Permission denied to create wrapper for object");
}
@@ -1672,7 +1654,7 @@ nsScriptSecurityManager::CanCreateInstance(JSContext *aJSContext,
PR_FREEIF(cidStr);
#endif
return CheckXPCPermissions(aJSContext, nsnull, nsnull, PR_FALSE,
return CheckXPCPermissions(aJSContext, nsnull, nsnull,
"Permission denied to create instance of class");
}
@@ -1686,7 +1668,7 @@ nsScriptSecurityManager::CanGetService(JSContext *aJSContext,
PR_FREEIF(cidStr);
#endif
return CheckXPCPermissions(aJSContext, nsnull, nsnull, PR_FALSE,
return CheckXPCPermissions(aJSContext, nsnull, nsnull,
"Permission denied to get service");
}
@@ -1702,19 +1684,18 @@ nsScriptSecurityManager::CanAccess(PRUint32 aAction,
void** aPolicy)
{
return CheckPropertyAccessImpl(aAction, aCallContext, aJSContext, aJSObject,
aObj, aClassInfo, aName, nsnull, nsnull, PR_TRUE, aPolicy);
aObj, aClassInfo, aName, nsnull, nsnull, aPolicy);
}
nsresult
nsScriptSecurityManager::CheckXPCPermissions(JSContext *aJSContext,
nsISupports* aObj,
const char* aObjectSecurityLevel,
PRBool aSkipFrame,
const char* aErrorMsg)
{
//-- Check for the all-powerful UniversalXPConnect privilege
PRBool ok = PR_FALSE;
if (NS_SUCCEEDED(IsCapabilityEnabledImpl("UniversalXPConnect", aSkipFrame, &ok)) && ok)
if (NS_SUCCEEDED(IsCapabilityEnabled("UniversalXPConnect", &ok)) && ok)
return NS_OK;
//-- If the object implements nsISecurityCheckedComponent, it has a non-default policy.
@@ -2135,14 +2116,14 @@ nsScriptSecurityManager::InitPrefs()
NS_ENSURE_SUCCESS(rv, rv);
mSecurityPrefs = do_QueryInterface(mPrefs, &rv);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIPref> oldPrefService = do_GetService(NS_PREF_CONTRACTID, &rv);
nsCOMPtr<nsIPrefBranchInternal> prefBranchInternal = do_QueryInterface(mPrefs, &rv);
NS_ENSURE_SUCCESS(rv, rv);
// Set the initial value of the "javascript.enabled" prefs
JSEnabledPrefChanged();
// set observer callbacks in case the value of the pref changes
oldPrefService->AddObserver(sJSEnabledPrefName, this);
oldPrefService->AddObserver(sJSMailEnabledPrefName, this);
prefBranchInternal->AddObserver(sJSEnabledPrefName, this);
prefBranchInternal->AddObserver(sJSMailEnabledPrefName, this);
PRUint32 prefCount;
char** prefNames;
@@ -2162,7 +2143,7 @@ nsScriptSecurityManager::InitPrefs()
NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(prefCount, prefNames);
//-- Set a callback for principal changes
oldPrefService->AddObserver(sPrincipalPrefix, this);
prefBranchInternal->AddObserver(sPrincipalPrefix, this);
return NS_OK;
}