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:
mstoltz%netscape.com 2001-05-18 06:56:29 +00:00
Родитель 172a2ac866
Коммит 11f7b8f900
8 изменённых файлов: 104 добавлений и 57 удалений

Просмотреть файл

@ -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)) {