зеркало из https://github.com/mozilla/pjs.git
Bug 105050 - return null window.opener to scripts if opener is a mail window.
Bug 32571 - Prompt user before allowing scripts to close windows if opener is null. both r=heikki, sr=jst.
This commit is contained in:
Родитель
ce1b14f952
Коммит
7446e86422
|
@ -198,6 +198,12 @@ interface nsIScriptSecurityManager : nsIXPCSecurityManager
|
||||||
[noscript] nsIPrincipal getObjectPrincipal(in JSContextPtr cx,
|
[noscript] nsIPrincipal getObjectPrincipal(in JSContextPtr cx,
|
||||||
in JSObjectPtr obj);
|
in JSObjectPtr obj);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the principal of the currently running script is the
|
||||||
|
* system principal, false otherwise.
|
||||||
|
*/
|
||||||
|
boolean subjectPrincipalIsSystem();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Forget all currently stored security policies and reread from prefs.
|
* Forget all currently stored security policies and reread from prefs.
|
||||||
* This must be called after any capability.policy prefs have changed.
|
* This must be called after any capability.policy prefs have changed.
|
||||||
|
|
|
@ -1240,6 +1240,31 @@ nsScriptSecurityManager::GetSystemPrincipal(nsIPrincipal **result)
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsScriptSecurityManager::SubjectPrincipalIsSystem(PRBool* aIsSystem)
|
||||||
|
{
|
||||||
|
NS_ENSURE_ARG_POINTER(aIsSystem);
|
||||||
|
*aIsSystem = PR_FALSE;
|
||||||
|
|
||||||
|
if (!mSystemPrincipal)
|
||||||
|
return NS_OK;
|
||||||
|
|
||||||
|
nsCOMPtr<nsIPrincipal> subject;
|
||||||
|
nsresult rv = GetSubjectPrincipal(getter_AddRefs(subject));
|
||||||
|
if (NS_FAILED(rv))
|
||||||
|
return rv;
|
||||||
|
|
||||||
|
if(!subject)
|
||||||
|
{
|
||||||
|
// No subject principal means no JS is running;
|
||||||
|
// this is the equivalent of system principal code
|
||||||
|
*aIsSystem = PR_TRUE;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
return mSystemPrincipal->Equals(subject, aIsSystem);
|
||||||
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsScriptSecurityManager::GetCertificatePrincipal(const char* aCertID,
|
nsScriptSecurityManager::GetCertificatePrincipal(const char* aCertID,
|
||||||
nsIPrincipal **result)
|
nsIPrincipal **result)
|
||||||
|
@ -2677,7 +2702,6 @@ nsScriptSecurityManager::InitPrefs()
|
||||||
PRUint32 prefCount;
|
PRUint32 prefCount;
|
||||||
char** prefNames;
|
char** prefNames;
|
||||||
|
|
||||||
//-- Set a callback for policy changes
|
|
||||||
// Registering the security manager as an observer to the
|
// Registering the security manager as an observer to the
|
||||||
// profile-after-change topic. We will build up the policy table
|
// profile-after-change topic. We will build up the policy table
|
||||||
// after the initial profile loads and after profile switches.
|
// after the initial profile loads and after profile switches.
|
||||||
|
|
|
@ -1 +1,4 @@
|
||||||
JSURLLoadBlockedWarning=Attempt to load a javascript: URL from one host\nin a window displaying content from another host\nwas blocked by the security manager.
|
JSURLLoadBlockedWarning = Attempt to load a javascript: URL from one host\nin a window displaying content from another host\nwas blocked by the security manager.
|
||||||
|
ConfirmWindowCloseDialogTitle = Close Window?
|
||||||
|
ConfirmWindowCloseDialogText = A script wants to close the current window. Do you wish to allow this?
|
||||||
|
|
||||||
|
|
|
@ -60,6 +60,7 @@ REQUIRES = xpcom \
|
||||||
xmlextras \
|
xmlextras \
|
||||||
find \
|
find \
|
||||||
appshell \
|
appshell \
|
||||||
|
intl \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
CPPSRCS = \
|
CPPSRCS = \
|
||||||
|
|
|
@ -57,6 +57,7 @@ REQUIRES = xpcom \
|
||||||
htmlparser \
|
htmlparser \
|
||||||
chardet \
|
chardet \
|
||||||
transformiix \
|
transformiix \
|
||||||
|
intl \
|
||||||
xmlextras \
|
xmlextras \
|
||||||
find \
|
find \
|
||||||
appshell \
|
appshell \
|
||||||
|
|
|
@ -124,6 +124,7 @@
|
||||||
#include "nsISupportsPrimitives.h"
|
#include "nsISupportsPrimitives.h"
|
||||||
#include "nsDOMClassInfo.h"
|
#include "nsDOMClassInfo.h"
|
||||||
#include "nsIJSNativeInitializer.h"
|
#include "nsIJSNativeInitializer.h"
|
||||||
|
#include "nsIStringBundle.h"
|
||||||
|
|
||||||
#include "plbase64.h"
|
#include "plbase64.h"
|
||||||
|
|
||||||
|
@ -155,7 +156,7 @@ static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
|
||||||
static NS_DEFINE_CID(kWindowMediatorCID, NS_WINDOWMEDIATOR_CID); // For window.find()
|
static NS_DEFINE_CID(kWindowMediatorCID, NS_WINDOWMEDIATOR_CID); // For window.find()
|
||||||
static const char *sWindowWatcherContractID = "@mozilla.org/embedcomp/window-watcher;1";
|
static const char *sWindowWatcherContractID = "@mozilla.org/embedcomp/window-watcher;1";
|
||||||
static const char *sJSStackContractID = "@mozilla.org/js/xpc/ContextStack;1";
|
static const char *sJSStackContractID = "@mozilla.org/js/xpc/ContextStack;1";
|
||||||
|
static NS_DEFINE_CID(kStringBundleServiceCID, NS_STRINGBUNDLESERVICE_CID);
|
||||||
|
|
||||||
static const char * const kCryptoContractID = NS_CRYPTO_CONTRACTID;
|
static const char * const kCryptoContractID = NS_CRYPTO_CONTRACTID;
|
||||||
static const char * const kPkcs11ContractID = NS_PKCS11_CONTRACTID;
|
static const char * const kPkcs11ContractID = NS_PKCS11_CONTRACTID;
|
||||||
|
@ -1156,7 +1157,28 @@ GlobalWindowImpl::GetControllers(nsIControllers** aResult)
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
GlobalWindowImpl::GetOpener(nsIDOMWindowInternal** aOpener)
|
GlobalWindowImpl::GetOpener(nsIDOMWindowInternal** aOpener)
|
||||||
{
|
{
|
||||||
*aOpener = mOpener;
|
*aOpener = nsnull;
|
||||||
|
// We don't want to reveal the opener if the opener is a mail window,
|
||||||
|
// because opener can be used to spoof the contents of a message (bug 105050).
|
||||||
|
// So, we look in the opener's root docshell to see if it's a mail window.
|
||||||
|
nsCOMPtr<nsIScriptGlobalObject> openerSGO(do_QueryInterface(mOpener));
|
||||||
|
if (openerSGO) {
|
||||||
|
nsCOMPtr<nsIDocShell> openerDocShell;
|
||||||
|
openerSGO->GetDocShell(getter_AddRefs(openerDocShell));
|
||||||
|
nsCOMPtr<nsIDocShellTreeItem> docShellAsItem(do_QueryInterface(openerDocShell));
|
||||||
|
if (docShellAsItem) {
|
||||||
|
nsCOMPtr<nsIDocShellTreeItem> openerRootItem;
|
||||||
|
docShellAsItem->GetRootTreeItem(getter_AddRefs(openerRootItem));
|
||||||
|
nsCOMPtr<nsIDocShell> openerRootDocShell(do_QueryInterface(openerRootItem));
|
||||||
|
if (openerRootDocShell) {
|
||||||
|
PRUint32 appType;
|
||||||
|
nsresult rv = openerRootDocShell->GetAppType(&appType);
|
||||||
|
if (NS_SUCCEEDED(rv) && appType != nsIDocShell::APP_TYPE_MAIL) {
|
||||||
|
*aOpener = mOpener;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
NS_IF_ADDREF(*aOpener);
|
NS_IF_ADDREF(*aOpener);
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
@ -2438,6 +2460,46 @@ GlobalWindowImpl::GetFrames(nsIDOMWindow** aFrames)
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define DOM_PROPERTIES_URL "chrome://communicator/locale/dom/dom.properties"
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
GlobalWindowImpl::ConfirmClose(PRBool* aConfirmed)
|
||||||
|
{
|
||||||
|
nsresult rv;
|
||||||
|
// Get the localized strings for the dialog
|
||||||
|
nsCOMPtr<nsIStringBundleService> bundleService(
|
||||||
|
do_GetService(kStringBundleServiceCID, &rv));
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
//XXX: What to do on error?
|
||||||
|
nsCOMPtr<nsIStringBundle> bundle;
|
||||||
|
rv = bundleService->CreateBundle(NS_LITERAL_CSTRING(DOM_PROPERTIES_URL).get(),
|
||||||
|
getter_AddRefs(bundle));
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
nsXPIDLString confirmTitle;
|
||||||
|
rv = bundle->GetStringFromName(NS_LITERAL_STRING("ConfirmWindowCloseDialogTitle").get(),
|
||||||
|
getter_Copies(confirmTitle));
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
nsXPIDLString confirmText;
|
||||||
|
rv = bundle->GetStringFromName(NS_LITERAL_STRING("ConfirmWindowCloseDialogText").get(),
|
||||||
|
getter_Copies(confirmText));
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
// Show the dialog
|
||||||
|
nsCOMPtr<nsIPrompt> prompter;
|
||||||
|
rv = GetPrompter(getter_AddRefs(prompter));
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
return prompter->Confirm(confirmTitle,
|
||||||
|
confirmText, aConfirmed);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define DENY_SCRIPT_CLOSE 0
|
||||||
|
#define CONFIRM_SCRIPT_CLOSE 1
|
||||||
|
#define ALLOW_SCRIPT_CLOSE 2
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
GlobalWindowImpl::Close()
|
GlobalWindowImpl::Close()
|
||||||
{
|
{
|
||||||
|
@ -2447,15 +2509,44 @@ GlobalWindowImpl::Close()
|
||||||
if (parent != NS_STATIC_CAST(nsIDOMWindow *, this)) {
|
if (parent != NS_STATIC_CAST(nsIDOMWindow *, this)) {
|
||||||
// window.close() is called on a frame in a frameset, such calls
|
// window.close() is called on a frame in a frameset, such calls
|
||||||
// are ignored.
|
// are ignored.
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Note: the basic security check, rejecting windows not opened through JS,
|
// If this window was not opened by script (!mOpener), find out
|
||||||
// has been removed. This was approved long ago by ...you're going to call me
|
// whether it's OK for a script to close it.
|
||||||
// on this, aren't you... well it was. And anyway, a better means is coming.
|
if (!mOpener) {
|
||||||
// In the new world of application-level interfaces being written in JS, this
|
nsresult rv;
|
||||||
// security check was causing problems.
|
nsCOMPtr<nsIScriptSecurityManager> secMan =
|
||||||
|
do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
// System scripts can close all windows
|
||||||
|
PRBool InSystemCode = PR_FALSE;
|
||||||
|
rv = secMan->SubjectPrincipalIsSystem(&InSystemCode);
|
||||||
|
if (NS_FAILED(rv) || !InSystemCode) {
|
||||||
|
// Check the pref "dom.allow_scripts_to_close_windows"
|
||||||
|
nsCOMPtr<nsIPref> pref(do_GetService(kPrefServiceCID, &rv));
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
PRInt32 closePref;
|
||||||
|
rv = pref->GetIntPref("dom.allow_scripts_to_close_windows", &closePref);
|
||||||
|
if (NS_FAILED(rv))
|
||||||
|
closePref = CONFIRM_SCRIPT_CLOSE;
|
||||||
|
PRBool confirmOK = PR_FALSE;
|
||||||
|
if (closePref == CONFIRM_SCRIPT_CLOSE) {
|
||||||
|
// Ask the user whether it's OK to close the window
|
||||||
|
rv = ConfirmClose(&confirmOK);
|
||||||
|
if (NS_FAILED(rv))
|
||||||
|
return rv;
|
||||||
|
} else {
|
||||||
|
confirmOK = (closePref == ALLOW_SCRIPT_CLOSE);
|
||||||
|
}
|
||||||
|
if (!confirmOK) {
|
||||||
|
// User clicked Cancel, so abort the close
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
nsCOMPtr<nsIJSContextStack> stack =
|
nsCOMPtr<nsIJSContextStack> stack =
|
||||||
do_GetService("@mozilla.org/js/xpc/ContextStack;1");
|
do_GetService("@mozilla.org/js/xpc/ContextStack;1");
|
||||||
|
|
|
@ -214,6 +214,7 @@ protected:
|
||||||
const nsAReadableString& aOptions,
|
const nsAReadableString& aOptions,
|
||||||
PRBool aDialog, jsval *argv, PRUint32 argc,
|
PRBool aDialog, jsval *argv, PRUint32 argc,
|
||||||
nsISupports *aExtraArgument, nsIDOMWindow **aReturn);
|
nsISupports *aExtraArgument, nsIDOMWindow **aReturn);
|
||||||
|
nsresult ConfirmClose(PRBool* aConfirmed);
|
||||||
static void CloseWindow(nsISupports* aWindow);
|
static void CloseWindow(nsISupports* aWindow);
|
||||||
|
|
||||||
// Timeout Functions
|
// Timeout Functions
|
||||||
|
|
|
@ -334,6 +334,9 @@ pref("capability.principal.codebase.foo.granted", "UniversalFoo");
|
||||||
//////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////
|
||||||
|
|
||||||
pref("dom.disable_open_during_load", false);
|
pref("dom.disable_open_during_load", false);
|
||||||
|
// 0 = never allow scripts to close windows that weren't opened by script,
|
||||||
|
// 1 = prompt user, 2 = always allow. Default is prompt.
|
||||||
|
pref("dom.allow_scripts_to_close_windows", 1);
|
||||||
|
|
||||||
pref("javascript.enabled", true);
|
pref("javascript.enabled", true);
|
||||||
pref("javascript.allow.mailnews", false);
|
pref("javascript.allow.mailnews", false);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче