More fixes for 55237, cleaned up CheckLoadURI and added a check on "Edit This Link." Also added error reporting (bug 40538).

r=beard, sr=hyatt
This commit is contained in:
mstoltz%netscape.com 2001-04-17 01:21:44 +00:00
Родитель 4e8d877e19
Коммит c302defdcd
5 изменённых файлов: 138 добавлений и 59 удалений

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

@ -112,16 +112,22 @@ interface nsIScriptSecurityManager : nsISupports
void checkLoadURI(in nsIURI from, in nsIURI uri,
in unsigned long flags);
/**
* Check that the function 'funObj' is allowed to run on 'targetObj'
*
* Will return error code NS_ERROR_DOM_SECURITY_ERR if the function
* should not run
*
* @param cx The current active JavaScript context.
* @param funObj The function trying to run..
* @param targetObj The object the function will run on.
*/
/**
* Same as CheckLoadURI but takes string arguments for ease of use by scripts
*/
void checkLoadURIStr(in string from, in string uri,
in unsigned long flags);
/**
* Check that the function 'funObj' is allowed to run on 'targetObj'
*
* Will return error code NS_ERROR_DOM_SECURITY_ERR if the function
* should not run
*
* @param cx The current active JavaScript context.
* @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,
in voidPtr targetObj);

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

@ -39,6 +39,7 @@
#include "nsIJSContextStack.h"
class nsIDocShell;
class nsString;
/////////////////////
// nsIPrincipalKey //
@ -91,12 +92,15 @@ public:
NS_DECL_ISUPPORTS
NS_DECL_NSISCRIPTSECURITYMANAGER
NS_DECL_NSIXPCSECURITYMANAGER
static nsScriptSecurityManager *
GetScriptSecurityManager();
JSContext * GetCurrentContextQuick();
private:
static nsresult
ReportErrorToConsole(nsIURI* aTarget);
nsresult
GetRootDocShell(JSContext *cx, nsIDocShell **result);

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

@ -65,6 +65,7 @@
#include "nsIDocShellTreeItem.h"
#include "nsIPrompt.h"
#include "nsIWindowWatcher.h"
#include "nsIConsoleService.h"
static NS_DEFINE_IID(kIIOServiceIID, NS_IIOSERVICE_IID);
static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID);
@ -554,6 +555,8 @@ NS_IMETHODIMP
nsScriptSecurityManager::CheckLoadURI(nsIURI *aSourceURI, nsIURI *aTargetURI,
PRUint32 aFlags)
{
//-- Get the source and target schemes
//-- jar URIs can be nested. This loop finds the innermost base URI.
nsCOMPtr<nsIJARURI> jarURI;
nsCOMPtr<nsIURI> sourceUri(aSourceURI);
while((jarURI = do_QueryInterface(sourceUri)))
@ -562,16 +565,7 @@ nsScriptSecurityManager::CheckLoadURI(nsIURI *aSourceURI, nsIURI *aTargetURI,
nsXPIDLCString sourceScheme;
if (NS_FAILED(sourceUri->GetScheme(getter_Copies(sourceScheme))))
return NS_ERROR_FAILURE;
// Some loads are not allowed from mail/news messages
if ((aFlags & nsIScriptSecurityManager::DISALLOW_FROM_MAIL) &&
(nsCRT::strcasecmp(sourceScheme, "mailbox") == 0 ||
nsCRT::strcasecmp(sourceScheme, "imap") == 0 ||
nsCRT::strcasecmp(sourceScheme, "news") == 0))
{
return NS_ERROR_DOM_BAD_URI;
}
return NS_ERROR_OUT_OF_MEMORY;
nsCOMPtr<nsIURI> targetUri(aTargetURI);
while((jarURI = do_QueryInterface(targetUri)))
@ -580,7 +574,16 @@ nsScriptSecurityManager::CheckLoadURI(nsIURI *aSourceURI, nsIURI *aTargetURI,
nsXPIDLCString targetScheme;
if (NS_FAILED(targetUri->GetScheme(getter_Copies(targetScheme))))
return NS_ERROR_FAILURE;
return NS_ERROR_OUT_OF_MEMORY;
// Some loads are not allowed from mail/news messages
if ((aFlags & nsIScriptSecurityManager::DISALLOW_FROM_MAIL) &&
(nsCRT::strcasecmp(sourceScheme, "mailbox") == 0 ||
nsCRT::strcasecmp(sourceScheme, "imap") == 0 ||
nsCRT::strcasecmp(sourceScheme, "news") == 0))
{
return ReportErrorToConsole(aTargetURI);
}
if (nsCRT::strcasecmp(targetScheme, sourceScheme) == 0)
{
@ -588,36 +591,37 @@ nsScriptSecurityManager::CheckLoadURI(nsIURI *aSourceURI, nsIURI *aTargetURI,
return NS_OK;
}
enum Action { AllowProtocol, DenyProtocol, PrefControlled, ChromeProtocol };
enum Action { AllowProtocol, DenyProtocol, PrefControlled, ChromeProtocol, AboutProtocol };
static const struct {
const char *name;
Action action;
} protocolList[] = {
//-- Keep the most commonly used protocols at the top of the list
// to increase performance
{ "http", AllowProtocol },
{ "http", AllowProtocol },
{ "file", PrefControlled },
{ "https", AllowProtocol },
{ "https", AllowProtocol },
{ "chrome", ChromeProtocol },
{ "mailbox", DenyProtocol },
{ "pop", AllowProtocol },
{ "imap", DenyProtocol },
{ "pop3", DenyProtocol },
{ "news", AllowProtocol },
{ "javascript", AllowProtocol },
{ "ftp", AllowProtocol },
{ "about", AllowProtocol },
{ "mailto", AllowProtocol },
{ "aim", AllowProtocol },
{ "data", AllowProtocol },
{ "keyword", DenyProtocol },
{ "resource", DenyProtocol },
{ "gopher", AllowProtocol },
{ "datetime", DenyProtocol },
{ "finger", AllowProtocol },
{ "res", DenyProtocol }
{ "mailbox", DenyProtocol },
{ "pop", AllowProtocol },
{ "imap", DenyProtocol },
{ "pop3", DenyProtocol },
{ "news", AllowProtocol },
{ "javascript", AllowProtocol },
{ "ftp", AllowProtocol },
{ "about", AboutProtocol },
{ "mailto", AllowProtocol },
{ "aim", AllowProtocol },
{ "data", AllowProtocol },
{ "keyword", DenyProtocol },
{ "resource", DenyProtocol },
{ "gopher", AllowProtocol },
{ "datetime", DenyProtocol },
{ "finger", AllowProtocol },
{ "res", DenyProtocol }
};
nsXPIDLCString targetSpec;
for (unsigned i=0; i < sizeof(protocolList)/sizeof(protocolList[0]); i++) {
if (nsCRT::strcasecmp(targetScheme, protocolList[i].name) == 0) {
PRBool doCheck = PR_FALSE;
@ -628,13 +632,21 @@ nsScriptSecurityManager::CheckLoadURI(nsIURI *aSourceURI, nsIURI *aTargetURI,
case PrefControlled:
// Allow access if pref is false
mPrefs->GetBoolPref("security.checkloaduri", &doCheck);
return doCheck ? NS_ERROR_DOM_BAD_URI : NS_OK;
return doCheck ? ReportErrorToConsole(aTargetURI) : NS_OK;
case ChromeProtocol:
return (aFlags & nsIScriptSecurityManager::ALLOW_CHROME) ?
NS_OK : NS_ERROR_DOM_BAD_URI;
NS_OK : ReportErrorToConsole(aTargetURI);
case AboutProtocol:
// Allow loading about:blank, otherwise deny
if(NS_FAILED(targetUri->GetSpec(getter_Copies(targetSpec))))
return NS_ERROR_FAILURE;
return (PL_strcmp(targetSpec, "about:blank") == 0) ||
(PL_strcmp(targetSpec, "about:") == 0) ||
(PL_strcmp(targetSpec, "about:mozilla") == 0) ?
NS_OK : ReportErrorToConsole(aTargetURI);
case DenyProtocol:
// Deny access
return NS_ERROR_DOM_BAD_URI;
return ReportErrorToConsole(aTargetURI);
}
}
}
@ -642,11 +654,60 @@ nsScriptSecurityManager::CheckLoadURI(nsIURI *aSourceURI, nsIURI *aTargetURI,
// If we reach here, we have an unknown protocol. Warn, but allow.
// This is risky from a security standpoint, but allows flexibility
// in installing new protocol handlers after initial ship.
NS_WARN_IF_FALSE(PR_FALSE, "unknown protocol");
NS_WARN_IF_FALSE(PR_FALSE, "unknown protocol in nsScriptSecurityManager::CheckLoadURI");
return NS_OK;
}
nsresult
nsScriptSecurityManager::ReportErrorToConsole(nsIURI* aTarget)
{
nsXPIDLCString spec;
nsresult rv = aTarget->GetSpec(getter_Copies(spec));
if (NS_FAILED(rv)) return rv;
nsAutoString msg;
msg.AssignWithConversion("The link to ");
msg.AppendWithConversion(spec);
msg.AppendWithConversion(" was blocked by the security manager.\nRemote content may not link to local content.");
// Report error in JS console
nsCOMPtr<nsIConsoleService> console(do_GetService("@mozilla.org/consoleservice;1"));
if (console)
{
PRUnichar* messageUni = msg.ToNewUnicode();
if (!messageUni)
return NS_ERROR_FAILURE;
console->LogStringMessage(messageUni);
nsMemory::Free(messageUni);
}
#ifndef DEBUG
else // If JS console reporting failed, print to stderr.
#endif
{
char* messageCstr = msg.ToNewCString();
if (!messageCstr)
return NS_ERROR_FAILURE;
fprintf(stderr, "%s\n", messageCstr);
PR_Free(messageCstr);
}
//-- Always returns an error
return NS_ERROR_DOM_BAD_URI;
}
NS_IMETHODIMP
nsScriptSecurityManager::CheckLoadURIStr(const char* aSourceURIStr, const char* aTargetURIStr,
PRUint32 aFlags)
{
nsCOMPtr<nsIURI> source;
nsresult rv = NS_NewURI(getter_AddRefs(source), aSourceURIStr, nsnull);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIURI> target;
rv = NS_NewURI(getter_AddRefs(target), aTargetURIStr, nsnull);
NS_ENSURE_SUCCESS(rv, rv);
return CheckLoadURI(source, target, aFlags);
}
NS_IMETHODIMP
nsScriptSecurityManager::CheckFunctionAccess(JSContext *aCx, void *aFunObj,
void *aTargetObj)

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

@ -39,24 +39,18 @@
function openNewWindowWith(url) {
// URL Loading Security Check
const nsIStandardURL = Components.interfaces.nsIStandardURL;
const nsIURI = Components.interfaces.nsIURI;
const stdURL = Components.classes["@mozilla.org/network/standard-url;1"];
var sourceURL = stdURL.createInstance(nsIStandardURL);
var focusedWindow = document.commandDispatcher.focusedWindow;
// URL Loading Security Check
var focusedWindow = document.commandDispatcher.focusedWindow;
var sourceWin = isDocumentFrame(focusedWindow) ? focusedWindow.location.href : window._content.location.href;
sourceURL.init(nsIStandardURL.URLTYPE_STANDARD, 80, sourceWin, null);
var targetURL = stdURL.createInstance(nsIStandardURL);
targetURL.init(nsIStandardURL.URLTYPE_STANDARD, 80, url, null);
const nsIScriptSecurityManager = Components.interfaces.nsIScriptSecurityManager;
var secMan = Components.classes["@mozilla.org/scriptsecuritymanager;1"].getService().
QueryInterface(nsIScriptSecurityManager);
secMan.checkLoadURI(sourceURL, targetURL, nsIScriptSecurityManager.STANDARD);
try {
secMan.checkLoadURIStr(sourceWin, url, nsIScriptSecurityManager.STANDARD);
} catch (e) {
throw "Load of " + url + " denied.";
}
var newWin;
var wintype = document.firstChild.getAttribute('windowtype');

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

@ -281,6 +281,20 @@ function editPage(url, launchWindow, delay)
}
}
// URL Loading Security Check
var focusedWindow = launchWindow.document.commandDispatcher.focusedWindow;
var sourceWin = isDocumentFrame(focusedWindow) ? focusedWindow.location.href : focusedWindow._content.location.href;
const nsIScriptSecurityManager = Components.interfaces.nsIScriptSecurityManager;
var secMan = Components.classes["@mozilla.org/scriptsecuritymanager;1"].getService().
QueryInterface(nsIScriptSecurityManager);
try {
secMan.checkLoadURIStr(sourceWin, url, nsIScriptSecurityManager.STANDARD);
} catch (e) {
throw "Edit of " + url + " denied.";
}
var windowManager = Components.classes['@mozilla.org/rdf/datasource;1?name=window-mediator'].getService();
if (!windowManager) return;
var windowManagerInterface = windowManager.QueryInterface( Components.interfaces.nsIWindowMediator);