Bugs 55069, 70951 - JS-blocking APIs for mailnews and embedding. r=mscott, sr=attinasi.

Bug 54237 - fix for event-capture bug, r=heikki, sr=jband.
This commit is contained in:
mstoltz%netscape.com 2001-03-23 04:22:56 +00:00
Родитель b278d498a5
Коммит 519500116e
11 изменённых файлов: 155 добавлений и 46 удалений

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

@ -129,7 +129,7 @@ interface nsIScriptSecurityManager : nsISupports
* Return true if content from the given principal is allowed to
* execute scripts.
*/
boolean canExecuteScripts(in nsIPrincipal principal);
[noscript] boolean canExecuteScripts(in JSContextPtr cx, in nsIPrincipal principal);
///////////////// Capabilities /////////////////////

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

@ -36,9 +36,10 @@
#include "nsCOMPtr.h"
#include "nsIPref.h"
#include "nsISecurityPref.h"
#include "nsIJSContextStack.h"
class nsIDocShell;
/////////////////////
// nsIPrincipalKey //
/////////////////////
@ -97,6 +98,9 @@ public:
JSContext * GetCurrentContextQuick();
private:
nsresult
GetRootDocShell(JSContext *cx, nsIDocShell **result);
NS_IMETHOD
CheckScriptAccessInternal(JSContext *cx,
void* obj, const char* aObjUrlStr, PRInt32 domPropInt,

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

@ -62,6 +62,8 @@
#include "nsIScriptGlobalObject.h"
#include "nsIDOMWindowInternal.h"
#include "nscore.h"
#include "nsIDocShell.h"
#include "nsIDocShellTreeItem.h"
static NS_DEFINE_CID(kNetSupportDialogCID, NS_NETSUPPORTDIALOG_CID);
static NS_DEFINE_IID(kIIOServiceIID, NS_IIOSERVICE_IID);
@ -407,7 +409,7 @@ NS_IMETHODIMP
nsScriptSecurityManager::CheckScriptAccessToURL(JSContext *cx,
const char* aObjUrlStr, PRInt32 domPropInt,
PRBool isWrite)
{
{
return CheckScriptAccessInternal(cx, nsnull, aObjUrlStr, domPropInt, isWrite);
}
@ -415,7 +417,7 @@ NS_IMETHODIMP
nsScriptSecurityManager::CheckScriptAccess(JSContext *cx,
void *aObj, PRInt32 domPropInt,
PRBool isWrite)
{
{
return CheckScriptAccessInternal(cx, aObj, nsnull, domPropInt, isWrite);
}
@ -450,7 +452,9 @@ nsScriptSecurityManager::CheckScriptAccessInternal(JSContext *cx,
case SCRIPT_SECURITY_SAME_DOMAIN_ACCESS:
{
const char *cap = isWrite ? UBW : UBR;
#ifdef DEBUG_mstoltz
printf("##### Checking %s : \n", domPropNames[domProp]);
#endif
nsCOMPtr<nsIPrincipal> objectPrincipal;
if (aObj)
{
@ -550,7 +554,7 @@ NS_IMETHODIMP
nsScriptSecurityManager::CheckLoadURI(nsIURI *aSourceURI, nsIURI *aTargetURI,
PRUint32 aFlags)
{
nsCOMPtr<nsIJARURI> jarURI;
nsCOMPtr<nsIJARURI> jarURI;
nsCOMPtr<nsIURI> sourceUri(aSourceURI);
while((jarURI = do_QueryInterface(sourceUri)))
jarURI->GetJARFile(getter_AddRefs(sourceUri));
@ -647,20 +651,26 @@ NS_IMETHODIMP
nsScriptSecurityManager::CheckFunctionAccess(JSContext *aCx, void *aFunObj,
void *aTargetObj)
{
//-- This check is called for event handlers
nsCOMPtr<nsIPrincipal> subject;
nsresult rv = GetFunctionObjectPrincipal(aCx, (JSObject *)aFunObj,
getter_AddRefs(subject));
getter_AddRefs(subject));
if (NS_FAILED(rv))
return rv;
// First check if the principal the function was compiled under is
PRBool isSystem;
if (NS_SUCCEEDED(subject->Equals(mSystemPrincipal, &isSystem)) && isSystem)
// This is the system principal: just allow access
return NS_OK;
// Check if the principal the function was compiled under is
// allowed to execute scripts.
if (!subject) {
return NS_ERROR_DOM_SECURITY_ERR;
}
PRBool result;
rv = CanExecuteScripts(subject, &result);
rv = CanExecuteScripts(aCx, subject, &result);
if (NS_FAILED(rv)) {
return rv;
}
@ -862,46 +872,75 @@ nsScriptSecurityManager::EnsureNameSetRegistered()
return mNameSetRegistered;
}
nsresult
nsScriptSecurityManager::GetRootDocShell(JSContext *cx, nsIDocShell **result)
{
nsresult rv;
*result = nsnull;
nsCOMPtr<nsIDocShell> docshell;
nsCOMPtr<nsIScriptContext> scriptContext = (nsIScriptContext*)JS_GetContextPrivate(cx);
if (!scriptContext) return NS_ERROR_FAILURE;
nsCOMPtr<nsIScriptGlobalObject> globalObject = scriptContext->GetGlobalObject();
if (!globalObject) return NS_ERROR_FAILURE;
rv = globalObject->GetDocShell(getter_AddRefs(docshell));
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIDocShellTreeItem> docshellTreeItem = do_QueryInterface(docshell, &rv);
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIDocShellTreeItem> rootItem;
rv = docshellTreeItem->GetRootTreeItem(getter_AddRefs(rootItem));
if (NS_FAILED(rv)) return rv;
return rootItem->QueryInterface(NS_GET_IID(nsIDocShell), (void**)result);
}
NS_IMETHODIMP
nsScriptSecurityManager::CanExecuteScripts(nsIPrincipal *principal,
nsScriptSecurityManager::CanExecuteScripts(JSContext* cx, nsIPrincipal *principal,
PRBool *result)
{
// XXX Really OK to fail?
// I suppose that in some embedding there may be no ScriptNameSetRegistry.
EnsureNameSetRegistered();
if (principal == mSystemPrincipal) {
// Even if JavaScript is disabled, we must still execute system scripts
if (principal == mSystemPrincipal)
{
// Even if JavaScript is disabled, we must still execute system scripts
*result = PR_TRUE;
return NS_OK;
}
if (GetBit(hasDomainPolicyVector, NS_DOM_PROP_JAVASCRIPT_ENABLED)) {
//-- See if the current window allows JS execution
nsCOMPtr<nsIDocShell> docshell;
nsresult rv;
rv = GetRootDocShell(cx, getter_AddRefs(docshell));
if (NS_SUCCEEDED(rv))
{
rv = docshell->GetAllowJavascript(result);
if (NS_FAILED(rv)) return rv;
if (!*result)
return NS_OK;
}
if (GetBit(hasDomainPolicyVector, NS_DOM_PROP_JAVASCRIPT_ENABLED))
{
// We may have a per-domain security policy for JavaScript execution
nsCAutoString capability;
PRInt32 secLevel = GetSecurityLevel(principal,
NS_DOM_PROP_JAVASCRIPT_ENABLED,
PR_FALSE, capability);
if (secLevel != SCRIPT_SECURITY_UNDEFINED_ACCESS) {
if (secLevel != SCRIPT_SECURITY_UNDEFINED_ACCESS)
{
*result = (secLevel == SCRIPT_SECURITY_ALL_ACCESS);
return NS_OK;
}
}
if (mIsJavaScriptEnabled != mIsMailJavaScriptEnabled) {
if ((mIsJavaScriptEnabled != mIsMailJavaScriptEnabled) && docshell)
{
// Is this script running from mail?
nsCOMPtr<nsICodebasePrincipal> codebase = do_QueryInterface(principal);
if (!codebase)
return NS_ERROR_FAILURE;
nsCOMPtr<nsIURI> uri;
if (NS_FAILED(codebase->GetURI(getter_AddRefs(uri))))
return NS_ERROR_FAILURE;
nsXPIDLCString scheme;
if (NS_FAILED(uri->GetScheme(getter_Copies(scheme))))
return NS_ERROR_FAILURE;
if (nsCRT::strcasecmp(scheme, "imap") == 0 ||
nsCRT::strcasecmp(scheme, "mailbox") == 0 ||
nsCRT::strcasecmp(scheme, "news") == 0)
PRUint32 appType;
rv = docshell->GetAppType(&appType);
if (NS_FAILED(rv)) return rv;
if (appType == nsIDocShell::APP_TYPE_MAIL)
{
*result = mIsMailJavaScriptEnabled;
return NS_OK;
@ -1685,7 +1724,12 @@ nsScriptSecurityManager::CheckPermissions(JSContext *aCx, nsIPrincipal* aObjectP
return NS_ERROR_FAILURE;
if (isSameOrigin)
{
#ifdef DEBUG_mstoltz
printf(" OK.\n");
#endif
return NS_OK;
}
// Allow access to about:blank
nsCOMPtr<nsICodebasePrincipal> objectCodebase = do_QueryInterface(aObjectPrincipal);
@ -1712,6 +1756,9 @@ nsScriptSecurityManager::CheckPermissions(JSContext *aCx, nsIPrincipal* aObjectP
/*
** Access tests failed, so now report error.
*/
#ifdef DEBUG_mstoltz
printf(" FAILED.\n");
#endif
return NS_ERROR_DOM_PROP_ACCESS_DENIED;
}

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

@ -337,15 +337,23 @@ nsXMLDocument::Load(const nsAReadableString& aUrl)
if (NS_FAILED(secMan->CheckLoadURIFromScript(nsnull, uri)))
return NS_ERROR_FAILURE;
// Set a principal for this document
NS_IF_RELEASE(mPrincipal);
rv = secMan->GetCodebasePrincipal(uri, &mPrincipal);
if (!mPrincipal) return rv;
// Create a channel
rv = NS_OpenURI(getter_AddRefs(channel), uri, nsnull, nsnull, this);
if (NS_FAILED(rv)) return rv;
// Set a principal for this document
NS_IF_RELEASE(mPrincipal);
nsCOMPtr<nsISupports> channelOwner;
rv = channel->GetOwner(getter_AddRefs(channelOwner));
if (NS_SUCCEEDED(rv) && channelOwner)
rv = channelOwner->QueryInterface(NS_GET_IID(nsIPrincipal), (void**)&mPrincipal);
if (NS_FAILED(rv) || !channelOwner)
{
rv = secMan->GetCodebasePrincipal(uri, &mPrincipal);
if (!mPrincipal) return rv;
}
// Prepare for loading the XML document "into oneself"
nsCOMPtr<nsIStreamListener> listener;
if (NS_FAILED(rv = StartDocumentLoad(kLoadAsData, channel,

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

@ -127,6 +127,8 @@ nsDocShell::nsDocShell() :
mDefaultScrollbarPref(-1,-1),
mInitialPageLoad(PR_TRUE),
mAllowPlugins(PR_TRUE),
mAllowJavascript(PR_TRUE),
mAppType(nsIDocShell::APP_TYPE_UNKNOWN),
mViewMode(viewNormal),
mLastViewMode(viewNormal),
mRestoreViewMode(PR_FALSE),
@ -698,6 +700,32 @@ NS_IMETHODIMP nsDocShell::SetAllowPlugins(PRBool aAllowPlugins)
return NS_OK;
}
NS_IMETHODIMP nsDocShell::GetAllowJavascript(PRBool* aAllowJavascript)
{
NS_ENSURE_ARG_POINTER(aAllowJavascript);
*aAllowJavascript = mAllowJavascript;
return NS_OK;
}
NS_IMETHODIMP nsDocShell::SetAllowJavascript(PRBool aAllowJavascript)
{
mAllowJavascript = aAllowJavascript;
return NS_OK;
}
NS_IMETHODIMP nsDocShell::GetAppType(PRUint32* aAppType)
{
*aAppType = mAppType;
return NS_OK;
}
NS_IMETHODIMP nsDocShell::SetAppType(PRUint32 aAppType)
{
mAppType = aAppType;
return NS_OK;
}
NS_IMETHODIMP nsDocShell::GetViewMode(PRInt32* aViewMode)
{
NS_ENSURE_ARG_POINTER(aViewMode);

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

@ -288,6 +288,8 @@ protected:
PRUint32 mLoadType;
PRBool mInitialPageLoad;
PRBool mAllowPlugins;
PRBool mAllowJavascript;
PRUint32 mAppType;
PRInt32 mViewMode;
PRInt32 mLastViewMode;
PRBool mRestoreViewMode;

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

@ -1,3 +1,4 @@
/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Mozilla Public
@ -138,10 +139,23 @@ interface nsIDocShell : nsISupports
attribute nsIDocumentCharsetInfo documentCharsetInfo;
/*
Attribute stating if it should allow plugins or not.
Whether to allow plugin execution
*/
attribute boolean allowPlugins;
/*
Whether to allow Javascript execution
*/
attribute boolean allowJavascript;
/*
The type of application that created this window
*/
const unsigned long APP_TYPE_UNKNOWN = 0;
const unsigned long APP_TYPE_MAIL = 1;
attribute unsigned long appType;
/*
Definitions for the viewModes the docShell can be in.
*/
@ -180,5 +194,6 @@ interface nsIDocShell : nsISupports
const unsigned long BUSY_FLAGS_PAGE_LOADING = 4;
readonly attribute unsigned long busyFlags;
};

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

@ -446,7 +446,7 @@ nsJSContext::EvaluateStringWithValue(const nsAReadableString& aScript,
nsCOMPtr<nsIScriptSecurityManager> securityManager;
rv = GetSecurityManager(getter_AddRefs(securityManager));
if (NS_SUCCEEDED(rv))
rv = securityManager->CanExecuteScripts(principal, &ok);
rv = securityManager->CanExecuteScripts(mContext, principal, &ok);
if (NS_FAILED(rv)) {
JSPRINCIPALS_DROP(mContext, jsprin);
return NS_ERROR_FAILURE;
@ -562,7 +562,7 @@ nsJSContext::EvaluateString(const nsAReadableString& aScript,
nsCOMPtr<nsIScriptSecurityManager> securityManager;
rv = GetSecurityManager(getter_AddRefs(securityManager));
if (NS_SUCCEEDED(rv))
rv = securityManager->CanExecuteScripts(principal, &ok);
rv = securityManager->CanExecuteScripts(mContext, principal, &ok);
if (NS_FAILED(rv)) {
JSPRINCIPALS_DROP(mContext, jsprin);
return NS_ERROR_FAILURE;
@ -665,7 +665,7 @@ nsJSContext::CompileScript(const PRUnichar* aText,
nsCOMPtr<nsIScriptSecurityManager> securityManager;
rv = GetSecurityManager(getter_AddRefs(securityManager));
if (NS_SUCCEEDED(rv))
rv = securityManager->CanExecuteScripts(aPrincipal, &ok);
rv = securityManager->CanExecuteScripts(mContext, aPrincipal, &ok);
if (NS_FAILED(rv)) {
JSPRINCIPALS_DROP(mContext, jsprin);
return NS_ERROR_FAILURE;

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

@ -30,7 +30,8 @@
[scriptable, uuid(F15398A0-8018-11d3-AF70-00A024FFC08C)]
interface nsIWebBrowserSetup : nsISupports
{
const unsigned long SETUP_ALLOW_PLUGINS = 1;
const unsigned long SETUP_ALLOW_PLUGINS = 1;
const unsigned long SETUP_ALLOW_JAVASCRIPT = 2;
void setProperty(in unsigned long aId, in unsigned long aValue);
};

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

@ -597,6 +597,13 @@ NS_IMETHODIMP nsWebBrowser::SetProperty(PRUint32 aId, PRUint32 aValue)
mDocShell->SetAllowPlugins(aValue);
}
break;
case nsIWebBrowserSetup::SETUP_ALLOW_JAVASCRIPT:
{
NS_ENSURE_STATE(mDocShell);
NS_ENSURE_TRUE((aValue == PR_TRUE || aValue == PR_FALSE), NS_ERROR_INVALID_ARG);
mDocShell->SetAllowJavascript(aValue);
}
break;
default:
return NS_ERROR_INVALID_ARG;

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

@ -254,6 +254,9 @@ NS_IMETHODIMP nsMsgWindow::SetRootDocShell(nsIDocShell * aDocShell)
{
mRootDocShellWeak = getter_AddRefs(NS_GetWeakReference(aDocShell));
aDocShell->SetParentURIContentListener(this);
// be sure to set the application flag on the root docshell
// so it knows we are a mail application.
aDocShell->SetAppType(nsIDocShell::APP_TYPE_MAIL);
}
return NS_OK;
}
@ -309,13 +312,7 @@ NS_IMETHODIMP nsMsgWindow::SetDOMWindow(nsIDOMWindowInternal *aWindow)
docShellAsItem->GetSameTypeRootTreeItem(getter_AddRefs(rootAsItem));
nsCOMPtr<nsIDocShell> rootAsShell(do_QueryInterface(rootAsItem));
if(rootAsShell)
rootAsShell->SetParentURIContentListener(this);
nsAutoString childName; childName.AssignWithConversion("messagepane");
nsCOMPtr<nsIDocShellTreeNode> rootAsNode(do_QueryInterface(rootAsItem));
docShell = do_QueryInterface(rootAsItem);
mRootDocShellWeak = getter_AddRefs(NS_GetWeakReference(docShell));
SetRootDocShell(rootAsShell);
// force ourselves to figure out the message pane
nsCOMPtr<nsIDocShell> messageWindowDocShell;
@ -323,7 +320,7 @@ NS_IMETHODIMP nsMsgWindow::SetDOMWindow(nsIDOMWindowInternal *aWindow)
SetStatusFeedback(mStatusFeedback);
}
//Get nsIMsgWindowCommands object
//Get nsIMsgWindowCommands object
nsCOMPtr<nsISupports> xpConnectObj;
nsCOMPtr<nsPIDOMWindow> piDOMWindow(do_QueryInterface(aWindow));
if (piDOMWindow)