зеркало из https://github.com/mozilla/pjs.git
Bug 47905 - adding security check for XMLHttpRequest.open.
Added nsIScriptSecurityManager::CheckConnect for this purpose. Also cleaned up the security check API by removing some unnecessary parameters. r=vidur@netscape.com, sr=jst@netscape.com Bug 79775 - Forward button broken in main mail window. Making WindowWatcher not call GetSubjectPrincipal if the URL to be loaded is chrome, since the calling principal is superfluous in this case. No one has been able to find the root cause of this problem, but this checkin works around it, which is the best we can do for now. r=ducarroz@netscape.com, sr=jst@netscape.com
This commit is contained in:
Родитель
3480594fe1
Коммит
201736a175
|
@ -34,13 +34,19 @@ interface nsIScriptSecurityManager : nsIXPCSecurityManager
|
|||
/**
|
||||
* Checks whether the running script is allowed to access aProperty.
|
||||
*/
|
||||
[noscript] void checkPropertyAccess(in PRUint32 aAction,
|
||||
in JSContextPtr aJSContext,
|
||||
[noscript] void checkPropertyAccess(in JSContextPtr aJSContext,
|
||||
in JSObjectPtr aJSObject,
|
||||
in nsISupports aObj,
|
||||
in nsIClassInfo aClassInfo,
|
||||
in string aClassName,
|
||||
in string aProperty);
|
||||
in string aProperty,
|
||||
in PRUint32 aAction);
|
||||
|
||||
/**
|
||||
* Checks whether the running script is allowed to connect to aTargetURI
|
||||
*/
|
||||
[noscript] void checkConnect(in JSContextPtr aJSContext,
|
||||
in nsIURI aTargetURI,
|
||||
in string aClassName,
|
||||
in string aPropertyName);
|
||||
|
||||
/**
|
||||
* Check that the script currently running in context "cx" can load "uri".
|
||||
|
|
|
@ -112,7 +112,8 @@ private:
|
|||
nsresult
|
||||
CheckPropertyAccessImpl(PRUint32 aAction, nsIXPCNativeCallContext* aCallContext,
|
||||
JSContext* aJSContext, JSObject* aJSObject,
|
||||
nsISupports* aObj, nsIClassInfo* aClassInfo,
|
||||
nsISupports* aObj, nsIURI* aTargetURI,
|
||||
nsIClassInfo* aClassInfo,
|
||||
jsval aName, const char* aClassName,
|
||||
const char* aProperty, void** aPolicy);
|
||||
|
||||
|
@ -122,7 +123,7 @@ private:
|
|||
|
||||
PRInt32
|
||||
GetSecurityLevel(JSContext* aCx, nsIPrincipal *principal,
|
||||
nsIClassInfo* aClassInfo,
|
||||
PRBool aIsDOM,
|
||||
const char* aClassName, const char* aProperty,
|
||||
PRUint32 aAction, nsCString &capability, void** aPolicy);
|
||||
|
||||
|
|
|
@ -137,23 +137,34 @@ NS_IMPL_THREADSAFE_ISUPPORTS3(nsScriptSecurityManager,
|
|||
|
||||
///////////////// Security Checks /////////////////
|
||||
NS_IMETHODIMP
|
||||
nsScriptSecurityManager::CheckPropertyAccess(PRUint32 aAction,
|
||||
JSContext* aJSContext,
|
||||
nsScriptSecurityManager::CheckPropertyAccess(JSContext* aJSContext,
|
||||
JSObject* aJSObject,
|
||||
nsISupports* aObj,
|
||||
nsIClassInfo* aClassInfo,
|
||||
const char* aClassName,
|
||||
const char* aProperty)
|
||||
const char* aPropertyName,
|
||||
PRUint32 aAction)
|
||||
{
|
||||
return CheckPropertyAccessImpl(aAction, nsnull, aJSContext, aJSObject, aObj,
|
||||
aClassInfo, nsnull, aClassName, aProperty, nsnull);
|
||||
return CheckPropertyAccessImpl(aAction, nsnull, aJSContext, aJSObject,
|
||||
nsnull, nsnull, nsnull, nsnull,
|
||||
aClassName, aPropertyName, nsnull);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScriptSecurityManager::CheckConnect(JSContext* aJSContext,
|
||||
nsIURI* aTargetURI,
|
||||
const char* aClassName,
|
||||
const char* aPropertyName)
|
||||
{
|
||||
return CheckPropertyAccessImpl(nsIXPCSecurityManager::ACCESS_GET_PROPERTY, nsnull,
|
||||
aJSContext, nsnull, nsnull, aTargetURI,
|
||||
nsnull, nsnull, aClassName, aPropertyName, nsnull);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsScriptSecurityManager::CheckPropertyAccessImpl(PRUint32 aAction,
|
||||
nsIXPCNativeCallContext* aCallContext,
|
||||
JSContext* aJSContext, JSObject* aJSObject,
|
||||
nsISupports* aObj, nsIClassInfo* aClassInfo,
|
||||
nsISupports* aObj, nsIURI* aTargetURI,
|
||||
nsIClassInfo* aClassInfo,
|
||||
jsval aName, const char* aClassName,
|
||||
const char* aProperty, void** aPolicy)
|
||||
{
|
||||
|
@ -214,8 +225,11 @@ nsScriptSecurityManager::CheckPropertyAccessImpl(PRUint32 aAction,
|
|||
propertyName.AssignWithConversion((PRUnichar*)JSValIDToString(aJSContext, aName));
|
||||
}
|
||||
|
||||
secLevel = GetSecurityLevel(aJSContext, subjectPrincipal, aClassInfo, className,
|
||||
propertyName, aAction, capability, aPolicy);
|
||||
// if (aPropertyStr), we were called from CheckPropertyAccess or checkConnect,
|
||||
// so we can assume this is a DOM class. Otherwise, we ask the ClassInfo.
|
||||
secLevel = GetSecurityLevel(aJSContext, subjectPrincipal,
|
||||
(aProperty || IsDOMClass(aClassInfo)),
|
||||
className, propertyName, aAction, capability, aPolicy);
|
||||
}
|
||||
|
||||
nsresult rv;
|
||||
|
@ -232,18 +246,27 @@ nsScriptSecurityManager::CheckPropertyAccessImpl(PRUint32 aAction,
|
|||
#ifdef DEBUG_mstoltz
|
||||
printf("Level: SameOrigin ");
|
||||
#endif
|
||||
nsCOMPtr<nsIPrincipal> objectPrincipal;
|
||||
if(aJSObject)
|
||||
{
|
||||
nsCOMPtr<nsIPrincipal> objectPrincipal;
|
||||
if (NS_FAILED(GetObjectPrincipal(aJSContext,
|
||||
NS_REINTERPRET_CAST(JSObject*, aJSObject),
|
||||
getter_AddRefs(objectPrincipal))))
|
||||
return NS_ERROR_FAILURE;
|
||||
rv = CheckSameOrigin(aJSContext, subjectPrincipal, objectPrincipal,
|
||||
aAction == nsIXPCSecurityManager::ACCESS_SET_PROPERTY);
|
||||
}
|
||||
else if(aTargetURI)
|
||||
{
|
||||
if (NS_FAILED(GetCodebasePrincipal(aTargetURI, getter_AddRefs(objectPrincipal))))
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
else
|
||||
{
|
||||
rv = NS_ERROR_DOM_SECURITY_ERR;
|
||||
break;
|
||||
}
|
||||
rv = CheckSameOrigin(aJSContext, subjectPrincipal, objectPrincipal,
|
||||
aAction == nsIXPCSecurityManager::ACCESS_SET_PROPERTY);
|
||||
|
||||
break;
|
||||
}
|
||||
case SCRIPT_SECURITY_CAPABILITY_ONLY:
|
||||
|
@ -383,7 +406,7 @@ nsScriptSecurityManager::IsDOMClass(nsIClassInfo* aClassInfo)
|
|||
PRInt32
|
||||
nsScriptSecurityManager::GetSecurityLevel(JSContext* aJSContext,
|
||||
nsIPrincipal *principal,
|
||||
nsIClassInfo* aClassInfo,
|
||||
PRBool aIsDOM,
|
||||
const char* aClassName,
|
||||
const char* aPropertyName,
|
||||
PRUint32 aAction,
|
||||
|
@ -447,7 +470,7 @@ nsScriptSecurityManager::GetSecurityLevel(JSContext* aJSContext,
|
|||
}
|
||||
//-- No policy for this property.
|
||||
// Use the default policy: sameOrigin for DOM, noAccess for everything else
|
||||
if(IsDOMClass(aClassInfo))
|
||||
if(aIsDOM)
|
||||
secLevel = SCRIPT_SECURITY_SAME_ORIGIN_ACCESS;
|
||||
if (!classPolicy && aPolicy)
|
||||
//-- If there's no stored policy for this property,
|
||||
|
@ -1688,8 +1711,9 @@ nsScriptSecurityManager::CanAccess(PRUint32 aAction,
|
|||
jsval aName,
|
||||
void** aPolicy)
|
||||
{
|
||||
return CheckPropertyAccessImpl(aAction, aCallContext, aJSContext, aJSObject,
|
||||
aObj, aClassInfo, aName, nsnull, nsnull, aPolicy);
|
||||
return CheckPropertyAccessImpl(aAction, aCallContext, aJSContext,
|
||||
aJSObject, aObj, nsnull, aClassInfo,
|
||||
aName, nsnull, nsnull, aPolicy);
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -1951,12 +1975,10 @@ nsScriptSecurityManager::InitPolicies(PRUint32 aPrefCount, const char** aPrefNam
|
|||
else if (count > 3)
|
||||
{ // capability.policy.<policyname>.<class>.<property>[.(get|set)]
|
||||
// Store the class name so we know this class has a policy set on it
|
||||
const char* className = dots[2] + 1;
|
||||
PRInt32 classNameLen = dots[3] - className;
|
||||
char* classNameNullTerm = PL_strndup(className, classNameLen);
|
||||
if (!classNameNullTerm)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
nsCStringKey classNameKey(classNameNullTerm);
|
||||
// Shoving a null into the pref anme string is unorthodox
|
||||
// but it saves a malloc & copy - hash keys require null-terminated strings
|
||||
*(char*)dots[3] = '\0';
|
||||
nsCStringKey classNameKey(dots[2] + 1);
|
||||
if (!(mClassPolicies))
|
||||
mClassPolicies = new nsHashtable(31);
|
||||
// We don't actually have to store the class name as data in the hashtable,
|
||||
|
@ -1966,7 +1988,6 @@ nsScriptSecurityManager::InitPolicies(PRUint32 aPrefCount, const char** aPrefNam
|
|||
mClassPolicies->Put(&classNameKey, (void*)CLASS_POLICY_DEFAULT);
|
||||
else if (!isDefault && classPolicy != (void*)CLASS_POLICY_SITE)
|
||||
mClassPolicies->Put(&classNameKey, (void*)CLASS_POLICY_SITE);
|
||||
PR_Free(classNameNullTerm);
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
|
|
|
@ -981,11 +981,9 @@ nsEventListenerManager::RegisterScriptEventListener(nsIScriptContext *aContext,
|
|||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
nsCOMPtr<nsIClassInfo> classInfo = do_QueryInterface(aObject);
|
||||
|
||||
if (NS_FAILED(rv = securityManager->CheckPropertyAccess(
|
||||
nsIXPCSecurityManager::ACCESS_SET_PROPERTY, cx, jsobj, aObject, classInfo,
|
||||
"EventTarget","addEventListener"))) {
|
||||
if (NS_FAILED(rv = securityManager->CheckPropertyAccess(cx, jsobj,
|
||||
"EventTarget","addEventListener",
|
||||
nsIXPCSecurityManager::ACCESS_SET_PROPERTY))) {
|
||||
// XXX set pending exception on the native call context?
|
||||
return rv;
|
||||
}
|
||||
|
|
|
@ -1108,9 +1108,9 @@ nsWindowSH::doCheckWriteAccess(JSContext *cx, JSObject *obj, jsval id,
|
|||
PRBool isLocation = JSVAL_IS_STRING(id) &&
|
||||
JSVAL_TO_STRING(id) == sLocation_id;
|
||||
|
||||
rv = sSecMan->CheckPropertyAccess(nsIXPCSecurityManager::ACCESS_SET_PROPERTY,
|
||||
cx, obj, native, this, "Window",
|
||||
isLocation ? "location" : "scriptglobals");
|
||||
rv = sSecMan->CheckPropertyAccess(cx, obj, "Window",
|
||||
isLocation ? "location" : "scriptglobals",
|
||||
nsIXPCSecurityManager::ACCESS_SET_PROPERTY);
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
return rv;
|
||||
|
@ -1146,9 +1146,9 @@ nsWindowSH::doCheckReadAccess(JSContext *cx, JSObject *obj, jsval id,
|
|||
PRBool isLocation = JSVAL_IS_STRING(id) &&
|
||||
JSVAL_TO_STRING(id) == sLocation_id;
|
||||
|
||||
rv = sSecMan->CheckPropertyAccess(nsIXPCSecurityManager::ACCESS_GET_PROPERTY,
|
||||
cx, obj, native, this, "Window",
|
||||
isLocation ? "location" : "scriptglobals");
|
||||
rv = sSecMan->CheckPropertyAccess(cx, obj, "Window",
|
||||
isLocation ? "location" : "scriptglobals",
|
||||
nsIXPCSecurityManager::ACCESS_GET_PROPERTY);
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
return rv;
|
||||
|
|
|
@ -4123,8 +4123,8 @@ NavigatorImpl::Preference()
|
|||
action = nsIXPCSecurityManager::ACCESS_GET_PROPERTY;
|
||||
else
|
||||
action = nsIXPCSecurityManager::ACCESS_SET_PROPERTY;
|
||||
rv = secMan->CheckPropertyAccess(action, cx, nsnull, nsnull, nsnull,
|
||||
"Navigator", "preferenceinternal");
|
||||
rv = secMan->CheckPropertyAccess(cx, nsnull,
|
||||
"Navigator", "preferenceinternal", action);
|
||||
if (NS_FAILED(rv))
|
||||
{
|
||||
//-- XXX doing the right thing here? Does the exception propagate?
|
||||
|
|
|
@ -630,17 +630,22 @@ nsWindowWatcher::OpenWindowJS(nsIDOMWindow *aParent,
|
|||
|
||||
nsCOMPtr<nsIDocShell> newDocShell(do_QueryInterface(newDocShellItem));
|
||||
if (uriToLoad) { // Get script principal and pass to docshell
|
||||
nsCOMPtr<nsIPrincipal> principal;
|
||||
if (NS_FAILED(secMan->GetSubjectPrincipal(getter_AddRefs(principal))))
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsIDocShellLoadInfo> loadInfo;
|
||||
newDocShell->CreateLoadInfo(getter_AddRefs(loadInfo));
|
||||
NS_ENSURE_TRUE(loadInfo, NS_ERROR_FAILURE);
|
||||
|
||||
if (principal) {
|
||||
nsCOMPtr<nsISupports> owner(do_QueryInterface(principal));
|
||||
loadInfo->SetOwner(owner);
|
||||
PRBool isChrome = PR_FALSE;
|
||||
rv = uriToLoad->SchemeIs("chrome", &isChrome);
|
||||
if (NS_FAILED(rv) || !isChrome) {
|
||||
nsCOMPtr<nsIPrincipal> principal;
|
||||
if (NS_FAILED(secMan->GetSubjectPrincipal(getter_AddRefs(principal))))
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
newDocShell->CreateLoadInfo(getter_AddRefs(loadInfo));
|
||||
NS_ENSURE_TRUE(loadInfo, NS_ERROR_FAILURE);
|
||||
|
||||
if (principal) {
|
||||
nsCOMPtr<nsISupports> owner(do_QueryInterface(principal));
|
||||
loadInfo->SetOwner(owner);
|
||||
}
|
||||
}
|
||||
|
||||
// Get the calling context off the JS context stack
|
||||
|
|
|
@ -922,10 +922,26 @@ nsXMLHttpRequest::Open(const char *method, const char *url)
|
|||
NS_WITH_SERVICE(nsIScriptSecurityManager, secMan,
|
||||
NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv);
|
||||
if (NS_FAILED(rv)) return NS_ERROR_FAILURE;
|
||||
/*
|
||||
rv = secMan->CheckScriptAccessToURL(cx, url, NS_DOM_PROP_XMLHTTPREQUEST_OPEN, PR_FALSE);
|
||||
if (NS_FAILED(rv)) return NS_ERROR_FAILURE;
|
||||
*/
|
||||
|
||||
nsCOMPtr<nsIURI> targetURI;
|
||||
rv = NS_NewURI(getter_AddRefs(targetURI), url, nsnull);
|
||||
if (NS_FAILED(rv)) return NS_ERROR_FAILURE;
|
||||
|
||||
rv = secMan->CheckConnect(cx, targetURI, "XMLHttpRequest","open");
|
||||
if (NS_FAILED(rv))
|
||||
{
|
||||
// Security check failed. The above call set a JS exception. The
|
||||
// following lines ensure that the exception is propagated.
|
||||
|
||||
NS_WITH_SERVICE(nsIXPConnect, xpc, nsIXPConnect::GetCID(), &rv);
|
||||
nsCOMPtr<nsIXPCNativeCallContext> cc;
|
||||
if(NS_SUCCEEDED(rv))
|
||||
xpc->GetCurrentNativeCallContext(getter_AddRefs(cc));
|
||||
if (cc)
|
||||
cc->SetExceptionWasThrown(PR_TRUE);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIPrincipal> principal;
|
||||
rv = secMan->GetSubjectPrincipal(getter_AddRefs(principal));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
|
|
Загрузка…
Ссылка в новой задаче