зеркало из https://github.com/mozilla/pjs.git
bug 47905, adding security check to XMLHttpRequest.open(). r=heikki, sr=brendan
This commit is contained in:
Родитель
c1879e8f7a
Коммит
6672d1a27a
|
@ -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;
|
||||
|
|
Загрузка…
Ссылка в новой задаче