Fixing 56009, exploit allowing XPConnect access. r,a=hyatt, sr=scc

This commit is contained in:
mstoltz%netscape.com 2000-10-13 22:59:47 +00:00
parent 955c7551bc
commit f1137e89ec
22 changed files with 92 additions and 61 deletions

View File

@ -83,6 +83,21 @@ interface nsIScriptSecurityManager : nsISupports
*/
void CheckLoadURIFromScript(in JSContextPtr cx, in nsIURI uri);
/**
* Default CheckLoadURI permissions
*/
const unsigned long STANDARD = 0;
/**
* If the source is mail, disallow the load
*/
const unsigned long DISALLOW_FROM_MAIL = 1 << 0;
/**
* Allow the loading of chrome URLs by non-chrome URLs
*/
const unsigned long ALLOW_CHROME = 1 << 1;
/**
* Check that content from "from" can load "uri".
*
@ -95,7 +110,7 @@ interface nsIScriptSecurityManager : nsISupports
* is a URI associated with mail or news
*/
void CheckLoadURI(in nsIURI from, in nsIURI uri,
in boolean disallowFromMail);
in unsigned long flags);
/**
* Check that the function 'funObj' is allowed to run on 'targetObj'

View File

@ -479,7 +479,7 @@ nsScriptSecurityManager::CheckLoadURIFromScript(JSContext *cx,
nsCOMPtr<nsIURI> uri;
if (NS_FAILED(codebase->GetURI(getter_AddRefs(uri))))
return NS_ERROR_FAILURE;
if (NS_SUCCEEDED(CheckLoadURI(uri, aURI, PR_FALSE)))
if (NS_SUCCEEDED(CheckLoadURI(uri, aURI, nsIScriptSecurityManager::STANDARD )))
return NS_OK;
// See if we're attempting to load a file: URI. If so, let a
@ -506,72 +506,73 @@ nsScriptSecurityManager::CheckLoadURIFromScript(JSContext *cx,
}
NS_IMETHODIMP
nsScriptSecurityManager::CheckLoadURI(nsIURI *aFromURI, nsIURI *aURI,
PRBool aDisallowFromMail)
nsScriptSecurityManager::CheckLoadURI(nsIURI *aSourceURI, nsIURI *aTargetURI,
PRUint32 aFlags)
{
nsCOMPtr<nsIJARURI> jarURI;
nsCOMPtr<nsIURI> uri = aFromURI;
while(uri && NS_SUCCEEDED(uri->QueryInterface(NS_GET_IID(nsIJARURI),
getter_AddRefs(jarURI))))
jarURI->GetJARFile(getter_AddRefs(uri));
if (!uri) return NS_ERROR_FAILURE;
nsCOMPtr<nsIURI> sourceUri(aSourceURI);
while((jarURI = do_QueryInterface(sourceUri)))
jarURI->GetJARFile(getter_AddRefs(sourceUri));
if (!sourceUri) return NS_ERROR_FAILURE;
nsXPIDLCString fromScheme;
if (NS_FAILED(uri->GetScheme(getter_Copies(fromScheme))))
nsXPIDLCString sourceScheme;
if (NS_FAILED(sourceUri->GetScheme(getter_Copies(sourceScheme))))
return NS_ERROR_FAILURE;
if (aDisallowFromMail &&
(nsCRT::strcasecmp(fromScheme, "mailbox") == 0 ||
nsCRT::strcasecmp(fromScheme, "imap") == 0 ||
nsCRT::strcasecmp(fromScheme, "news") == 0))
// 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;
}
uri = aURI;
while(uri && NS_SUCCEEDED(uri->QueryInterface(NS_GET_IID(nsIJARURI),
getter_AddRefs(jarURI))))
jarURI->GetJARFile(getter_AddRefs(uri));
if (!uri) return NS_ERROR_FAILURE;
nsCOMPtr<nsIURI> targetUri(aTargetURI);
while((jarURI = do_QueryInterface(targetUri)))
jarURI->GetJARFile(getter_AddRefs(targetUri));
if (!targetUri) return NS_ERROR_FAILURE;
nsXPIDLCString scheme;
if (NS_FAILED(uri->GetScheme(getter_Copies(scheme))))
nsXPIDLCString targetScheme;
if (NS_FAILED(targetUri->GetScheme(getter_Copies(targetScheme))))
return NS_ERROR_FAILURE;
if (nsCRT::strcasecmp(scheme, fromScheme) == 0)
if (nsCRT::strcasecmp(targetScheme, sourceScheme) == 0)
{
// every scheme can access another URI from the same scheme
return NS_OK;
}
enum Action { AllowProtocol, DenyProtocol, PrefControlled };
enum Action { AllowProtocol, DenyProtocol, PrefControlled, ChromeProtocol };
static const struct {
const char *name;
Action action;
} protocolList[] = {
{ "about", AllowProtocol },
{ "data", AllowProtocol },
{ "file", PrefControlled },
{ "ftp", AllowProtocol },
//-- Keep the most commonly used protocols at the top of the list
// to increase performance
{ "http", AllowProtocol },
{ "file", PrefControlled },
{ "https", AllowProtocol },
{ "chrome", ChromeProtocol },
{ "mailbox", DenyProtocol },
{ "pop", AllowProtocol },
{ "imap", DenyProtocol },
{ "pop3", DenyProtocol },
{ "news", AllowProtocol },
{ "javascript", AllowProtocol },
{ "ftp", AllowProtocol },
{ "about", AllowProtocol },
{ "mailto", AllowProtocol },
{ "data", AllowProtocol },
{ "keyword", DenyProtocol },
{ "res", DenyProtocol },
{ "resource", DenyProtocol },
{ "datetime", DenyProtocol },
{ "finger", AllowProtocol },
{ "chrome", AllowProtocol },
{ "javascript", AllowProtocol },
{ "mailto", AllowProtocol },
{ "imap", DenyProtocol },
{ "mailbox", DenyProtocol },
{ "pop3", DenyProtocol },
{ "pop", AllowProtocol },
{ "news", AllowProtocol },
{ "res", DenyProtocol }
};
for (unsigned i=0; i < sizeof(protocolList)/sizeof(protocolList[0]); i++) {
if (nsCRT::strcasecmp(scheme, protocolList[i].name) == 0) {
if (nsCRT::strcasecmp(targetScheme, protocolList[i].name) == 0) {
PRBool doCheck = PR_FALSE;
switch (protocolList[i].action) {
case AllowProtocol:
@ -581,6 +582,9 @@ nsScriptSecurityManager::CheckLoadURI(nsIURI *aFromURI, nsIURI *aURI,
// Allow access if pref is false
mPrefs->GetBoolPref("security.checkloaduri", &doCheck);
return doCheck ? NS_ERROR_DOM_BAD_URI : NS_OK;
case ChromeProtocol:
return (aFlags & nsIScriptSecurityManager::ALLOW_CHROME) ?
NS_OK : NS_ERROR_DOM_BAD_URI;
case DenyProtocol:
// Deny access
return NS_ERROR_DOM_BAD_URI;

View File

@ -724,7 +724,8 @@ nsChromeProtocolHandler::NewChannel(nsIURI* aURI,
nsCOMPtr<nsIURL> url = do_QueryInterface(aURI);
nsXPIDLCString fileExtension;
rv = url->GetFileExtension(getter_Copies(fileExtension));
if (PL_strcmp(fileExtension, "xul") == 0)
if (PL_strcasecmp(fileExtension, "xul") == 0 || PL_strcasecmp(fileExtension, "html") == 0 ||
PL_strcasecmp(fileExtension, "xml") == 0)
{
NS_WITH_SERVICE(nsIScriptSecurityManager, securityManager,
NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv);

View File

@ -2410,7 +2410,7 @@ nsGenericElement::TriggerLink(nsIPresContext* aPresContext,
if (NS_SUCCEEDED(rv))
rv = NS_NewURI(getter_AddRefs(absURI), absURLSpec, aBaseURL);
if (NS_SUCCEEDED(rv))
proceed = securityManager->CheckLoadURI(aBaseURL, absURI, PR_FALSE);
proceed = securityManager->CheckLoadURI(aBaseURL, absURI, nsIScriptSecurityManager::STANDARD);
// Only pass off the click event if the script security manager
// says it's ok.

View File

@ -3665,7 +3665,7 @@ HTMLContentSink::ProcessBaseHref(const nsString& aBaseHref)
nsCOMPtr<nsIURI> baseHrefURI;
rv = NS_NewURI(getter_AddRefs(baseHrefURI), aBaseHref, nsnull);
if (NS_FAILED(rv)) return;
rv = securityManager->CheckLoadURI(mDocumentBaseURL, baseHrefURI, PR_FALSE);
rv = securityManager->CheckLoadURI(mDocumentBaseURL, baseHrefURI, nsIScriptSecurityManager::STANDARD);
if (NS_FAILED(rv)) return;
if (nsnull == mBody) { // still in real HEAD
@ -4355,7 +4355,7 @@ HTMLContentSink::ProcessMETATag(const nsIParserNode& aNode)
if (NS_SUCCEEDED(rv)) {
rv = securityManager->CheckLoadURI(baseURI,
uri,
PR_TRUE);
nsIScriptSecurityManager::DISALLOW_FROM_MAIL);
if (NS_SUCCEEDED(rv)) {
nsCOMPtr<nsIRefreshURI> reefer =
do_QueryInterface(mWebShell);
@ -4934,7 +4934,7 @@ HTMLContentSink::ProcessSCRIPTTag(const nsIParserNode& aNode)
NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv);
if (NS_FAILED(rv))
return rv;
rv = securityManager->CheckLoadURI(mDocumentBaseURL, mScriptURI, PR_FALSE);
rv = securityManager->CheckLoadURI(mDocumentBaseURL, mScriptURI, nsIScriptSecurityManager::ALLOW_CHROME);
if (NS_FAILED(rv))
return rv;

View File

@ -1330,7 +1330,7 @@ CSSLoaderImpl::LoadStyleLink(nsIContent* aElement,
nsIURI* docURI;
rv = mDocument->GetBaseURL(docURI);
if (NS_FAILED(rv) || !docURI) return NS_ERROR_FAILURE;
rv = secMan->CheckLoadURI(docURI, aURL, PR_FALSE);
rv = secMan->CheckLoadURI(docURI, aURL, nsIScriptSecurityManager::ALLOW_CHROME);
NS_IF_RELEASE(docURI);
if (NS_FAILED(rv)) return NS_ERROR_FAILURE;

View File

@ -293,7 +293,7 @@ static nsresult CheckLoadURI(nsIURI *aBaseURI, const nsAReadableString& aURI, ns
if (NS_SUCCEEDED(rv)) {
rv= securityManager->CheckLoadURI(aBaseURI,
*aAbsURI,
PR_TRUE);
nsIScriptSecurityManager::DISALLOW_FROM_MAIL);
}
}

View File

@ -1730,7 +1730,7 @@ nsXMLContentSink::ProcessStartSCRIPTTag(const nsIParserNode& aNode)
NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv);
if (NS_FAILED(rv))
return rv;
rv = securityManager->CheckLoadURI(mDocumentBaseURL, url, PR_FALSE);
rv = securityManager->CheckLoadURI(mDocumentBaseURL, url, nsIScriptSecurityManager::ALLOW_CHROME);
if (NS_FAILED(rv))
return rv;

View File

@ -2410,7 +2410,7 @@ nsGenericElement::TriggerLink(nsIPresContext* aPresContext,
if (NS_SUCCEEDED(rv))
rv = NS_NewURI(getter_AddRefs(absURI), absURLSpec, aBaseURL);
if (NS_SUCCEEDED(rv))
proceed = securityManager->CheckLoadURI(aBaseURL, absURI, PR_FALSE);
proceed = securityManager->CheckLoadURI(aBaseURL, absURI, nsIScriptSecurityManager::STANDARD);
// Only pass off the click event if the script security manager
// says it's ok.

View File

@ -983,7 +983,7 @@ nsHTMLFrameInnerFrame::DoLoadURL(nsIPresContext* aPresContext)
nsCOMPtr<nsIURI> newURI;
rv = NS_NewURI(getter_AddRefs(newURI), absURL, baseURI);
NS_ENSURE_SUCCESS(rv, rv);
rv = secMan->CheckLoadURI(referrer, newURI, PR_FALSE);
rv = secMan->CheckLoadURI(referrer, newURI, nsIScriptSecurityManager::STANDARD);
if (NS_FAILED(rv))
return rv; // We're not

View File

@ -769,7 +769,7 @@ nsImageFrame::TriggerLink(nsIPresContext* aPresContext,
rv = NS_NewURI(getter_AddRefs(absURI), aURLSpec, baseURI);
if (NS_SUCCEEDED(rv))
proceed = securityManager->CheckLoadURI(baseURI, absURI, PR_FALSE);
proceed = securityManager->CheckLoadURI(baseURI, absURI, nsIScriptSecurityManager::STANDARD);
// Only pass off the click event if the script security manager
// says it's ok.

View File

@ -769,7 +769,7 @@ nsImageFrame::TriggerLink(nsIPresContext* aPresContext,
rv = NS_NewURI(getter_AddRefs(absURI), aURLSpec, baseURI);
if (NS_SUCCEEDED(rv))
proceed = securityManager->CheckLoadURI(baseURI, absURI, PR_FALSE);
proceed = securityManager->CheckLoadURI(baseURI, absURI, nsIScriptSecurityManager::STANDARD);
// Only pass off the click event if the script security manager
// says it's ok.

View File

@ -983,7 +983,7 @@ nsHTMLFrameInnerFrame::DoLoadURL(nsIPresContext* aPresContext)
nsCOMPtr<nsIURI> newURI;
rv = NS_NewURI(getter_AddRefs(newURI), absURL, baseURI);
NS_ENSURE_SUCCESS(rv, rv);
rv = secMan->CheckLoadURI(referrer, newURI, PR_FALSE);
rv = secMan->CheckLoadURI(referrer, newURI, nsIScriptSecurityManager::STANDARD);
if (NS_FAILED(rv))
return rv; // We're not

View File

@ -3665,7 +3665,7 @@ HTMLContentSink::ProcessBaseHref(const nsString& aBaseHref)
nsCOMPtr<nsIURI> baseHrefURI;
rv = NS_NewURI(getter_AddRefs(baseHrefURI), aBaseHref, nsnull);
if (NS_FAILED(rv)) return;
rv = securityManager->CheckLoadURI(mDocumentBaseURL, baseHrefURI, PR_FALSE);
rv = securityManager->CheckLoadURI(mDocumentBaseURL, baseHrefURI, nsIScriptSecurityManager::STANDARD);
if (NS_FAILED(rv)) return;
if (nsnull == mBody) { // still in real HEAD
@ -4355,7 +4355,7 @@ HTMLContentSink::ProcessMETATag(const nsIParserNode& aNode)
if (NS_SUCCEEDED(rv)) {
rv = securityManager->CheckLoadURI(baseURI,
uri,
PR_TRUE);
nsIScriptSecurityManager::DISALLOW_FROM_MAIL);
if (NS_SUCCEEDED(rv)) {
nsCOMPtr<nsIRefreshURI> reefer =
do_QueryInterface(mWebShell);
@ -4934,7 +4934,7 @@ HTMLContentSink::ProcessSCRIPTTag(const nsIParserNode& aNode)
NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv);
if (NS_FAILED(rv))
return rv;
rv = securityManager->CheckLoadURI(mDocumentBaseURL, mScriptURI, PR_FALSE);
rv = securityManager->CheckLoadURI(mDocumentBaseURL, mScriptURI, nsIScriptSecurityManager::ALLOW_CHROME);
if (NS_FAILED(rv))
return rv;

View File

@ -787,7 +787,7 @@ nsFormFrame::OnSubmit(nsIPresContext* aPresContext, nsIFrame* aFrame)
result = NS_NewURI(getter_AddRefs(actionURL), href, docURL);
if (NS_SUCCEEDED(result)) {
result = securityManager->CheckLoadURI(docURL, actionURL, PR_FALSE);
result = securityManager->CheckLoadURI(docURL, actionURL, nsIScriptSecurityManager::STANDARD);
if (NS_FAILED(result)) return result;
}

View File

@ -1330,7 +1330,7 @@ CSSLoaderImpl::LoadStyleLink(nsIContent* aElement,
nsIURI* docURI;
rv = mDocument->GetBaseURL(docURI);
if (NS_FAILED(rv) || !docURI) return NS_ERROR_FAILURE;
rv = secMan->CheckLoadURI(docURI, aURL, PR_FALSE);
rv = secMan->CheckLoadURI(docURI, aURL, nsIScriptSecurityManager::ALLOW_CHROME);
NS_IF_RELEASE(docURI);
if (NS_FAILED(rv)) return NS_ERROR_FAILURE;

View File

@ -1330,7 +1330,7 @@ CSSLoaderImpl::LoadStyleLink(nsIContent* aElement,
nsIURI* docURI;
rv = mDocument->GetBaseURL(docURI);
if (NS_FAILED(rv) || !docURI) return NS_ERROR_FAILURE;
rv = secMan->CheckLoadURI(docURI, aURL, PR_FALSE);
rv = secMan->CheckLoadURI(docURI, aURL, nsIScriptSecurityManager::ALLOW_CHROME);
NS_IF_RELEASE(docURI);
if (NS_FAILED(rv)) return NS_ERROR_FAILURE;

View File

@ -293,7 +293,7 @@ static nsresult CheckLoadURI(nsIURI *aBaseURI, const nsAReadableString& aURI, ns
if (NS_SUCCEEDED(rv)) {
rv= securityManager->CheckLoadURI(aBaseURI,
*aAbsURI,
PR_TRUE);
nsIScriptSecurityManager::DISALLOW_FROM_MAIL);
}
}

View File

@ -1730,7 +1730,7 @@ nsXMLContentSink::ProcessStartSCRIPTTag(const nsIParserNode& aNode)
NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv);
if (NS_FAILED(rv))
return rv;
rv = securityManager->CheckLoadURI(mDocumentBaseURL, url, PR_FALSE);
rv = securityManager->CheckLoadURI(mDocumentBaseURL, url, nsIScriptSecurityManager::ALLOW_CHROME);
if (NS_FAILED(rv))
return rv;

View File

@ -189,9 +189,19 @@ pref("capability.policy.default.history.next.read", "UniversalBrowserRead");
pref("capability.policy.default.history.previous.read", "UniversalBrowserRead");
pref("capability.policy.default.history.item.read", "UniversalBrowserRead");
pref("capability.policy.default.location.hash.write", "allAccess");
pref("capability.policy.default.location.host.write", "allAccess");
pref("capability.policy.default.location.hostname.write", "allAccess");
pref("capability.policy.default.location.href.write", "allAccess");
pref("capability.policy.default.location.pathname.write", "allAccess");
pref("capability.policy.default.location.port.write", "allAccess");
pref("capability.policy.default.location.protocol.write", "allAccess");
pref("capability.policy.default.location.search.write", "allAccess");
pref("capability.policy.default.navigator.preference.read", "UniversalPreferencesRead");
pref("capability.policy.default.navigator.preference.write", "UniversalPreferencesWrite");
pref("capability.policy.default.windowinternal.location.write", "allAccess");
pref("capability.policy.default.windowinternal.opendialog", "noAccess");
localDefPref("ghist.expires.pos", 4);

View File

@ -1757,7 +1757,7 @@ nsresult nsHTTPChannel::Redirect(const char *aNewLocation,
NS_WITH_SERVICE(nsIScriptSecurityManager, securityManager,
NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv);
if (NS_FAILED(rv)) return rv;
rv = securityManager->CheckLoadURI(mOriginalURI ? mOriginalURI : mURI, newURI, PR_TRUE);
rv = securityManager->CheckLoadURI(mOriginalURI ? mOriginalURI : mURI, newURI, nsIScriptSecurityManager::DISALLOW_FROM_MAIL);
if (NS_FAILED(rv)) return rv;
}

View File

@ -724,7 +724,8 @@ nsChromeProtocolHandler::NewChannel(nsIURI* aURI,
nsCOMPtr<nsIURL> url = do_QueryInterface(aURI);
nsXPIDLCString fileExtension;
rv = url->GetFileExtension(getter_Copies(fileExtension));
if (PL_strcmp(fileExtension, "xul") == 0)
if (PL_strcasecmp(fileExtension, "xul") == 0 || PL_strcasecmp(fileExtension, "html") == 0 ||
PL_strcasecmp(fileExtension, "xml") == 0)
{
NS_WITH_SERVICE(nsIScriptSecurityManager, securityManager,
NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv);