bug 47905, adding security check to XMLHttpRequest.open(). r=heikki, sr=brendan

This commit is contained in:
mstoltz%netscape.com 2001-03-02 00:09:20 +00:00
Родитель c1879e8f7a
Коммит 6672d1a27a
8 изменённых файлов: 113 добавлений и 51 удалений

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

@ -40,23 +40,23 @@ interface nsIScriptSecurityManager : nsISupports
* executing script. Will return null if there is no script
* currently executing.
*/
nsIPrincipal GetSubjectPrincipal();
nsIPrincipal getSubjectPrincipal();
/**
* Return the all-powerful system principal.
*/
nsIPrincipal GetSystemPrincipal();
nsIPrincipal getSystemPrincipal();
/**
* Return a principal that can be QI'd to nsICodebasePrincipal and
* has the same origin as aURI.
*/
nsIPrincipal GetCodebasePrincipal(in nsIURI aURI);
nsIPrincipal getCodebasePrincipal(in nsIURI aURI);
/**
* Return a principal that can be QI'd to nsICertificatePrincipal.
*/
nsIPrincipal GetCertificatePrincipal(in string CertID);
nsIPrincipal getCertificatePrincipal(in string CertID);
///////////////// Security Checks //////////////////
@ -69,7 +69,7 @@ interface nsIScriptSecurityManager : nsISupports
* @param prop The ordinal of the property being accessed (see nsDOMPropEnums.h)
* @param isWrite True if write access is being attempted
*/
[noscript] void CheckScriptAccess(in JSContextPtr cx, in voidPtr obj,
[noscript] void checkScriptAccess(in JSContextPtr cx, in voidPtr obj,
in long prop, in boolean isWrite);
/**
@ -81,7 +81,7 @@ interface nsIScriptSecurityManager : nsISupports
* @param cx the JSContext of the script causing the load
* @param uri the URI that is being loaded
*/
[noscript] void CheckLoadURIFromScript(in JSContextPtr cx, in nsIURI uri);
[noscript] void checkLoadURIFromScript(in JSContextPtr cx, in nsIURI uri);
/**
* Default CheckLoadURI permissions
@ -109,7 +109,7 @@ interface nsIScriptSecurityManager : nsISupports
* @param disallowFromMail if true, return NS_ERROR_DOM_BAD_URI if 'from'
* is a URI associated with mail or news
*/
void CheckLoadURI(in nsIURI from, in nsIURI uri,
void checkLoadURI(in nsIURI from, in nsIURI uri,
in unsigned long flags);
/**
@ -122,14 +122,14 @@ interface nsIScriptSecurityManager : nsISupports
* @param funObj The function trying to run..
* @param targetObj The object the function will run on.
*/
[noscript] void CheckFunctionAccess(in JSContextPtr cx, in voidPtr funObj,
[noscript] void checkFunctionAccess(in JSContextPtr cx, in voidPtr funObj,
in voidPtr targetObj);
/**
* Return true if content from the given principal is allowed to
* execute scripts.
*/
boolean CanExecuteScripts(in nsIPrincipal principal);
boolean canExecuteScripts(in nsIPrincipal principal);
///////////////// Capabilities /////////////////////
@ -139,7 +139,7 @@ interface nsIScriptSecurityManager : nsISupports
* with 'principal'. Will prompt user if necessary. Returns
* nsIPrincipal::ENABLE_GRANTED or nsIPrincipal::ENABLE_DENIED based on user's choice.
*/
void RequestCapability(in nsIPrincipal principal, in string capability, out short result);
void requestCapability(in nsIPrincipal principal, in string capability, out short result);
/**
* Return true if the currently executing script has 'capability' enabled.
@ -150,20 +150,20 @@ interface nsIScriptSecurityManager : nsISupports
* Enable 'capability' in the innermost frame of the currently executing
* script.
*/
void EnableCapability(in string capability);
void enableCapability(in string capability);
/**
* Remove 'capability' from the innermost frame of the currently executing
* script. Any setting of 'capability' from enclosing frames thus comes into
* effect.
*/
void RevertCapability(in string capability);
void revertCapability(in string capability);
/**
* Disable 'capability' in the innermost frame of the currently executing
* script.
*/
void DisableCapability(in string capability);
void disableCapability(in string capability);
//////////////// Master Certificate Functions ////////////////////
@ -171,8 +171,22 @@ interface nsIScriptSecurityManager : nsISupports
* Allow 'certificateID' to enable 'capability.' Can only be performed
* by code signed by the system certificate.
*/
void SetCanEnableCapability(in string certificateID, in string capability,
void setCanEnableCapability(in string certificateID, in string capability,
in short canEnable);
//////////////// Temporary ///////////////////////////////////////
/**
* Checks whether the currently executing script can load the given URL
* (special case for XMLHttpRequest)
*
* @param cx The current active JavaScript context
* @param url The url that is being accessed
* @param prop The ordinal of the property being accessed (see nsDOMPropEnums.h)
* @param isWrite True if write access is being attempted
*/
[noscript] void checkScriptAccessToURL(in JSContextPtr cx, in string url,
in long prop, in boolean isWrite);
};
%{C++

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

@ -97,6 +97,11 @@ public:
JSContext * GetCurrentContextQuick();
private:
NS_IMETHOD
CheckScriptAccessInternal(JSContext *cx,
void* obj, const char* aObjUrlStr, PRInt32 domPropInt,
PRBool isWrite);
NS_IMETHOD
CreateCodebasePrincipal(nsIURI* aURI, nsIPrincipal** result);
@ -107,7 +112,7 @@ private:
GetObjectPrincipal(JSContext *aCx, JSObject *aObj, nsIPrincipal **result);
NS_IMETHOD
CheckPermissions(JSContext *aCx, JSObject *aObj, const char *aCapability);
CheckPermissions(JSContext *aCx, nsIPrincipal* aObjectPrincipal, const char *aCapability);
PRInt32
GetSecurityLevel(nsIPrincipal *principal, nsDOMProp domProp,

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

@ -61,6 +61,7 @@
#include "nsIXPConnect.h"
#include "nsIScriptGlobalObject.h"
#include "nsIDOMWindowInternal.h"
#include "nscore.h"
static NS_DEFINE_CID(kNetSupportDialogCID, NS_NETSUPPORTDIALOG_CID);
static NS_DEFINE_IID(kIIOServiceIID, NS_IIOSERVICE_IID);
@ -402,42 +403,78 @@ static char *domPropNames[] = {
NS_DOM_PROP_NAMES
};
NS_IMETHODIMP
nsScriptSecurityManager::CheckScriptAccessToURL(JSContext *cx,
const char* aObjUrlStr, PRInt32 domPropInt,
PRBool isWrite)
{
return CheckScriptAccessInternal(cx, nsnull, aObjUrlStr, domPropInt, isWrite);
}
NS_IMETHODIMP
nsScriptSecurityManager::CheckScriptAccess(JSContext *cx,
void *aObj, PRInt32 domPropInt,
PRBool isWrite)
{
return CheckScriptAccessInternal(cx, aObj, nsnull, domPropInt, isWrite);
}
NS_IMETHODIMP
nsScriptSecurityManager::CheckScriptAccessInternal(JSContext *cx,
void* aObj, const char* aObjUrlStr,
PRInt32 domPropInt, PRBool isWrite)
{
nsCOMPtr<nsIPrincipal> principal;
if (NS_FAILED(GetSubjectPrincipal(cx, getter_AddRefs(principal)))) {
if (NS_FAILED(GetSubjectPrincipal(cx, getter_AddRefs(principal))))
return NS_ERROR_FAILURE;
}
PRBool equals;
if (!principal ||
NS_SUCCEEDED(principal->Equals(mSystemPrincipal, &equals)) && equals)
{
// We have native code or the system principal: just allow access
return NS_OK;
}
nsCAutoString capability;
nsDOMProp domProp = (nsDOMProp) domPropInt;
PRInt32 secLevel = GetSecurityLevel(principal, domProp, isWrite,
capability);
switch (secLevel) {
static const char UBR[] = "UniversalBrowserRead";
static const char UBW[] = "UniversalBrowserWrite";
switch (secLevel)
{
case SCRIPT_SECURITY_ALL_ACCESS:
return NS_OK;
case SCRIPT_SECURITY_UNDEFINED_ACCESS:
case SCRIPT_SECURITY_SAME_DOMAIN_ACCESS: {
const char *cap = isWrite
? "UniversalBrowserWrite"
: "UniversalBrowserRead";
return CheckPermissions(cx, (JSObject *) aObj, cap);
case SCRIPT_SECURITY_SAME_DOMAIN_ACCESS:
{
const char *cap = isWrite ? UBW : UBR;
nsCOMPtr<nsIPrincipal> objectPrincipal;
if (aObj)
{
if (NS_FAILED(GetObjectPrincipal(cx, NS_STATIC_CAST(JSObject*, aObj),
getter_AddRefs(objectPrincipal))))
return NS_ERROR_FAILURE;
}
else
{
nsCOMPtr<nsIURI> objectURI;
nsresult rv = NS_NewURI(getter_AddRefs(objectURI), aObjUrlStr, nsnull);
if (NS_FAILED(rv)) return rv;
rv = GetCodebasePrincipal(objectURI, getter_AddRefs(objectPrincipal));
if (NS_FAILED(rv)) return rv;
}
return CheckPermissions(cx, objectPrincipal, cap);
}
case SCRIPT_SECURITY_CAPABILITY_ONLY: {
PRBool capabilityEnabled = PR_FALSE;
nsresult rv = IsCapabilityEnabled(capability, &capabilityEnabled);
if (NS_FAILED(rv) || !capabilityEnabled)
return NS_ERROR_DOM_SECURITY_ERR;
return NS_OK;
case SCRIPT_SECURITY_CAPABILITY_ONLY:
{
PRBool capabilityEnabled = PR_FALSE;
nsresult rv = IsCapabilityEnabled(capability, &capabilityEnabled);
if (NS_FAILED(rv) || !capabilityEnabled)
return NS_ERROR_DOM_SECURITY_ERR;
return NS_OK;
}
default:
// Default is no access
@ -1304,7 +1341,8 @@ nsScriptSecurityManager::SetCanEnableCapability(const char* certificateID,
rv = systemCertZip->Open();
if (NS_SUCCEEDED(rv))
{
nsCOMPtr<nsIJAR> systemCertJar = do_QueryInterface(systemCertZip);
nsCOMPtr<nsIJAR> systemCertJar = do_QueryInterface(systemCertZip, &rv);
if (NS_FAILED(rv)) return NS_ERROR_FAILURE;
rv = systemCertJar->GetCertificatePrincipal(nsnull,
getter_AddRefs(mSystemCertificate));
if (NS_FAILED(rv)) return NS_ERROR_FAILURE;
@ -1627,7 +1665,7 @@ nsScriptSecurityManager::GetObjectPrincipal(JSContext *aCx, JSObject *aObj,
}
NS_IMETHODIMP
nsScriptSecurityManager::CheckPermissions(JSContext *aCx, JSObject *aObj,
nsScriptSecurityManager::CheckPermissions(JSContext *aCx, nsIPrincipal* aObjectPrincipal,
const char *aCapability)
{
/*
@ -1637,29 +1675,25 @@ nsScriptSecurityManager::CheckPermissions(JSContext *aCx, JSObject *aObj,
if (NS_FAILED(GetSubjectPrincipal(aCx, getter_AddRefs(subject))))
return NS_ERROR_FAILURE;
nsCOMPtr<nsIPrincipal> object;
if (NS_FAILED(GetObjectPrincipal(aCx, aObj, getter_AddRefs(object))))
return NS_ERROR_FAILURE;
if (subject == object) {
if (subject.get() == aObjectPrincipal)
return NS_OK;
}
PRBool isSameOrigin = PR_FALSE;
if (NS_FAILED(subject->Equals(object, &isSameOrigin)))
if (NS_FAILED(subject->Equals(aObjectPrincipal, &isSameOrigin)))
return NS_ERROR_FAILURE;
if (isSameOrigin)
return NS_OK;
// Allow access to about:blank
nsCOMPtr<nsICodebasePrincipal> objectCodebase = do_QueryInterface(object);
if (objectCodebase) {
nsCOMPtr<nsICodebasePrincipal> objectCodebase = do_QueryInterface(aObjectPrincipal);
if (objectCodebase)
{
nsXPIDLCString origin;
if (NS_FAILED(objectCodebase->GetOrigin(getter_Copies(origin))))
return NS_ERROR_FAILURE;
if (nsCRT::strcasecmp(origin, "about:blank") == 0) {
if (nsCRT::strcasecmp(origin, "about:blank") == 0)
return NS_OK;
}
}
/*

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

@ -1029,7 +1029,8 @@ enum nsDOMProp {
NS_DOM_PROP_WINDOWINTERNAL_TOOLBAR,
NS_DOM_PROP_WINDOWINTERNAL_UNESCAPE,
NS_DOM_PROP_WINDOWINTERNAL_UPDATECOMMANDS,
NS_DOM_PROP_WINDOWINTERNAL_WINDOW,
NS_DOM_PROP_WINDOWINTERNAL_WINDOW,
NS_DOM_PROP_XMLHTTPREQUEST_OPEN,
NS_DOM_PROP_XULCOMMANDDISPATCHER_ACTIVE,
NS_DOM_PROP_XULCOMMANDDISPATCHER_ADDCOMMANDUPDATER,
NS_DOM_PROP_XULCOMMANDDISPATCHER_FOCUSEDELEMENT,

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

@ -1028,6 +1028,7 @@
"windowinternal.unescape", \
"windowinternal.updatecommands", \
"windowinternal.window", \
"xmlhttprequest.open", \
"xulcommanddispatcher.active", \
"xulcommanddispatcher.addcommandupdater", \
"xulcommanddispatcher.focusedelement", \

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

@ -46,6 +46,7 @@
#include "nsICodebasePrincipal.h"
#include "nsWeakPtr.h"
#include "nsICharsetAlias.h"
#include "nsDOMPropEnums.h"
#ifdef IMPLEMENT_SYNC_LOAD
#include "nsIScriptContext.h"
#include "nsIScriptGlobalObject.h"
@ -854,6 +855,8 @@ nsXMLHttpRequest::OpenRequest(const char *method,
if (NS_FAILED(rv)) return rv;
// Only http URLs are allowed
// The following check takes the place of nsScriptSecurityManager::CheckLoadURI
// since loads of http URLs are always allowed.
PRBool isHTTP = PR_FALSE;
uri->SchemeIs(nsIURI::HTTP, &isHTTP);
if (!isHTTP)
@ -921,16 +924,18 @@ nsXMLHttpRequest::Open(const char *method, const char *url)
NS_WITH_SERVICE(nsIScriptSecurityManager, secMan,
NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv);
if (NS_SUCCEEDED(rv)) {
nsCOMPtr<nsIPrincipal> principal;
rv = secMan->GetSubjectPrincipal(getter_AddRefs(principal));
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<nsIPrincipal> principal;
rv = secMan->GetSubjectPrincipal(getter_AddRefs(principal));
if (NS_SUCCEEDED(rv)) {
nsCOMPtr<nsICodebasePrincipal> codebase(do_QueryInterface(principal));
if (codebase) {
codebase->GetURI(getter_AddRefs(mBaseURI));
nsCOMPtr<nsICodebasePrincipal> codebase = do_QueryInterface(principal);
if (codebase) {
codebase->GetURI(getter_AddRefs(mBaseURI));
}
}
}
if (argc > 2) {
JSBool asyncBool;

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

@ -29,6 +29,7 @@ function myfunc()
}
p.onload = myfunc;
netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");
p.open("POST", "http://blueviper/cgi-bin/echo_xml.cgi");
if (!sendPlainTextData) {

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

@ -9,6 +9,7 @@ x.documentElement.lastChild.appendChild(document.createTextNode("My Document Hea
x.documentElement.lastChild.setAttributeNS("http://www.w3.org/1999/xhtml","id","id1")
var p = new XMLHttpRequest();
netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");
p.open("POST", "http://blueviper/cgi-bin/echo_xml.cgi", false);
p.send(x);
var d = p.responseXML;