Allow about: modules to just set a flag to force script execution to be allowed
for particular about: URIs, instead of hardcoding checks in the security manager. Bug 341313, r=darin, sr=jst
This commit is contained in:
Родитель
c9b38b2394
Коммит
6c8d302694
|
@ -1619,19 +1619,28 @@ nsScriptSecurityManager::CanExecuteScripts(JSContext* cx,
|
|||
}
|
||||
|
||||
// OK, the docshell doesn't have script execution explicitly disabled.
|
||||
// Check whether our URI is "about:". If it is, we need to allow JS to
|
||||
// run... In this case, don't apply the JS enabled pref or policies.
|
||||
// Check whether our URI is an "about:" URI that allows scripts. If it is,
|
||||
// we need to allow JS to run. In this case, don't apply the JS enabled
|
||||
// pref or policies. On failures, just press on and don't do this special
|
||||
// case.
|
||||
nsCOMPtr<nsIURI> principalURI;
|
||||
aPrincipal->GetURI(getter_AddRefs(principalURI));
|
||||
if (principalURI)
|
||||
{
|
||||
nsCAutoString spec;
|
||||
principalURI->GetSpec(spec);
|
||||
if (spec.EqualsLiteral("about:") ||
|
||||
StringBeginsWith(spec, NS_LITERAL_CSTRING("about:neterror?")))
|
||||
{
|
||||
*result = PR_TRUE;
|
||||
return NS_OK;
|
||||
PRBool isAbout;
|
||||
rv = principalURI->SchemeIs("about", &isAbout);
|
||||
if (NS_SUCCEEDED(rv) && isAbout) {
|
||||
nsCOMPtr<nsIAboutModule> module;
|
||||
rv = NS_GetAboutModule(principalURI, getter_AddRefs(module));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
PRUint32 flags;
|
||||
rv = module->GetURIFlags(principalURI, &flags);
|
||||
if (NS_SUCCEEDED(rv) &&
|
||||
(flags & nsIAboutModule::ALLOW_SCRIPT)) {
|
||||
*result = PR_TRUE;
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
#include "nsIURI.h"
|
||||
#include "nsString.h"
|
||||
#include "nsReadableUtils.h"
|
||||
#include "nsIAboutModule.h"
|
||||
|
||||
inline nsresult
|
||||
NS_GetAboutModuleName(nsIURI *aAboutURI, nsCString& aModule)
|
||||
|
@ -62,3 +63,18 @@ NS_GetAboutModuleName(nsIURI *aAboutURI, nsCString& aModule)
|
|||
ToLowerCase(aModule);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
inline nsresult
|
||||
NS_GetAboutModule(nsIURI *aAboutURI, nsIAboutModule** aModule)
|
||||
{
|
||||
NS_PRECONDITION(aAboutURI, "Must have URI");
|
||||
|
||||
nsCAutoString contractID;
|
||||
nsresult rv = NS_GetAboutModuleName(aAboutURI, contractID);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
// look up a handler to deal with "what"
|
||||
contractID.Insert(NS_LITERAL_CSTRING(NS_ABOUT_MODULE_CONTRACTID_PREFIX), 0);
|
||||
|
||||
return CallGetService(contractID.get(), aModule);
|
||||
}
|
||||
|
|
|
@ -58,6 +58,12 @@ interface nsIAboutModule : nsISupports
|
|||
*/
|
||||
const unsigned long URI_SAFE_FOR_UNTRUSTED_CONTENT = (1 << 0);
|
||||
|
||||
/**
|
||||
* A flag that indicates whether script should be enabled for the
|
||||
* given about: URI even if it's disabled in general.
|
||||
*/
|
||||
const unsigned long ALLOW_SCRIPT = (1 << 1);
|
||||
|
||||
/**
|
||||
* A method to get the flags that apply to a given about: URI. The URI
|
||||
* passed in is guaranteed to be one of the URIs that this module
|
||||
|
|
|
@ -105,7 +105,7 @@ nsAboutProtocolHandler::NewURI(const nsACString &aSpec,
|
|||
PRBool isSafe = PR_FALSE;
|
||||
|
||||
nsCOMPtr<nsIAboutModule> aboutMod;
|
||||
rv = GetModuleForURI(url, getter_AddRefs(aboutMod));
|
||||
rv = NS_GetAboutModule(url, getter_AddRefs(aboutMod));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
// The standard return case
|
||||
PRUint32 flags;
|
||||
|
@ -147,7 +147,7 @@ nsAboutProtocolHandler::NewChannel(nsIURI* uri, nsIChannel* *result)
|
|||
|
||||
// about:what you ask?
|
||||
nsCOMPtr<nsIAboutModule> aboutMod;
|
||||
nsresult rv = GetModuleForURI(uri, getter_AddRefs(aboutMod));
|
||||
nsresult rv = NS_GetAboutModule(uri, getter_AddRefs(aboutMod));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
// The standard return case:
|
||||
return aboutMod->NewChannel(uri, result);
|
||||
|
@ -172,24 +172,6 @@ nsAboutProtocolHandler::AllowPort(PRInt32 port, const char *scheme, PRBool *_ret
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/* static */
|
||||
nsresult
|
||||
nsAboutProtocolHandler::GetModuleForURI(nsIURI* uri, nsIAboutModule** module)
|
||||
{
|
||||
NS_PRECONDITION(uri, "Must have URI");
|
||||
|
||||
nsresult rv;
|
||||
nsCAutoString contractID;
|
||||
rv = NS_GetAboutModuleName(uri, contractID);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
// look up a handler to deal with "what"
|
||||
contractID.Insert(NS_LITERAL_CSTRING(NS_ABOUT_MODULE_CONTRACTID_PREFIX), 0);
|
||||
|
||||
return CallGetService(contractID.get(), module);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Safe about protocol handler impl
|
||||
|
||||
|
|
|
@ -54,9 +54,6 @@ public:
|
|||
// nsAboutProtocolHandler methods:
|
||||
nsAboutProtocolHandler() {}
|
||||
virtual ~nsAboutProtocolHandler() {}
|
||||
|
||||
protected:
|
||||
static nsresult GetModuleForURI(nsIURI* uri, nsIAboutModule** module);
|
||||
};
|
||||
|
||||
class nsSafeAboutProtocolHandler : public nsIProtocolHandler
|
||||
|
|
|
@ -51,6 +51,9 @@ struct RedirEntry {
|
|||
const char* id;
|
||||
const char* url;
|
||||
PRBool dropChromePrivs; // if PR_TRUE, the page will not have chrome privileges
|
||||
PRBool allowScripts; // if PR_TRUE, the page will be able to run scripts
|
||||
// even if script is generally disabled and it
|
||||
// doesn't have chrome privileges. Use sparingly!
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -61,16 +64,17 @@ struct RedirEntry {
|
|||
before adding new map entries with dropChromePrivs == PR_FALSE.
|
||||
*/
|
||||
static RedirEntry kRedirMap[] = {
|
||||
{ "credits", "http://www.mozilla.org/credits/", PR_TRUE },
|
||||
{ "mozilla", "chrome://global/content/mozilla.xhtml", PR_TRUE },
|
||||
{ "plugins", "chrome://global/content/plugins.html", PR_FALSE },
|
||||
{ "config", "chrome://global/content/config.xul", PR_FALSE },
|
||||
{ "logo", "chrome://global/content/logo.gif", PR_TRUE },
|
||||
{ "buildconfig", "chrome://global/content/buildconfig.html", PR_TRUE },
|
||||
{ "license", "chrome://global/content/license.html", PR_TRUE },
|
||||
{ "licence", "chrome://global/content/license.html", PR_TRUE },
|
||||
{ "about", "chrome://global/content/aboutAbout.html", PR_FALSE },
|
||||
{ "neterror", "chrome://global/content/netError.xhtml", PR_TRUE }
|
||||
{ "credits", "http://www.mozilla.org/credits/", PR_TRUE, PR_FALSE },
|
||||
{ "mozilla", "chrome://global/content/mozilla.xhtml", PR_TRUE, PR_FALSE },
|
||||
{ "plugins", "chrome://global/content/plugins.html", PR_FALSE, PR_FALSE },
|
||||
{ "config", "chrome://global/content/config.xul", PR_FALSE, PR_FALSE },
|
||||
{ "logo", "chrome://global/content/logo.gif", PR_TRUE, PR_FALSE },
|
||||
{ "buildconfig", "chrome://global/content/buildconfig.html",
|
||||
PR_TRUE, PR_FALSE },
|
||||
{ "license", "chrome://global/content/license.html", PR_TRUE, PR_FALSE },
|
||||
{ "licence", "chrome://global/content/license.html", PR_TRUE, PR_FALSE },
|
||||
{ "about", "chrome://global/content/aboutAbout.html", PR_FALSE, PR_FALSE },
|
||||
{ "neterror", "chrome://global/content/netError.xhtml", PR_TRUE, PR_TRUE }
|
||||
};
|
||||
static const int kRedirTotal = NS_ARRAY_LENGTH(kRedirMap);
|
||||
|
||||
|
@ -145,6 +149,9 @@ nsAboutRedirector::GetURIFlags(nsIURI *aURI, PRUint32 *result)
|
|||
{
|
||||
*result = kRedirMap[i].dropChromePrivs ?
|
||||
nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT : 0;
|
||||
if (kRedirMap[i].allowScripts) {
|
||||
*result |= nsIAboutModule::ALLOW_SCRIPT;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -80,7 +80,7 @@ nsAbout::NewChannel(nsIURI *aURI, nsIChannel **result)
|
|||
NS_IMETHODIMP
|
||||
nsAbout::GetURIFlags(nsIURI *aURI, PRUint32 *result)
|
||||
{
|
||||
*result = 0;
|
||||
*result = nsIAboutModule::ALLOW_SCRIPT;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче