2018-11-30 22:52:05 +03:00
|
|
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
2015-07-11 07:22:14 +03:00
|
|
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
2012-05-21 15:12:37 +04:00
|
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
2011-10-11 09:50:08 +04:00
|
|
|
|
2013-08-27 06:05:20 +04:00
|
|
|
#include "nsScriptSecurityManager.h"
|
|
|
|
|
2013-12-09 06:52:54 +04:00
|
|
|
#include "mozilla/ArrayUtils.h"
|
2019-11-01 09:03:35 +03:00
|
|
|
#include "mozilla/StaticPrefs_extensions.h"
|
2019-08-01 09:01:40 +03:00
|
|
|
#include "mozilla/StaticPrefs_security.h"
|
2019-04-12 08:31:32 +03:00
|
|
|
#include "mozilla/StoragePrincipalHelper.h"
|
2011-10-11 09:50:08 +04:00
|
|
|
|
2016-08-04 21:19:24 +03:00
|
|
|
#include "xpcpublic.h"
|
2012-05-18 12:29:40 +04:00
|
|
|
#include "XPCWrapper.h"
|
2016-04-28 13:13:09 +03:00
|
|
|
#include "nsIInputStreamChannel.h"
|
2014-05-17 02:59:36 +04:00
|
|
|
#include "nsILoadContext.h"
|
1999-08-20 13:51:02 +04:00
|
|
|
#include "nsIServiceManager.h"
|
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2001-05-08 20:46:42 +04:00
|
|
|
#include "nsIScriptObjectPrincipal.h"
|
2001-07-16 06:40:48 +04:00
|
|
|
#include "nsIScriptContext.h"
|
2018-09-25 08:25:05 +03:00
|
|
|
#include "nsIScriptError.h"
|
1999-08-20 13:51:02 +04:00
|
|
|
#include "nsIURL.h"
|
2018-02-26 22:43:47 +03:00
|
|
|
#include "nsIURIMutator.h"
|
2006-05-02 22:54:19 +04:00
|
|
|
#include "nsINestedURI.h"
|
1999-08-20 13:51:02 +04:00
|
|
|
#include "nspr.h"
|
1999-08-30 01:58:42 +04:00
|
|
|
#include "nsJSPrincipals.h"
|
2015-05-15 23:43:11 +03:00
|
|
|
#include "mozilla/BasePrincipal.h"
|
2017-10-11 01:00:16 +03:00
|
|
|
#include "ExpandedPrincipal.h"
|
2017-03-22 13:39:08 +03:00
|
|
|
#include "SystemPrincipal.h"
|
2013-11-13 04:43:35 +04:00
|
|
|
#include "DomainPolicy.h"
|
2017-08-17 08:29:03 +03:00
|
|
|
#include "nsString.h"
|
2002-05-15 22:55:21 +04:00
|
|
|
#include "nsCRT.h"
|
2006-11-16 21:25:52 +03:00
|
|
|
#include "nsCRTGlue.h"
|
2019-09-18 22:36:31 +03:00
|
|
|
#include "nsContentSecurityUtils.h"
|
2016-01-30 02:19:56 +03:00
|
|
|
#include "nsDocShell.h"
|
2012-07-27 18:03:27 +04:00
|
|
|
#include "nsError.h"
|
2018-09-25 08:25:05 +03:00
|
|
|
#include "nsGlobalWindowInner.h"
|
1999-10-29 02:09:03 +04:00
|
|
|
#include "nsDOMCID.h"
|
2000-02-10 07:56:56 +03:00
|
|
|
#include "nsTextFormatter.h"
|
|
|
|
#include "nsIStringBundle.h"
|
2000-04-26 07:50:07 +04:00
|
|
|
#include "nsNetUtil.h"
|
2014-09-09 09:22:22 +04:00
|
|
|
#include "nsIEffectiveTLDService.h"
|
2003-10-22 02:11:49 +04:00
|
|
|
#include "nsIProperties.h"
|
2000-08-15 02:38:27 +04:00
|
|
|
#include "nsDirectoryServiceDefs.h"
|
2000-04-26 07:50:07 +04:00
|
|
|
#include "nsIFile.h"
|
2007-09-06 11:02:57 +04:00
|
|
|
#include "nsIFileURL.h"
|
2000-04-26 07:50:07 +04:00
|
|
|
#include "nsIZipReader.h"
|
2000-09-09 04:53:21 +04:00
|
|
|
#include "nsIScriptGlobalObject.h"
|
2005-11-29 02:56:44 +03:00
|
|
|
#include "nsPIDOMWindow.h"
|
2001-03-23 07:22:56 +03:00
|
|
|
#include "nsIDocShell.h"
|
2001-04-07 07:33:56 +04:00
|
|
|
#include "nsIPrompt.h"
|
|
|
|
#include "nsIWindowWatcher.h"
|
2001-04-17 05:21:44 +04:00
|
|
|
#include "nsIConsoleService.h"
|
2017-08-04 15:11:17 +03:00
|
|
|
#include "nsIOService.h"
|
2002-08-29 08:05:39 +04:00
|
|
|
#include "nsIContent.h"
|
2006-06-13 07:07:47 +04:00
|
|
|
#include "nsDOMJSUtils.h"
|
2005-09-14 08:16:27 +04:00
|
|
|
#include "nsAboutProtocolUtils.h"
|
2006-03-15 07:59:42 +03:00
|
|
|
#include "nsIClassInfo.h"
|
2006-04-25 07:24:43 +04:00
|
|
|
#include "nsIURIFixup.h"
|
2008-04-13 01:26:19 +04:00
|
|
|
#include "nsIChromeRegistry.h"
|
2017-06-08 12:44:09 +03:00
|
|
|
#include "nsIResProtocolHandler.h"
|
2010-03-08 11:24:50 +03:00
|
|
|
#include "nsIContentSecurityPolicy.h"
|
2010-08-05 06:15:55 +04:00
|
|
|
#include "nsIAsyncVerifyRedirectCallback.h"
|
2018-12-17 04:27:58 +03:00
|
|
|
#include "mozilla/Components.h"
|
2011-06-20 07:00:16 +04:00
|
|
|
#include "mozilla/Preferences.h"
|
2012-05-03 08:35:38 +04:00
|
|
|
#include "mozilla/dom/BindingUtils.h"
|
2018-07-17 22:37:48 +03:00
|
|
|
#include "mozilla/NullPrincipal.h"
|
2013-07-30 18:25:31 +04:00
|
|
|
#include <stdint.h>
|
2019-03-15 15:20:52 +03:00
|
|
|
#include "mozilla/dom/nsCSPContext.h"
|
2014-08-15 05:47:15 +04:00
|
|
|
#include "mozilla/dom/ScriptSettings.h"
|
2012-06-19 21:20:34 +04:00
|
|
|
#include "mozilla/ClearOnShutdown.h"
|
2012-07-26 23:33:45 +04:00
|
|
|
#include "mozilla/StaticPtr.h"
|
2018-10-23 09:17:13 +03:00
|
|
|
#include "mozilla/dom/WorkerCommon.h"
|
|
|
|
#include "mozilla/dom/WorkerPrivate.h"
|
2012-09-25 23:33:01 +04:00
|
|
|
#include "nsContentUtils.h"
|
2013-11-13 04:43:31 +04:00
|
|
|
#include "nsJSUtils.h"
|
2014-07-10 10:56:36 +04:00
|
|
|
#include "nsILoadInfo.h"
|
2017-05-18 10:07:25 +03:00
|
|
|
#include "nsIDOMXULCommandDispatcher.h"
|
|
|
|
#include "nsITreeSelection.h"
|
2012-09-25 23:33:01 +04:00
|
|
|
|
|
|
|
// This should be probably defined on some other place... but I couldn't find it
|
|
|
|
#define WEBAPPS_PERM_NAME "webapps-manage"
|
2011-06-20 07:00:16 +04:00
|
|
|
|
|
|
|
using namespace mozilla;
|
2012-03-31 08:42:20 +04:00
|
|
|
using namespace mozilla::dom;
|
2000-02-10 07:56:56 +03:00
|
|
|
|
2012-07-30 18:20:58 +04:00
|
|
|
nsIIOService* nsScriptSecurityManager::sIOService = nullptr;
|
2011-09-29 10:19:26 +04:00
|
|
|
bool nsScriptSecurityManager::sStrictFileOriginPolicy = true;
|
1999-08-20 13:51:02 +04:00
|
|
|
|
2018-05-08 16:52:53 +03:00
|
|
|
namespace {
|
|
|
|
|
|
|
|
class BundleHelper {
|
|
|
|
public:
|
|
|
|
NS_INLINE_DECL_REFCOUNTING(BundleHelper)
|
|
|
|
|
|
|
|
static nsIStringBundle* GetOrCreate() {
|
|
|
|
MOZ_ASSERT(!sShutdown);
|
|
|
|
|
|
|
|
// Already shutting down. Nothing should require the use of the string
|
|
|
|
// bundle when shutting down.
|
|
|
|
if (sShutdown) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!sSelf) {
|
|
|
|
sSelf = new BundleHelper();
|
|
|
|
}
|
|
|
|
|
|
|
|
return sSelf->GetOrCreateInternal();
|
|
|
|
}
|
|
|
|
|
|
|
|
static void Shutdown() {
|
|
|
|
sSelf = nullptr;
|
|
|
|
sShutdown = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
~BundleHelper() = default;
|
|
|
|
|
|
|
|
nsIStringBundle* GetOrCreateInternal() {
|
|
|
|
if (!mBundle) {
|
|
|
|
nsCOMPtr<nsIStringBundleService> bundleService =
|
|
|
|
mozilla::services::GetStringBundleService();
|
|
|
|
if (NS_WARN_IF(!bundleService)) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult rv = bundleService->CreateBundle(
|
|
|
|
"chrome://global/locale/security/caps.properties",
|
|
|
|
getter_AddRefs(mBundle));
|
|
|
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return mBundle;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsCOMPtr<nsIStringBundle> mBundle;
|
|
|
|
|
|
|
|
static StaticRefPtr<BundleHelper> sSelf;
|
|
|
|
static bool sShutdown;
|
|
|
|
};
|
|
|
|
|
|
|
|
StaticRefPtr<BundleHelper> BundleHelper::sSelf;
|
|
|
|
bool BundleHelper::sShutdown = false;
|
|
|
|
|
|
|
|
} // namespace
|
|
|
|
|
2002-02-13 07:20:46 +03:00
|
|
|
///////////////////////////
|
|
|
|
// Convenience Functions //
|
|
|
|
///////////////////////////
|
1999-11-12 01:10:36 +03:00
|
|
|
|
2009-05-21 05:49:42 +04:00
|
|
|
class nsAutoInPrincipalDomainOriginSetter {
|
|
|
|
public:
|
|
|
|
nsAutoInPrincipalDomainOriginSetter() { ++sInPrincipalDomainOrigin; }
|
|
|
|
~nsAutoInPrincipalDomainOriginSetter() { --sInPrincipalDomainOrigin; }
|
2012-08-22 19:56:38 +04:00
|
|
|
static uint32_t sInPrincipalDomainOrigin;
|
2009-05-21 05:49:42 +04:00
|
|
|
};
|
2012-08-22 19:56:38 +04:00
|
|
|
uint32_t nsAutoInPrincipalDomainOriginSetter::sInPrincipalDomainOrigin;
|
2009-05-21 05:49:42 +04:00
|
|
|
|
2009-07-27 05:27:33 +04:00
|
|
|
static nsresult GetOriginFromURI(nsIURI* aURI, nsACString& aOrigin) {
|
2009-05-21 23:46:05 +04:00
|
|
|
if (nsAutoInPrincipalDomainOriginSetter::sInPrincipalDomainOrigin > 1) {
|
|
|
|
// Allow a single recursive call to GetPrincipalDomainOrigin, since that
|
|
|
|
// might be happening on a different principal from the first call. But
|
|
|
|
// after that, cut off the recursion; it just indicates that something
|
|
|
|
// we're doing in this method causes us to reenter a security check here.
|
|
|
|
return NS_ERROR_NOT_AVAILABLE;
|
|
|
|
}
|
|
|
|
|
2009-05-21 05:49:42 +04:00
|
|
|
nsAutoInPrincipalDomainOriginSetter autoSetter;
|
2008-07-29 10:37:58 +04:00
|
|
|
|
2009-07-27 05:27:33 +04:00
|
|
|
nsCOMPtr<nsIURI> uri = NS_GetInnermostURI(aURI);
|
2008-07-29 10:37:58 +04:00
|
|
|
NS_ENSURE_TRUE(uri, NS_ERROR_UNEXPECTED);
|
|
|
|
|
2012-09-02 06:35:17 +04:00
|
|
|
nsAutoCString hostPort;
|
2008-07-29 10:37:58 +04:00
|
|
|
|
|
|
|
nsresult rv = uri->GetHostPort(hostPort);
|
|
|
|
if (NS_SUCCEEDED(rv)) {
|
2012-09-02 06:35:17 +04:00
|
|
|
nsAutoCString scheme;
|
2008-07-29 10:37:58 +04:00
|
|
|
rv = uri->GetScheme(scheme);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
aOrigin = scheme + NS_LITERAL_CSTRING("://") + hostPort;
|
|
|
|
} else {
|
|
|
|
// Some URIs (e.g., nsSimpleURI) don't support host. Just
|
|
|
|
// get the full spec.
|
|
|
|
rv = uri->GetSpec(aOrigin);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2009-07-27 05:27:33 +04:00
|
|
|
static nsresult GetPrincipalDomainOrigin(nsIPrincipal* aPrincipal,
|
|
|
|
nsACString& aOrigin) {
|
|
|
|
nsCOMPtr<nsIURI> uri;
|
|
|
|
aPrincipal->GetDomain(getter_AddRefs(uri));
|
|
|
|
if (!uri) {
|
|
|
|
aPrincipal->GetURI(getter_AddRefs(uri));
|
|
|
|
}
|
|
|
|
NS_ENSURE_TRUE(uri, NS_ERROR_UNEXPECTED);
|
|
|
|
|
|
|
|
return GetOriginFromURI(uri, aOrigin);
|
|
|
|
}
|
|
|
|
|
2016-08-15 13:20:01 +03:00
|
|
|
inline void SetPendingExceptionASCII(JSContext* cx, const char* aMsg) {
|
|
|
|
JS_ReportErrorASCII(cx, "%s", aMsg);
|
2004-09-01 11:53:32 +04:00
|
|
|
}
|
|
|
|
|
2014-01-04 19:02:17 +04:00
|
|
|
inline void SetPendingException(JSContext* cx, const char16_t* aMsg) {
|
2016-10-11 21:44:40 +03:00
|
|
|
NS_ConvertUTF16toUTF8 msg(aMsg);
|
|
|
|
JS_ReportErrorUTF8(cx, "%s", msg.get());
|
2004-09-01 11:53:32 +04:00
|
|
|
}
|
|
|
|
|
2008-02-27 06:45:29 +03:00
|
|
|
/* static */
|
2002-06-15 03:54:18 +04:00
|
|
|
bool nsScriptSecurityManager::SecurityCompareURIs(nsIURI* aSourceURI,
|
2006-11-15 01:46:45 +03:00
|
|
|
nsIURI* aTargetURI) {
|
2008-08-28 05:15:32 +04:00
|
|
|
return NS_SecurityCompareURIs(aSourceURI, aTargetURI,
|
|
|
|
sStrictFileOriginPolicy);
|
2002-06-15 03:54:18 +04:00
|
|
|
}
|
|
|
|
|
2008-10-08 17:16:27 +04:00
|
|
|
// SecurityHashURI is consistent with SecurityCompareURIs because
|
|
|
|
// NS_SecurityHashURI is consistent with NS_SecurityCompareURIs. See
|
|
|
|
// nsNetUtil.h.
|
|
|
|
uint32_t nsScriptSecurityManager::SecurityHashURI(nsIURI* aURI) {
|
|
|
|
return NS_SecurityHashURI(aURI);
|
|
|
|
}
|
|
|
|
|
2015-04-13 23:37:14 +03:00
|
|
|
/*
|
|
|
|
* GetChannelResultPrincipal will return the principal that the resource
|
|
|
|
* returned by this channel will use. For example, if the resource is in
|
|
|
|
* a sandbox, it will return the nullprincipal. If the resource is forced
|
|
|
|
* to inherit principal, it will return the principal of its parent. If
|
|
|
|
* the load doesn't require sandboxing or inheriting, it will return the same
|
|
|
|
* principal as GetChannelURIPrincipal. Namely the principal of the URI
|
|
|
|
* that is being loaded.
|
|
|
|
*/
|
2006-11-22 21:27:54 +03:00
|
|
|
NS_IMETHODIMP
|
2014-08-07 03:05:40 +04:00
|
|
|
nsScriptSecurityManager::GetChannelResultPrincipal(nsIChannel* aChannel,
|
|
|
|
nsIPrincipal** aPrincipal) {
|
2016-04-28 13:13:09 +03:00
|
|
|
return GetChannelResultPrincipal(aChannel, aPrincipal,
|
|
|
|
/*aIgnoreSandboxing*/ false);
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult nsScriptSecurityManager::GetChannelResultPrincipalIfNotSandboxed(
|
|
|
|
nsIChannel* aChannel, nsIPrincipal** aPrincipal) {
|
|
|
|
return GetChannelResultPrincipal(aChannel, aPrincipal,
|
|
|
|
/*aIgnoreSandboxing*/ true);
|
|
|
|
}
|
|
|
|
|
2019-04-12 08:31:32 +03:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsScriptSecurityManager::GetChannelResultStoragePrincipal(
|
|
|
|
nsIChannel* aChannel, nsIPrincipal** aPrincipal) {
|
|
|
|
nsCOMPtr<nsIPrincipal> principal;
|
|
|
|
nsresult rv = GetChannelResultPrincipal(aChannel, getter_AddRefs(principal),
|
|
|
|
/*aIgnoreSandboxing*/ false);
|
|
|
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
return StoragePrincipalHelper::Create(aChannel, principal, aPrincipal);
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsScriptSecurityManager::GetChannelResultPrincipals(
|
|
|
|
nsIChannel* aChannel, nsIPrincipal** aPrincipal,
|
|
|
|
nsIPrincipal** aStoragePrincipal) {
|
|
|
|
nsresult rv = GetChannelResultPrincipal(aChannel, aPrincipal,
|
|
|
|
/*aIgnoreSandboxing*/ false);
|
|
|
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2019-09-27 17:05:13 +03:00
|
|
|
if (!(*aPrincipal)->GetIsContentPrincipal()) {
|
|
|
|
// If for some reason we don't have a content principal here, just reuse our
|
|
|
|
// principal for the storage principal too, since attempting to create a
|
|
|
|
// storage principal would fail anyway.
|
|
|
|
nsCOMPtr<nsIPrincipal> copy = *aPrincipal;
|
|
|
|
copy.forget(aStoragePrincipal);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2019-04-12 08:31:32 +03:00
|
|
|
return StoragePrincipalHelper::Create(aChannel, *aPrincipal,
|
|
|
|
aStoragePrincipal);
|
|
|
|
}
|
|
|
|
|
2016-04-28 13:13:09 +03:00
|
|
|
nsresult nsScriptSecurityManager::GetChannelResultPrincipal(
|
|
|
|
nsIChannel* aChannel, nsIPrincipal** aPrincipal, bool aIgnoreSandboxing) {
|
2018-04-28 22:50:58 +03:00
|
|
|
MOZ_ASSERT(aChannel, "Must have channel!");
|
|
|
|
|
2017-01-30 16:13:13 +03:00
|
|
|
// Check whether we have an nsILoadInfo that says what we should do.
|
2019-02-20 15:27:25 +03:00
|
|
|
nsCOMPtr<nsILoadInfo> loadInfo = aChannel->LoadInfo();
|
|
|
|
if (loadInfo->GetForceInheritPrincipalOverruleOwner()) {
|
2017-11-03 05:56:27 +03:00
|
|
|
nsCOMPtr<nsIPrincipal> principalToInherit =
|
|
|
|
loadInfo->FindPrincipalToInherit(aChannel);
|
2017-01-30 16:13:13 +03:00
|
|
|
principalToInherit.forget(aPrincipal);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
2016-10-05 22:19:51 +03:00
|
|
|
|
2017-01-30 16:13:13 +03:00
|
|
|
nsCOMPtr<nsISupports> owner;
|
|
|
|
aChannel->GetOwner(getter_AddRefs(owner));
|
|
|
|
if (owner) {
|
|
|
|
CallQueryInterface(owner, aPrincipal);
|
|
|
|
if (*aPrincipal) {
|
|
|
|
return NS_OK;
|
2006-11-22 21:27:54 +03:00
|
|
|
}
|
2017-01-30 16:13:13 +03:00
|
|
|
}
|
2006-11-22 21:27:54 +03:00
|
|
|
|
2019-02-20 15:27:25 +03:00
|
|
|
if (!aIgnoreSandboxing && loadInfo->GetLoadingSandboxed()) {
|
|
|
|
nsCOMPtr<nsIPrincipal> sandboxedLoadingPrincipal =
|
|
|
|
loadInfo->GetSandboxedLoadingPrincipal();
|
|
|
|
MOZ_ASSERT(sandboxedLoadingPrincipal);
|
|
|
|
sandboxedLoadingPrincipal.forget(aPrincipal);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
2014-07-10 10:56:36 +04:00
|
|
|
|
2019-02-20 15:27:25 +03:00
|
|
|
bool forceInherit = loadInfo->GetForceInheritPrincipal();
|
|
|
|
if (aIgnoreSandboxing && !forceInherit) {
|
|
|
|
// Check if SEC_FORCE_INHERIT_PRINCIPAL was dropped because of
|
|
|
|
// sandboxing:
|
|
|
|
if (loadInfo->GetLoadingSandboxed() &&
|
|
|
|
loadInfo->GetForceInheritPrincipalDropped()) {
|
|
|
|
forceInherit = true;
|
2017-01-30 16:13:13 +03:00
|
|
|
}
|
2019-02-20 15:27:25 +03:00
|
|
|
}
|
|
|
|
if (forceInherit) {
|
|
|
|
nsCOMPtr<nsIPrincipal> principalToInherit =
|
|
|
|
loadInfo->FindPrincipalToInherit(aChannel);
|
|
|
|
principalToInherit.forget(aPrincipal);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
auto securityMode = loadInfo->GetSecurityMode();
|
|
|
|
// The data: inheritance flags should only apply to the initial load,
|
|
|
|
// not to loads that it might have redirected to.
|
|
|
|
if (loadInfo->RedirectChain().IsEmpty() &&
|
|
|
|
(securityMode == nsILoadInfo::SEC_REQUIRE_SAME_ORIGIN_DATA_INHERITS ||
|
|
|
|
securityMode == nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_INHERITS ||
|
|
|
|
securityMode == nsILoadInfo::SEC_REQUIRE_CORS_DATA_INHERITS)) {
|
|
|
|
nsCOMPtr<nsIURI> uri;
|
|
|
|
nsresult rv = NS_GetFinalChannelURI(aChannel, getter_AddRefs(uri));
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
|
|
|
nsCOMPtr<nsIPrincipal> principalToInherit =
|
|
|
|
loadInfo->FindPrincipalToInherit(aChannel);
|
|
|
|
bool inheritForAboutBlank = loadInfo->GetAboutBlankInherits();
|
|
|
|
|
|
|
|
if (nsContentUtils::ChannelShouldInheritPrincipal(
|
|
|
|
principalToInherit, uri, inheritForAboutBlank, false)) {
|
2017-01-30 16:13:13 +03:00
|
|
|
principalToInherit.forget(aPrincipal);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
}
|
2019-05-22 02:14:27 +03:00
|
|
|
return GetChannelURIPrincipal(aChannel, aPrincipal);
|
2014-08-07 03:05:40 +04:00
|
|
|
}
|
2014-07-10 10:56:36 +04:00
|
|
|
|
2015-04-13 23:37:14 +03:00
|
|
|
/* The principal of the URI that this channel is loading. This is never
|
|
|
|
* affected by things like sandboxed loads, or loads where we forcefully
|
|
|
|
* inherit the principal. Think of this as the principal of the server
|
|
|
|
* which this channel is loading from. Most callers should use
|
|
|
|
* GetChannelResultPrincipal instead of GetChannelURIPrincipal. Only
|
|
|
|
* call GetChannelURIPrincipal if you are sure that you want the
|
|
|
|
* principal that matches the uri, even in cases when the load is
|
|
|
|
* sandboxed or when the load could be a blob or data uri (i.e even when
|
|
|
|
* you encounter loads that may or may not be sandboxed and loads
|
|
|
|
* that may or may not inherit)."
|
|
|
|
*/
|
2014-08-07 03:05:40 +04:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsScriptSecurityManager::GetChannelURIPrincipal(nsIChannel* aChannel,
|
|
|
|
nsIPrincipal** aPrincipal) {
|
2018-04-28 22:50:58 +03:00
|
|
|
MOZ_ASSERT(aChannel, "Must have channel!");
|
2014-08-07 03:05:40 +04:00
|
|
|
|
|
|
|
// Get the principal from the URI. Make sure this does the same thing
|
2019-08-09 20:47:41 +03:00
|
|
|
// as Document::Reset and PrototypeDocumentContentSink::Init.
|
2006-11-22 21:27:54 +03:00
|
|
|
nsCOMPtr<nsIURI> uri;
|
2007-10-24 01:56:41 +04:00
|
|
|
nsresult rv = NS_GetFinalChannelURI(aChannel, getter_AddRefs(uri));
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
2006-11-22 21:27:54 +03:00
|
|
|
|
2019-02-20 15:27:25 +03:00
|
|
|
nsCOMPtr<nsILoadInfo> loadInfo = aChannel->LoadInfo();
|
2016-01-13 07:30:00 +03:00
|
|
|
|
2016-08-26 07:41:37 +03:00
|
|
|
// Inherit the origin attributes from loadInfo.
|
|
|
|
// If this is a top-level document load, the origin attributes of the
|
|
|
|
// loadInfo will be set from nsDocShell::DoURILoad.
|
|
|
|
// For subresource loading, the origin attributes of the loadInfo is from
|
|
|
|
// its loadingPrincipal.
|
2019-02-20 15:27:25 +03:00
|
|
|
OriginAttributes attrs = loadInfo->GetOriginAttributes();
|
2017-03-08 09:41:51 +03:00
|
|
|
|
|
|
|
nsCOMPtr<nsIPrincipal> prin =
|
2019-07-08 19:37:45 +03:00
|
|
|
BasePrincipal::CreateContentPrincipal(uri, attrs);
|
2015-05-15 23:43:11 +03:00
|
|
|
prin.forget(aPrincipal);
|
|
|
|
return *aPrincipal ? NS_OK : NS_ERROR_FAILURE;
|
2006-11-22 21:27:54 +03:00
|
|
|
}
|
|
|
|
|
1999-11-12 01:10:36 +03:00
|
|
|
/////////////////////////////
|
|
|
|
// nsScriptSecurityManager //
|
|
|
|
/////////////////////////////
|
|
|
|
|
1999-09-08 00:40:20 +04:00
|
|
|
////////////////////////////////////
|
|
|
|
// Methods implementing ISupports //
|
|
|
|
////////////////////////////////////
|
2014-04-27 11:06:00 +04:00
|
|
|
NS_IMPL_ISUPPORTS(nsScriptSecurityManager, nsIScriptSecurityManager)
|
1999-08-20 13:51:02 +04:00
|
|
|
|
1999-09-08 00:40:20 +04:00
|
|
|
///////////////////////////////////////////////////
|
|
|
|
// Methods implementing nsIScriptSecurityManager //
|
|
|
|
///////////////////////////////////////////////////
|
1999-08-20 13:51:02 +04:00
|
|
|
|
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2001-05-08 20:46:42 +04:00
|
|
|
///////////////// Security Checks /////////////////
|
2012-03-09 13:48:50 +04:00
|
|
|
|
2018-07-16 18:58:04 +03:00
|
|
|
bool nsScriptSecurityManager::ContentSecurityPolicyPermitsJSAction(
|
|
|
|
JSContext* cx, JS::HandleValue aValue) {
|
2014-05-07 02:43:03 +04:00
|
|
|
MOZ_ASSERT(cx == nsContentUtils::GetCurrentJSContext());
|
2018-10-15 11:02:04 +03:00
|
|
|
|
2019-05-22 02:14:27 +03:00
|
|
|
// Get the window, if any, corresponding to the current global
|
2010-03-08 11:24:50 +03:00
|
|
|
nsCOMPtr<nsIContentSecurityPolicy> csp;
|
2019-05-22 02:14:27 +03:00
|
|
|
if (nsGlobalWindowInner* win = xpc::CurrentWindowOrNull(cx)) {
|
|
|
|
csp = win->GetCsp();
|
|
|
|
}
|
2010-03-08 11:24:50 +03:00
|
|
|
|
2019-11-01 09:03:35 +03:00
|
|
|
nsCOMPtr<nsIPrincipal> subjectPrincipal = nsContentUtils::SubjectPrincipal();
|
|
|
|
if (!csp) {
|
|
|
|
if (!StaticPrefs::extensions_content_script_csp_enabled()) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
// Get the CSP for addon sandboxes. If the principal is expanded and has a
|
|
|
|
// csp, we're probably in luck.
|
|
|
|
auto* basePrin = BasePrincipal::Cast(subjectPrincipal);
|
|
|
|
// ContentScriptAddonPolicy means it is also an expanded principal, thus
|
|
|
|
// this is in a sandbox used as a content script.
|
|
|
|
if (basePrin->ContentScriptAddonPolicy()) {
|
|
|
|
basePrin->As<ExpandedPrincipal>()->GetCsp(getter_AddRefs(csp));
|
|
|
|
}
|
|
|
|
// don't do anything unless there's a CSP
|
|
|
|
if (!csp) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
2010-03-08 11:24:50 +03:00
|
|
|
|
2018-10-23 09:17:13 +03:00
|
|
|
nsCOMPtr<nsICSPEventListener> cspEventListener;
|
|
|
|
if (!NS_IsMainThread()) {
|
|
|
|
WorkerPrivate* workerPrivate =
|
|
|
|
mozilla::dom::GetWorkerPrivateFromContext(cx);
|
|
|
|
if (workerPrivate) {
|
|
|
|
cspEventListener = workerPrivate->CSPEventListener();
|
|
|
|
}
|
2018-11-30 13:46:48 +03:00
|
|
|
}
|
2018-10-23 09:17:13 +03:00
|
|
|
|
2011-09-29 10:19:26 +04:00
|
|
|
bool evalOK = true;
|
2012-10-16 00:54:58 +04:00
|
|
|
bool reportViolation = false;
|
2019-05-22 02:14:27 +03:00
|
|
|
nsresult rv = csp->GetAllowsEval(&reportViolation, &evalOK);
|
2010-03-08 11:24:50 +03:00
|
|
|
|
2019-08-01 23:45:01 +03:00
|
|
|
// A little convoluted. We want the scriptSample for a) reporting a violation
|
2019-08-06 22:56:23 +03:00
|
|
|
// or b) passing it to AssertEvalNotUsingSystemPrincipal or c) we're in the
|
|
|
|
// parent process. So do the work to get it if either of those cases is true.
|
2019-08-01 23:45:01 +03:00
|
|
|
nsAutoJSString scriptSample;
|
2019-08-06 22:56:23 +03:00
|
|
|
if (reportViolation || subjectPrincipal->IsSystemPrincipal() ||
|
|
|
|
XRE_IsE10sParentProcess()) {
|
2018-07-16 18:58:04 +03:00
|
|
|
JS::Rooted<JSString*> jsString(cx, JS::ToString(cx, aValue));
|
|
|
|
if (NS_WARN_IF(!jsString)) {
|
|
|
|
JS_ClearPendingException(cx);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (NS_WARN_IF(!scriptSample.init(cx, jsString))) {
|
|
|
|
JS_ClearPendingException(cx);
|
|
|
|
return false;
|
|
|
|
}
|
2019-08-01 23:45:01 +03:00
|
|
|
}
|
|
|
|
|
2019-09-19 05:32:41 +03:00
|
|
|
#if !defined(ANDROID)
|
Bug 1583949 - Add a check for IsEvalAllowed to the worker callpath for eval() r=ckerschb,baku
This patch does several things. Because Workers aren't on the main thread,
many of the things done are in the name of off main thread access.
1) Changes a parameter in IsEvalAllowed from a nsIPrincipal to a bool.
We only used the principal to determined if it was the System Principal.
Principals aren't thread safe and can only be accessed on Main Thread, so
if we passed a Principal in, we would be in error. Instead only pass in
the bool which - for workers - comes from a thread-safe location.
2) Separates out the Telemetry Event Recording and sending a message to the
console into a new function nsContentSecurityUtils::NotifyEvalUsage. (And
creates a runnable that calls it.)
We do this because we will need to only call this method on the main thread.
Telemetry Event Recording has only ever been called on the Main Thread.
While I possibly-successfully cut it over to happen Off Main Thread (OMT)
by porting preferences to StaticPrefs, I don't know if there were other
threading assumptions in the Telemetry Code. So it would be much safer to
just continue recording Event Telemetry on the main thread.
Sending a message to the console requires calling GetStringBundleService()
which requires main thread. I didn't investigate if this could be made
thread-safe, I just threw it onto the main thread too.
If, in IsEvalAllowed, we are on the main thread - we call NotifyEvalUsage
directly. If we are not, we create a runnable which will then call
NotifyEvalUsage for us on the main thread.
3) Ports allow_eval_with_system_principal and allow_eval_in_parent_process
from bools to RelaxedAtomicBool - because we now check these prefs OMT.
4) In RuntimeService.cpp, adds the call to IsEvalAllowed.
5) Add resource://gre/modules/workers/require.js to the allowlist of eval
usage. This was the script that identified this gap in the first place.
It uses eval (twice) for structural reasons (scope and line number
massaging.) The contents of the eval are the result of a request to a
uri (which may be internal, like resource://). The whole point of this
is to implement a CommonJS require() api.
This usage of eval is safe because the only way an attacker can inject
into it is by either controlling the response of the uri request or
controlling (or appending to) the argument. If they can do that, they
are able to inject script into Firefox even if we cut this usage of eval
over to some other type of safe(r) script loader.
Bug 1584564 tracks making sure calls to require.js are safe.
6) Adds cld-worker.js to the allowlist. Bug 1584605 is for refactoring that
eval usage, which is decidedly non-trivial.
7) Does _not_ enforce the eval restrictions for workers. While I've gotten
try to be green and not throw up any instances of eval-usage by workers,
it is much safer to deploy this is Telemetry-only mode for Workers for
a little bit to see if anything pops up from the Nightly population.
Bug 1584602 is for enforcing the checks.
Differential Revision: https://phabricator.services.mozilla.com/D47480
--HG--
extra : moz-landing-system : lando
2019-10-08 20:31:35 +03:00
|
|
|
if (!nsContentSecurityUtils::IsEvalAllowed(
|
|
|
|
cx, subjectPrincipal->IsSystemPrincipal(), scriptSample)) {
|
2019-09-19 05:32:41 +03:00
|
|
|
return false;
|
|
|
|
}
|
2019-08-01 23:45:01 +03:00
|
|
|
#endif
|
|
|
|
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
NS_WARNING("CSP: failed to get allowsEval");
|
|
|
|
return true; // fail open to not break sites.
|
|
|
|
}
|
2018-07-16 18:58:04 +03:00
|
|
|
|
2019-08-01 23:45:01 +03:00
|
|
|
if (reportViolation) {
|
2018-07-16 18:58:04 +03:00
|
|
|
JS::AutoFilename scriptFilename;
|
2011-01-31 21:09:44 +03:00
|
|
|
nsAutoString fileName;
|
2012-04-16 23:30:00 +04:00
|
|
|
unsigned lineNum = 0;
|
2018-07-05 09:21:04 +03:00
|
|
|
unsigned columnNum = 0;
|
|
|
|
if (JS::DescribeScriptedCaller(cx, &scriptFilename, &lineNum, &columnNum)) {
|
2014-02-25 19:43:14 +04:00
|
|
|
if (const char* file = scriptFilename.get()) {
|
2012-04-16 23:30:00 +04:00
|
|
|
CopyUTF8toUTF16(nsDependentCString(file), fileName);
|
2011-01-31 21:09:44 +03:00
|
|
|
}
|
2016-02-26 23:23:13 +03:00
|
|
|
} else {
|
|
|
|
MOZ_ASSERT(!JS_IsExceptionPending(cx));
|
2011-01-31 21:09:44 +03:00
|
|
|
}
|
|
|
|
csp->LogViolationDetails(nsIContentSecurityPolicy::VIOLATION_TYPE_EVAL,
|
2018-07-10 18:40:21 +03:00
|
|
|
nullptr, // triggering element
|
2018-10-23 09:17:13 +03:00
|
|
|
cspEventListener, fileName, scriptSample, lineNum,
|
2018-09-25 08:25:05 +03:00
|
|
|
columnNum, EmptyString(), EmptyString());
|
2018-11-30 13:46:48 +03:00
|
|
|
}
|
2011-01-31 21:09:44 +03:00
|
|
|
|
2010-03-08 11:24:50 +03:00
|
|
|
return evalOK;
|
|
|
|
}
|
|
|
|
|
2014-01-03 20:32:56 +04:00
|
|
|
// static
|
|
|
|
bool nsScriptSecurityManager::JSPrincipalsSubsume(JSPrincipals* first,
|
|
|
|
JSPrincipals* second) {
|
|
|
|
return nsJSPrincipals::get(first)->Subsumes(nsJSPrincipals::get(second));
|
|
|
|
}
|
|
|
|
|
2002-06-15 03:54:18 +04:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsScriptSecurityManager::CheckSameOriginURI(nsIURI* aSourceURI,
|
2007-10-27 05:46:09 +04:00
|
|
|
nsIURI* aTargetURI,
|
2018-09-25 08:25:05 +03:00
|
|
|
bool reportError,
|
|
|
|
bool aFromPrivateWindow) {
|
|
|
|
// Please note that aFromPrivateWindow is only 100% accurate if
|
|
|
|
// reportError is true.
|
2006-11-15 01:46:45 +03:00
|
|
|
if (!SecurityCompareURIs(aSourceURI, aTargetURI)) {
|
2007-10-27 05:46:09 +04:00
|
|
|
if (reportError) {
|
2018-09-25 08:25:05 +03:00
|
|
|
ReportError("CheckSameOriginError", aSourceURI, aTargetURI,
|
|
|
|
aFromPrivateWindow);
|
2002-06-15 03:54:18 +04:00
|
|
|
}
|
|
|
|
return NS_ERROR_DOM_BAD_URI;
|
2018-11-30 13:46:48 +03:00
|
|
|
}
|
2002-06-15 03:54:18 +04:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2019-02-26 01:03:35 +03:00
|
|
|
/*static*/
|
|
|
|
uint32_t nsScriptSecurityManager::HashPrincipalByOrigin(
|
2008-10-08 17:16:27 +04:00
|
|
|
nsIPrincipal* aPrincipal) {
|
|
|
|
nsCOMPtr<nsIURI> uri;
|
|
|
|
aPrincipal->GetDomain(getter_AddRefs(uri));
|
|
|
|
if (!uri) aPrincipal->GetURI(getter_AddRefs(uri));
|
|
|
|
return SecurityHashURI(uri);
|
|
|
|
}
|
2003-06-19 03:48:57 +04:00
|
|
|
|
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2001-05-08 20:46:42 +04:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsScriptSecurityManager::CheckLoadURIFromScript(JSContext* cx, nsIURI* aURI) {
|
|
|
|
// Get principal of currently executing script.
|
2014-05-07 02:43:03 +04:00
|
|
|
MOZ_ASSERT(cx == nsContentUtils::GetCurrentJSContext());
|
2014-05-13 13:58:00 +04:00
|
|
|
nsIPrincipal* principal = nsContentUtils::SubjectPrincipal();
|
2014-05-07 02:43:03 +04:00
|
|
|
nsresult rv = CheckLoadURIWithPrincipal(principal, aURI,
|
|
|
|
nsIScriptSecurityManager::STANDARD);
|
2006-04-03 00:58:26 +04:00
|
|
|
if (NS_SUCCEEDED(rv)) {
|
|
|
|
// OK to load
|
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2001-05-08 20:46:42 +04:00
|
|
|
return NS_OK;
|
2006-04-03 00:58:26 +04:00
|
|
|
}
|
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2001-05-08 20:46:42 +04:00
|
|
|
|
|
|
|
// Report error.
|
2012-09-02 06:35:17 +04:00
|
|
|
nsAutoCString spec;
|
2002-03-06 10:48:55 +03:00
|
|
|
if (NS_FAILED(aURI->GetAsciiSpec(spec))) return NS_ERROR_FAILURE;
|
2012-09-02 06:35:17 +04:00
|
|
|
nsAutoCString msg("Access to '");
|
2009-05-20 08:57:37 +04:00
|
|
|
msg.Append(spec);
|
|
|
|
msg.AppendLiteral("' from script denied");
|
2016-08-15 13:20:01 +03:00
|
|
|
SetPendingExceptionASCII(cx, msg.get());
|
2008-03-17 17:10:48 +03:00
|
|
|
return NS_ERROR_DOM_BAD_URI;
|
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2001-05-08 20:46:42 +04:00
|
|
|
}
|
|
|
|
|
2006-11-11 02:49:08 +03:00
|
|
|
/**
|
|
|
|
* Helper method to handle cases where a flag passed to
|
|
|
|
* CheckLoadURIWithPrincipal means denying loading if the given URI has certain
|
|
|
|
* nsIProtocolHandler flags set.
|
|
|
|
* @return if success, access is allowed. Otherwise, deny access
|
|
|
|
*/
|
2012-08-22 19:56:38 +04:00
|
|
|
static nsresult DenyAccessIfURIHasFlags(nsIURI* aURI, uint32_t aURIFlags) {
|
2018-04-28 22:50:58 +03:00
|
|
|
MOZ_ASSERT(aURI, "Must have URI!");
|
2016-02-05 04:42:44 +03:00
|
|
|
|
2011-09-29 10:19:26 +04:00
|
|
|
bool uriHasFlags;
|
2006-11-11 02:49:08 +03:00
|
|
|
nsresult rv = NS_URIChainHasFlags(aURI, aURIFlags, &uriHasFlags);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
|
|
|
if (uriHasFlags) {
|
|
|
|
return NS_ERROR_DOM_BAD_URI;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2014-09-09 09:22:22 +04:00
|
|
|
static bool EqualOrSubdomain(nsIURI* aProbeArg, nsIURI* aBase) {
|
2018-02-26 22:43:47 +03:00
|
|
|
nsresult rv;
|
|
|
|
nsCOMPtr<nsIURI> probe = aProbeArg;
|
2014-09-09 09:22:22 +04:00
|
|
|
|
|
|
|
nsCOMPtr<nsIEffectiveTLDService> tldService =
|
2016-05-19 11:04:46 +03:00
|
|
|
do_GetService(NS_EFFECTIVETLDSERVICE_CONTRACTID);
|
2014-09-09 09:22:22 +04:00
|
|
|
NS_ENSURE_TRUE(tldService, false);
|
|
|
|
while (true) {
|
|
|
|
if (nsScriptSecurityManager::SecurityCompareURIs(probe, aBase)) {
|
|
|
|
return true;
|
2018-11-30 13:46:48 +03:00
|
|
|
}
|
2014-09-09 09:22:22 +04:00
|
|
|
|
|
|
|
nsAutoCString host, newHost;
|
2016-05-19 11:04:46 +03:00
|
|
|
rv = probe->GetHost(host);
|
2014-09-09 09:22:22 +04:00
|
|
|
NS_ENSURE_SUCCESS(rv, false);
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2014-09-09 09:22:22 +04:00
|
|
|
rv = tldService->GetNextSubDomain(host, newHost);
|
|
|
|
if (rv == NS_ERROR_INSUFFICIENT_DOMAIN_LEVELS) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
NS_ENSURE_SUCCESS(rv, false);
|
2018-02-26 22:43:47 +03:00
|
|
|
rv = NS_MutateURI(probe).SetHost(newHost).Finalize(probe);
|
2014-09-09 09:22:22 +04:00
|
|
|
NS_ENSURE_SUCCESS(rv, false);
|
2018-11-30 13:46:48 +03:00
|
|
|
}
|
2014-09-09 09:22:22 +04:00
|
|
|
}
|
|
|
|
|
2004-04-25 20:55:27 +04:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsScriptSecurityManager::CheckLoadURIWithPrincipal(nsIPrincipal* aPrincipal,
|
|
|
|
nsIURI* aTargetURI,
|
2012-08-22 19:56:38 +04:00
|
|
|
uint32_t aFlags) {
|
2018-04-28 22:50:58 +03:00
|
|
|
MOZ_ASSERT(aPrincipal, "CheckLoadURIWithPrincipal must have a principal");
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2005-05-12 22:20:07 +04:00
|
|
|
// If someone passes a flag that we don't understand, we should
|
|
|
|
// fail, because they may need a security check that we don't
|
|
|
|
// provide.
|
2006-11-11 02:49:08 +03:00
|
|
|
NS_ENSURE_FALSE(
|
|
|
|
aFlags &
|
|
|
|
~(nsIScriptSecurityManager::LOAD_IS_AUTOMATIC_DOCUMENT_REPLACEMENT |
|
2005-05-12 22:20:07 +04:00
|
|
|
nsIScriptSecurityManager::ALLOW_CHROME |
|
|
|
|
nsIScriptSecurityManager::DISALLOW_SCRIPT |
|
2012-09-13 18:16:17 +04:00
|
|
|
nsIScriptSecurityManager::DISALLOW_INHERIT_PRINCIPAL |
|
|
|
|
nsIScriptSecurityManager::DONT_REPORT_ERRORS),
|
2005-05-12 22:20:07 +04:00
|
|
|
NS_ERROR_UNEXPECTED);
|
2004-04-25 20:55:27 +04:00
|
|
|
NS_ENSURE_ARG_POINTER(aPrincipal);
|
2009-01-02 02:45:23 +03:00
|
|
|
NS_ENSURE_ARG_POINTER(aTargetURI);
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2012-03-14 22:55:47 +04:00
|
|
|
// If DISALLOW_INHERIT_PRINCIPAL is set, we prevent loading of URIs which
|
|
|
|
// would do such inheriting. That would be URIs that do not have their own
|
|
|
|
// security context. We do this even for the system principal.
|
|
|
|
if (aFlags & nsIScriptSecurityManager::DISALLOW_INHERIT_PRINCIPAL) {
|
|
|
|
nsresult rv = DenyAccessIfURIHasFlags(
|
|
|
|
aTargetURI, nsIProtocolHandler::URI_INHERITS_SECURITY_CONTEXT);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
}
|
|
|
|
|
2004-04-25 20:55:27 +04:00
|
|
|
if (aPrincipal == mSystemPrincipal) {
|
|
|
|
// Allow access
|
|
|
|
return NS_OK;
|
|
|
|
}
|
2012-03-14 22:55:47 +04:00
|
|
|
|
2004-04-25 20:55:27 +04:00
|
|
|
nsCOMPtr<nsIURI> sourceURI;
|
|
|
|
aPrincipal->GetURI(getter_AddRefs(sourceURI));
|
2007-08-07 06:09:16 +04:00
|
|
|
if (!sourceURI) {
|
2017-10-11 01:00:16 +03:00
|
|
|
auto* basePrin = BasePrincipal::Cast(aPrincipal);
|
|
|
|
if (basePrin->Is<ExpandedPrincipal>()) {
|
|
|
|
auto expanded = basePrin->As<ExpandedPrincipal>();
|
2018-10-31 20:56:43 +03:00
|
|
|
for (auto& prin : expanded->AllowList()) {
|
2017-10-11 01:00:16 +03:00
|
|
|
nsresult rv = CheckLoadURIWithPrincipal(prin, aTargetURI, aFlags);
|
2012-06-11 03:44:50 +04:00
|
|
|
if (NS_SUCCEEDED(rv)) {
|
2018-10-31 20:56:43 +03:00
|
|
|
// Allow access if it succeeded with one of the allowlisted principals
|
2012-06-11 03:44:50 +04:00
|
|
|
return NS_OK;
|
|
|
|
}
|
2018-11-30 13:46:48 +03:00
|
|
|
}
|
2012-06-11 03:44:50 +04:00
|
|
|
// None of our allowlisted principals worked.
|
2007-08-07 06:09:16 +04:00
|
|
|
return NS_ERROR_DOM_BAD_URI;
|
|
|
|
}
|
2018-11-30 13:46:48 +03:00
|
|
|
NS_ERROR(
|
2012-06-11 03:44:50 +04:00
|
|
|
"Non-system principals or expanded principal passed to "
|
2006-11-11 02:49:08 +03:00
|
|
|
"CheckLoadURIWithPrincipal "
|
2007-08-07 06:09:16 +04:00
|
|
|
"must have a URI!");
|
2014-01-17 03:45:40 +04:00
|
|
|
return NS_ERROR_UNEXPECTED;
|
2018-11-30 13:46:48 +03:00
|
|
|
}
|
2016-02-05 04:42:44 +03:00
|
|
|
|
2006-11-11 02:49:08 +03:00
|
|
|
// Automatic loads are not allowed from certain protocols.
|
|
|
|
if (aFlags &
|
|
|
|
nsIScriptSecurityManager::LOAD_IS_AUTOMATIC_DOCUMENT_REPLACEMENT) {
|
|
|
|
nsresult rv = DenyAccessIfURIHasFlags(
|
|
|
|
sourceURI,
|
|
|
|
nsIProtocolHandler::URI_FORBIDS_AUTOMATIC_DOCUMENT_REPLACEMENT);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
}
|
2001-04-17 05:21:44 +04:00
|
|
|
|
2006-11-11 02:49:08 +03:00
|
|
|
// If either URI is a nested URI, get the base URI
|
|
|
|
nsCOMPtr<nsIURI> sourceBaseURI = NS_GetInnermostURI(sourceURI);
|
|
|
|
nsCOMPtr<nsIURI> targetBaseURI = NS_GetInnermostURI(aTargetURI);
|
|
|
|
|
2001-08-03 00:32:48 +04:00
|
|
|
//-- get the target scheme
|
2012-09-02 06:35:17 +04:00
|
|
|
nsAutoCString targetScheme;
|
2006-11-11 02:49:08 +03:00
|
|
|
nsresult rv = targetBaseURI->GetScheme(targetScheme);
|
2001-08-03 00:32:48 +04:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
2001-07-31 23:05:34 +04:00
|
|
|
|
2006-11-11 02:49:08 +03:00
|
|
|
//-- Some callers do not allow loading javascript:
|
|
|
|
if ((aFlags & nsIScriptSecurityManager::DISALLOW_SCRIPT) &&
|
|
|
|
targetScheme.EqualsLiteral("javascript")) {
|
2003-05-30 01:51:34 +04:00
|
|
|
return NS_ERROR_DOM_BAD_URI;
|
|
|
|
}
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2010-03-03 10:51:09 +03:00
|
|
|
// Check for uris that are only loadable by principals that subsume them
|
2011-09-29 10:19:26 +04:00
|
|
|
bool hasFlags;
|
2010-03-03 10:51:09 +03:00
|
|
|
rv = NS_URIChainHasFlags(
|
2016-11-09 21:25:11 +03:00
|
|
|
targetBaseURI, nsIProtocolHandler::URI_LOADABLE_BY_SUBSUMERS, &hasFlags);
|
2010-03-03 10:51:09 +03:00
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
2003-05-30 01:51:34 +04:00
|
|
|
|
2010-03-03 10:51:09 +03:00
|
|
|
if (hasFlags) {
|
|
|
|
// check nothing else in the URI chain has flags that prevent
|
|
|
|
// access:
|
|
|
|
rv = CheckLoadURIFlags(
|
|
|
|
sourceURI, aTargetURI, sourceBaseURI, targetBaseURI, aFlags,
|
|
|
|
aPrincipal->OriginAttributesRef().mPrivateBrowsingId > 0);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
2016-07-13 14:05:22 +03:00
|
|
|
// Check the principal is allowed to load the target.
|
2012-08-20 22:34:33 +04:00
|
|
|
return aPrincipal->CheckMayLoad(targetBaseURI, true, false);
|
2018-11-30 13:46:48 +03:00
|
|
|
}
|
2010-03-03 10:51:09 +03:00
|
|
|
|
2016-07-13 14:05:22 +03:00
|
|
|
//-- get the source scheme
|
|
|
|
nsAutoCString sourceScheme;
|
|
|
|
rv = sourceBaseURI->GetScheme(sourceScheme);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2007-01-26 07:33:02 +03:00
|
|
|
if (sourceScheme.LowerCaseEqualsLiteral(NS_NULLPRINCIPAL_SCHEME)) {
|
2015-12-11 16:06:41 +03:00
|
|
|
// A null principal can target its own URI.
|
|
|
|
if (sourceURI == aTargetURI) {
|
|
|
|
return NS_OK;
|
|
|
|
}
|
2019-08-15 08:29:35 +03:00
|
|
|
} else if (StaticPrefs::
|
|
|
|
security_view_source_reachable_from_inner_protocol() &&
|
2016-09-27 15:31:53 +03:00
|
|
|
sourceScheme.EqualsIgnoreCase(targetScheme.get()) &&
|
2019-08-07 22:49:40 +03:00
|
|
|
aTargetURI->SchemeIs("view-source")) {
|
2016-09-27 15:31:53 +03:00
|
|
|
// exception for foo: linking to view-source:foo for reftests...
|
2008-03-28 06:46:15 +03:00
|
|
|
return NS_OK;
|
2017-11-23 00:31:41 +03:00
|
|
|
} else if (sourceScheme.EqualsIgnoreCase("file") &&
|
|
|
|
targetScheme.EqualsIgnoreCase("moz-icon")) {
|
|
|
|
// exception for file: linking to moz-icon://.ext?size=...
|
|
|
|
// Note that because targetScheme is the base (innermost) URI scheme,
|
|
|
|
// this does NOT allow file -> moz-icon:file:///... links.
|
|
|
|
// This is intentional.
|
2008-03-28 06:46:15 +03:00
|
|
|
return NS_OK;
|
2018-11-30 13:46:48 +03:00
|
|
|
}
|
|
|
|
|
2017-06-20 22:23:49 +03:00
|
|
|
// Check for webextension
|
|
|
|
rv = NS_URIChainHasFlags(
|
2016-11-09 21:25:11 +03:00
|
|
|
aTargetURI, nsIProtocolHandler::URI_LOADABLE_BY_EXTENSIONS, &hasFlags);
|
2010-03-03 10:51:09 +03:00
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
2015-12-11 16:06:41 +03:00
|
|
|
|
|
|
|
if (hasFlags && BasePrincipal::Cast(aPrincipal)->AddonPolicy()) {
|
|
|
|
return NS_OK;
|
2018-11-30 13:46:48 +03:00
|
|
|
}
|
2015-12-11 16:06:41 +03:00
|
|
|
|
2008-03-28 06:46:15 +03:00
|
|
|
// If we get here, check all the schemes can link to each other, from the top
|
|
|
|
// down:
|
|
|
|
nsCaseInsensitiveCStringComparator stringComparator;
|
|
|
|
nsCOMPtr<nsIURI> currentURI = sourceURI;
|
2016-09-27 15:31:53 +03:00
|
|
|
nsCOMPtr<nsIURI> currentOtherURI = aTargetURI;
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2016-11-09 21:25:11 +03:00
|
|
|
bool denySameSchemeLinks = false;
|
2008-03-28 06:46:15 +03:00
|
|
|
rv = NS_URIChainHasFlags(aTargetURI,
|
|
|
|
nsIProtocolHandler::URI_SCHEME_NOT_SELF_LINKABLE,
|
2016-11-09 21:25:11 +03:00
|
|
|
&denySameSchemeLinks);
|
2008-03-28 06:46:15 +03:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2016-09-27 15:31:53 +03:00
|
|
|
while (currentURI && currentOtherURI) {
|
|
|
|
nsAutoCString scheme, otherScheme;
|
2008-03-28 06:46:15 +03:00
|
|
|
currentURI->GetScheme(scheme);
|
2016-09-27 15:31:53 +03:00
|
|
|
currentOtherURI->GetScheme(otherScheme);
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2016-11-23 21:26:44 +03:00
|
|
|
bool schemesMatch = scheme.Equals(otherScheme, stringComparator);
|
2017-02-02 18:10:11 +03:00
|
|
|
bool isSamePage = false;
|
2008-03-28 06:46:15 +03:00
|
|
|
// about: URIs are special snowflakes.
|
|
|
|
if (scheme.EqualsLiteral("about") && schemesMatch) {
|
|
|
|
nsAutoCString moduleName, otherModuleName;
|
|
|
|
// about: pages can always link to themselves:
|
|
|
|
isSamePage =
|
2017-02-02 18:10:11 +03:00
|
|
|
NS_SUCCEEDED(NS_GetAboutModuleName(currentURI, moduleName)) &&
|
2016-09-27 15:31:53 +03:00
|
|
|
NS_SUCCEEDED(
|
2008-03-28 06:46:15 +03:00
|
|
|
NS_GetAboutModuleName(currentOtherURI, otherModuleName)) &&
|
2017-02-02 18:10:11 +03:00
|
|
|
moduleName.Equals(otherModuleName);
|
|
|
|
if (!isSamePage) {
|
2008-03-28 06:46:15 +03:00
|
|
|
// We will have allowed the load earlier if the source page has
|
|
|
|
// system principal. So we know the source has a content
|
2017-02-02 18:10:11 +03:00
|
|
|
// principal, and it's trying to link to something else.
|
2008-03-28 06:46:15 +03:00
|
|
|
// Linkable about: pages are always reachable, even if we hit
|
|
|
|
// the CheckLoadURIFlags call below.
|
|
|
|
// We punch only 1 other hole: iff the source is unlinkable,
|
|
|
|
// we let them link to other pages explicitly marked SAFE
|
2017-02-02 18:10:11 +03:00
|
|
|
// for content. This avoids world-linkable about: pages linking
|
|
|
|
// to non-world-linkable about: pages.
|
|
|
|
nsCOMPtr<nsIAboutModule> module, otherModule;
|
|
|
|
bool knowBothModules =
|
2016-09-27 15:31:53 +03:00
|
|
|
NS_SUCCEEDED(
|
2008-03-28 06:46:15 +03:00
|
|
|
NS_GetAboutModule(currentURI, getter_AddRefs(module))) &&
|
2017-02-02 18:10:11 +03:00
|
|
|
NS_SUCCEEDED(NS_GetAboutModule(currentOtherURI,
|
|
|
|
getter_AddRefs(otherModule)));
|
2008-03-28 06:46:15 +03:00
|
|
|
uint32_t aboutModuleFlags = 0;
|
2017-02-02 18:10:11 +03:00
|
|
|
uint32_t otherAboutModuleFlags = 0;
|
|
|
|
knowBothModules =
|
|
|
|
knowBothModules &&
|
2008-03-28 06:46:15 +03:00
|
|
|
NS_SUCCEEDED(module->GetURIFlags(currentURI, &aboutModuleFlags)) &&
|
2017-02-02 18:10:11 +03:00
|
|
|
NS_SUCCEEDED(otherModule->GetURIFlags(currentOtherURI,
|
|
|
|
&otherAboutModuleFlags));
|
2008-03-28 06:46:15 +03:00
|
|
|
if (knowBothModules) {
|
2017-02-02 18:10:11 +03:00
|
|
|
isSamePage = !(aboutModuleFlags & nsIAboutModule::MAKE_LINKABLE) &&
|
|
|
|
(otherAboutModuleFlags &
|
|
|
|
nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT);
|
|
|
|
if (isSamePage &&
|
|
|
|
otherAboutModuleFlags & nsIAboutModule::MAKE_LINKABLE) {
|
2008-03-28 06:46:15 +03:00
|
|
|
// XXXgijs: this is a hack. The target will be nested
|
|
|
|
// (with innerURI of moz-safe-about:whatever), and
|
2017-02-02 18:10:11 +03:00
|
|
|
// the source isn't, so we won't pass if we finish
|
|
|
|
// the loop. We *should* pass, though, so return here.
|
|
|
|
// This hack can go away when bug 1228118 is fixed.
|
2008-03-28 06:46:15 +03:00
|
|
|
return NS_OK;
|
2018-11-30 13:46:48 +03:00
|
|
|
}
|
2008-03-28 06:46:15 +03:00
|
|
|
}
|
|
|
|
}
|
2016-09-27 15:31:53 +03:00
|
|
|
} else {
|
|
|
|
bool equalExceptRef = false;
|
|
|
|
rv = currentURI->EqualsExceptRef(currentOtherURI, &equalExceptRef);
|
2017-11-23 00:31:41 +03:00
|
|
|
isSamePage = NS_SUCCEEDED(rv) && equalExceptRef;
|
|
|
|
}
|
2012-09-25 23:33:01 +04:00
|
|
|
|
2017-06-20 22:23:49 +03:00
|
|
|
// If schemes are not equal, or they're equal but the target URI
|
2016-11-09 21:25:11 +03:00
|
|
|
// is different from the source URI and doesn't always allow linking
|
2017-06-20 22:23:49 +03:00
|
|
|
// from the same scheme, check if the URI flags of the current target
|
2016-11-09 21:25:11 +03:00
|
|
|
// URI allow the current source URI to link to it.
|
2017-06-20 22:23:49 +03:00
|
|
|
// The policy is specified by the protocol flags on both URIs.
|
|
|
|
if (!schemesMatch || (denySameSchemeLinks && !isSamePage)) {
|
|
|
|
return CheckLoadURIFlags(
|
|
|
|
currentURI, currentOtherURI, sourceBaseURI, targetBaseURI, aFlags,
|
|
|
|
aPrincipal->OriginAttributesRef().mPrivateBrowsingId > 0);
|
2018-11-30 13:46:48 +03:00
|
|
|
}
|
2017-06-20 22:23:49 +03:00
|
|
|
// Otherwise... check if we can nest another level:
|
|
|
|
nsCOMPtr<nsINestedURI> nestedURI = do_QueryInterface(currentURI);
|
|
|
|
nsCOMPtr<nsINestedURI> nestedOtherURI = do_QueryInterface(currentOtherURI);
|
|
|
|
|
2017-09-05 21:04:43 +03:00
|
|
|
// If schemes match and neither URI is nested further, we're OK.
|
|
|
|
if (!nestedURI && !nestedOtherURI) {
|
|
|
|
return NS_OK;
|
2017-06-20 22:23:49 +03:00
|
|
|
}
|
2016-09-27 15:31:53 +03:00
|
|
|
// If one is nested and the other isn't, something is wrong.
|
2017-02-02 18:10:11 +03:00
|
|
|
if (!nestedURI != !nestedOtherURI) {
|
2016-09-27 15:31:53 +03:00
|
|
|
return NS_ERROR_DOM_BAD_URI;
|
2006-03-15 14:03:25 +03:00
|
|
|
}
|
2016-09-27 15:31:53 +03:00
|
|
|
// Otherwise, both should be nested and we'll go through the loop again.
|
|
|
|
nestedURI->GetInnerURI(getter_AddRefs(currentURI));
|
|
|
|
nestedOtherURI->GetInnerURI(getter_AddRefs(currentOtherURI));
|
2018-11-30 13:46:48 +03:00
|
|
|
}
|
2006-03-15 14:03:25 +03:00
|
|
|
|
2016-09-27 15:31:53 +03:00
|
|
|
// We should never get here. We should always return from inside the loop.
|
|
|
|
return NS_ERROR_DOM_BAD_URI;
|
2016-07-13 14:05:22 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Helper method to check whether the target URI and its innermost ("base") URI
|
|
|
|
* has protocol flags that should stop it from being loaded by the source URI
|
|
|
|
* (and/or the source URI's innermost ("base") URI), taking into account any
|
|
|
|
* nsIScriptSecurityManager flags originally passed to
|
|
|
|
* CheckLoadURIWithPrincipal and friends.
|
|
|
|
*
|
|
|
|
* @return if success, access is allowed. Otherwise, deny access
|
|
|
|
*/
|
|
|
|
nsresult nsScriptSecurityManager::CheckLoadURIFlags(
|
|
|
|
nsIURI* aSourceURI, nsIURI* aTargetURI, nsIURI* aSourceBaseURI,
|
2018-09-25 08:25:05 +03:00
|
|
|
nsIURI* aTargetBaseURI, uint32_t aFlags, bool aFromPrivateWindow) {
|
2016-07-13 14:05:22 +03:00
|
|
|
// Note that the order of policy checks here is very important!
|
|
|
|
// We start from most restrictive and work our way down.
|
|
|
|
bool reportErrors = !(aFlags & nsIScriptSecurityManager::DONT_REPORT_ERRORS);
|
2017-07-12 08:13:37 +03:00
|
|
|
const char* errorTag = "CheckLoadURIError";
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2016-07-13 14:05:22 +03:00
|
|
|
nsAutoCString targetScheme;
|
|
|
|
nsresult rv = aTargetBaseURI->GetScheme(targetScheme);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2006-11-11 02:49:08 +03:00
|
|
|
// Check for system target URI
|
2015-12-11 16:06:41 +03:00
|
|
|
rv = DenyAccessIfURIHasFlags(aTargetURI,
|
2006-11-11 02:49:08 +03:00
|
|
|
nsIProtocolHandler::URI_DANGEROUS_TO_LOAD);
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
// Deny access, since the origin principal is not system
|
2012-09-13 18:16:17 +04:00
|
|
|
if (reportErrors) {
|
2018-09-25 08:25:05 +03:00
|
|
|
ReportError(errorTag, aSourceURI, aTargetURI, aFromPrivateWindow);
|
2006-11-11 02:49:08 +03:00
|
|
|
}
|
2016-11-09 21:25:11 +03:00
|
|
|
return rv;
|
2018-11-30 13:46:48 +03:00
|
|
|
}
|
2005-09-09 22:43:45 +04:00
|
|
|
|
2019-01-29 18:40:09 +03:00
|
|
|
// Used by ExtensionProtocolHandler to prevent loading extension resources
|
|
|
|
// in private contexts if the extension does not have permission.
|
|
|
|
if (aFromPrivateWindow) {
|
|
|
|
rv = DenyAccessIfURIHasFlags(
|
|
|
|
aTargetURI, nsIProtocolHandler::URI_DISALLOW_IN_PRIVATE_CONTEXT);
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
if (reportErrors) {
|
|
|
|
ReportError(errorTag, aSourceURI, aTargetURI, aFromPrivateWindow);
|
|
|
|
}
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-11-11 02:49:08 +03:00
|
|
|
// Check for chrome target URI
|
2016-07-13 14:05:22 +03:00
|
|
|
bool hasFlags = false;
|
2006-11-11 02:49:08 +03:00
|
|
|
rv = NS_URIChainHasFlags(aTargetURI, nsIProtocolHandler::URI_IS_UI_RESOURCE,
|
|
|
|
&hasFlags);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
if (hasFlags) {
|
2015-03-20 01:58:44 +03:00
|
|
|
if (aFlags & nsIScriptSecurityManager::ALLOW_CHROME) {
|
|
|
|
// Allow a URI_IS_UI_RESOURCE source to link to a URI_IS_UI_RESOURCE
|
2017-06-08 12:44:09 +03:00
|
|
|
// target if ALLOW_CHROME is set.
|
|
|
|
//
|
|
|
|
// ALLOW_CHROME is a flag that we pass on all loads _except_ docshell
|
|
|
|
// loads (since docshell loads run the loaded content with its origin
|
|
|
|
// principal). So we're effectively allowing resource://, chrome://,
|
|
|
|
// and moz-icon:// source URIs to load resource://, chrome://, and
|
|
|
|
// moz-icon:// files, so long as they're not loading it as a document.
|
|
|
|
bool sourceIsUIResource;
|
|
|
|
rv = NS_URIChainHasFlags(aSourceBaseURI,
|
|
|
|
nsIProtocolHandler::URI_IS_UI_RESOURCE,
|
|
|
|
&sourceIsUIResource);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
if (sourceIsUIResource) {
|
|
|
|
return NS_OK;
|
2008-04-13 01:26:19 +04:00
|
|
|
}
|
2005-09-09 22:43:45 +04:00
|
|
|
|
2012-09-13 18:16:17 +04:00
|
|
|
if (targetScheme.EqualsLiteral("resource")) {
|
2019-08-01 09:01:40 +03:00
|
|
|
if (StaticPrefs::security_all_resource_uri_content_accessible()) {
|
2017-07-19 11:37:25 +03:00
|
|
|
return NS_OK;
|
2014-05-09 20:59:22 +04:00
|
|
|
}
|
|
|
|
|
2016-07-13 14:05:22 +03:00
|
|
|
nsCOMPtr<nsIProtocolHandler> ph;
|
|
|
|
rv = sIOService->GetProtocolHandler("resource", getter_AddRefs(ph));
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
if (!ph) {
|
2006-11-11 02:49:08 +03:00
|
|
|
return NS_ERROR_DOM_BAD_URI;
|
|
|
|
}
|
|
|
|
|
2018-09-25 08:25:05 +03:00
|
|
|
nsCOMPtr<nsIResProtocolHandler> rph = do_QueryInterface(ph);
|
2017-06-08 12:44:09 +03:00
|
|
|
if (!rph) {
|
2018-09-25 08:25:05 +03:00
|
|
|
return NS_ERROR_DOM_BAD_URI;
|
2012-09-13 18:16:17 +04:00
|
|
|
}
|
2000-03-11 09:32:42 +03:00
|
|
|
|
2016-07-13 14:05:22 +03:00
|
|
|
bool accessAllowed = false;
|
|
|
|
rph->AllowContentToAccess(aTargetBaseURI, &accessAllowed);
|
2018-05-08 16:52:53 +03:00
|
|
|
if (accessAllowed) {
|
|
|
|
return NS_OK;
|
2006-11-11 02:49:08 +03:00
|
|
|
}
|
2017-12-21 18:54:43 +03:00
|
|
|
} else if (targetScheme.EqualsLiteral("chrome")) {
|
2018-10-31 20:56:43 +03:00
|
|
|
// Allow the load only if the chrome package is allowlisted.
|
2017-06-08 12:44:09 +03:00
|
|
|
nsCOMPtr<nsIXULChromeRegistry> reg(
|
|
|
|
do_GetService(NS_CHROMEREGISTRY_CONTRACTID));
|
|
|
|
if (reg) {
|
2011-09-29 10:19:26 +04:00
|
|
|
bool accessAllowed = false;
|
2017-06-08 12:44:09 +03:00
|
|
|
reg->AllowContentToAccess(aTargetBaseURI, &accessAllowed);
|
2008-04-13 01:26:19 +04:00
|
|
|
if (accessAllowed) {
|
2015-03-20 01:58:44 +03:00
|
|
|
return NS_OK;
|
2018-11-30 13:46:48 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2006-11-11 02:49:08 +03:00
|
|
|
}
|
2016-02-05 04:42:44 +03:00
|
|
|
|
2012-09-13 18:16:17 +04:00
|
|
|
if (reportErrors) {
|
2018-09-25 08:25:05 +03:00
|
|
|
ReportError(errorTag, aSourceURI, aTargetURI, aFromPrivateWindow);
|
2018-11-30 13:46:48 +03:00
|
|
|
}
|
2000-03-11 09:32:42 +03:00
|
|
|
return NS_ERROR_DOM_BAD_URI;
|
1999-09-01 04:54:35 +04:00
|
|
|
}
|
|
|
|
|
2018-09-25 08:25:05 +03:00
|
|
|
// Check for target URI pointing to a file
|
|
|
|
rv = NS_URIChainHasFlags(aTargetURI, nsIProtocolHandler::URI_IS_LOCAL_FILE,
|
|
|
|
&hasFlags);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
if (hasFlags) {
|
|
|
|
// Allow domains that were allowlisted in the prefs. In 99.9% of cases,
|
|
|
|
// this array is empty.
|
|
|
|
bool isAllowlisted;
|
2002-06-15 03:54:18 +04:00
|
|
|
MOZ_ALWAYS_SUCCEEDS(InFileURIAllowlist(aSourceURI, &isAllowlisted));
|
2018-10-31 20:56:43 +03:00
|
|
|
if (isAllowlisted) {
|
2002-06-15 03:54:18 +04:00
|
|
|
return NS_OK;
|
2018-11-30 13:46:48 +03:00
|
|
|
}
|
2001-04-17 05:21:44 +04:00
|
|
|
|
2002-06-15 03:54:18 +04:00
|
|
|
// Allow chrome://
|
2019-08-07 22:49:40 +03:00
|
|
|
if (aSourceBaseURI->SchemeIs("chrome")) {
|
2002-06-15 03:54:18 +04:00
|
|
|
return NS_OK;
|
2018-11-30 13:46:48 +03:00
|
|
|
}
|
2002-06-15 03:54:18 +04:00
|
|
|
|
|
|
|
// Nothing else.
|
2012-09-13 18:16:17 +04:00
|
|
|
if (reportErrors) {
|
2002-06-15 03:54:18 +04:00
|
|
|
ReportError(errorTag, aSourceURI, aTargetURI, aFromPrivateWindow);
|
2018-11-30 13:46:48 +03:00
|
|
|
}
|
2002-06-15 03:54:18 +04:00
|
|
|
return NS_ERROR_DOM_BAD_URI;
|
2018-11-30 13:46:48 +03:00
|
|
|
}
|
2002-06-15 03:54:18 +04:00
|
|
|
|
2006-11-11 02:49:08 +03:00
|
|
|
// OK, everyone is allowed to load this, since unflagged handlers are
|
|
|
|
// deprecated but treated as URI_LOADABLE_BY_ANYONE. But check whether we
|
|
|
|
// need to warn. At some point we'll want to make this warning into an
|
|
|
|
// error and treat unflagged handlers as URI_DANGEROUS_TO_LOAD.
|
2016-07-13 14:05:22 +03:00
|
|
|
rv = NS_URIChainHasFlags(
|
2016-11-09 21:25:11 +03:00
|
|
|
aTargetBaseURI, nsIProtocolHandler::URI_LOADABLE_BY_ANYONE, &hasFlags);
|
2015-03-20 01:58:44 +03:00
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
2016-07-13 14:05:22 +03:00
|
|
|
// NB: we also get here if the base URI is URI_LOADABLE_BY_SUBSUMERS,
|
|
|
|
// and none of the rest of the nested chain of URIs for aTargetURI
|
|
|
|
// prohibits the load, so avoid warning in that case:
|
2017-02-02 18:10:11 +03:00
|
|
|
bool hasSubsumersFlag = false;
|
2016-07-13 14:05:22 +03:00
|
|
|
rv = NS_URIChainHasFlags(aTargetBaseURI,
|
|
|
|
nsIProtocolHandler::URI_LOADABLE_BY_SUBSUMERS,
|
|
|
|
&hasSubsumersFlag);
|
2006-11-11 02:49:08 +03:00
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
2016-07-13 14:05:22 +03:00
|
|
|
if (!hasFlags && !hasSubsumersFlag) {
|
2018-05-08 16:52:53 +03:00
|
|
|
nsCOMPtr<nsIStringBundle> bundle = BundleHelper::GetOrCreate();
|
|
|
|
if (bundle) {
|
|
|
|
nsAutoString message;
|
2019-06-11 18:51:51 +03:00
|
|
|
AutoTArray<nsString, 1> formatStrings;
|
|
|
|
CopyASCIItoUTF16(targetScheme, *formatStrings.AppendElement());
|
2018-05-08 16:52:53 +03:00
|
|
|
rv = bundle->FormatStringFromName("ProtocolFlagError", formatStrings,
|
2019-06-11 18:51:51 +03:00
|
|
|
message);
|
2018-05-08 16:52:53 +03:00
|
|
|
if (NS_SUCCEEDED(rv)) {
|
|
|
|
nsCOMPtr<nsIConsoleService> console(
|
|
|
|
do_GetService("@mozilla.org/consoleservice;1"));
|
|
|
|
NS_ENSURE_TRUE(console, NS_ERROR_FAILURE);
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2018-05-08 16:52:53 +03:00
|
|
|
console->LogStringMessage(message.get());
|
2018-11-30 13:46:48 +03:00
|
|
|
}
|
2018-05-08 16:52:53 +03:00
|
|
|
}
|
2018-11-30 13:46:48 +03:00
|
|
|
}
|
2018-05-08 16:52:53 +03:00
|
|
|
|
2002-06-15 03:54:18 +04:00
|
|
|
return NS_OK;
|
2018-11-30 13:46:48 +03:00
|
|
|
}
|
2002-06-15 03:54:18 +04:00
|
|
|
|
2018-09-25 08:25:05 +03:00
|
|
|
nsresult nsScriptSecurityManager::ReportError(const char* aMessageTag,
|
|
|
|
nsIURI* aSource, nsIURI* aTarget,
|
|
|
|
bool aFromPrivateWindow) {
|
|
|
|
nsresult rv;
|
|
|
|
NS_ENSURE_TRUE(aSource && aTarget, NS_ERROR_NULL_POINTER);
|
2002-06-15 03:54:18 +04:00
|
|
|
|
2018-09-25 08:25:05 +03:00
|
|
|
// Get the source URL spec
|
|
|
|
nsAutoCString sourceSpec;
|
|
|
|
rv = aSource->GetAsciiSpec(sourceSpec);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2002-06-15 03:54:18 +04:00
|
|
|
// Get the target URL spec
|
2018-09-25 08:25:05 +03:00
|
|
|
nsAutoCString targetSpec;
|
|
|
|
rv = aTarget->GetAsciiSpec(targetSpec);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2018-09-25 08:25:05 +03:00
|
|
|
nsCOMPtr<nsIStringBundle> bundle = BundleHelper::GetOrCreate();
|
2018-05-08 16:52:53 +03:00
|
|
|
if (NS_WARN_IF(!bundle)) {
|
2002-06-15 03:54:18 +04:00
|
|
|
return NS_OK;
|
2018-11-30 13:46:48 +03:00
|
|
|
}
|
|
|
|
|
2002-06-15 03:54:18 +04:00
|
|
|
// Localize the error message
|
2018-05-08 16:52:53 +03:00
|
|
|
nsAutoString message;
|
2019-06-11 18:51:51 +03:00
|
|
|
AutoTArray<nsString, 2> formatStrings;
|
|
|
|
CopyASCIItoUTF16(sourceSpec, *formatStrings.AppendElement());
|
|
|
|
CopyASCIItoUTF16(targetSpec, *formatStrings.AppendElement());
|
|
|
|
rv = bundle->FormatStringFromName(aMessageTag, formatStrings, message);
|
2006-11-11 02:49:08 +03:00
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2018-05-08 16:52:53 +03:00
|
|
|
nsCOMPtr<nsIConsoleService> console(
|
2018-09-25 08:25:05 +03:00
|
|
|
do_GetService(NS_CONSOLESERVICE_CONTRACTID));
|
|
|
|
NS_ENSURE_TRUE(console, NS_ERROR_FAILURE);
|
|
|
|
nsCOMPtr<nsIScriptError> error(do_CreateInstance(NS_SCRIPTERROR_CONTRACTID));
|
|
|
|
NS_ENSURE_TRUE(error, NS_ERROR_FAILURE);
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2018-09-25 08:25:05 +03:00
|
|
|
// using category of "SOP" so we can link to MDN
|
|
|
|
rv = error->Init(message, EmptyString(), EmptyString(), 0, 0,
|
2019-04-02 01:42:34 +03:00
|
|
|
nsIScriptError::errorFlag, "SOP", aFromPrivateWindow,
|
|
|
|
true /* From chrome context */);
|
2016-07-13 14:05:22 +03:00
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
2018-05-08 16:52:53 +03:00
|
|
|
console->LogMessage(error);
|
2008-04-13 01:26:19 +04:00
|
|
|
return NS_OK;
|
2001-04-17 05:21:44 +04:00
|
|
|
}
|
|
|
|
|
2006-08-22 02:15:20 +04:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsScriptSecurityManager::CheckLoadURIStrWithPrincipal(
|
|
|
|
nsIPrincipal* aPrincipal, const nsACString& aTargetURIStr,
|
2012-08-22 19:56:38 +04:00
|
|
|
uint32_t aFlags) {
|
2006-08-22 02:15:20 +04:00
|
|
|
nsresult rv;
|
2001-04-17 05:21:44 +04:00
|
|
|
nsCOMPtr<nsIURI> target;
|
2019-07-15 16:39:51 +03:00
|
|
|
rv = NS_NewURI(getter_AddRefs(target), aTargetURIStr);
|
2016-07-13 14:05:22 +03:00
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2006-08-22 02:15:20 +04:00
|
|
|
rv = CheckLoadURIWithPrincipal(aPrincipal, target, aFlags);
|
2013-10-09 06:32:38 +04:00
|
|
|
if (rv == NS_ERROR_DOM_BAD_URI) {
|
|
|
|
// Don't warn because NS_ERROR_DOM_BAD_URI is one of the expected
|
|
|
|
// return values.
|
|
|
|
return rv;
|
2018-11-30 13:46:48 +03:00
|
|
|
}
|
2016-07-13 14:05:22 +03:00
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2006-04-25 07:24:43 +04:00
|
|
|
// Now start testing fixup -- since aTargetURIStr is a string, not
|
|
|
|
// an nsIURI, we may well end up fixing it up before loading.
|
|
|
|
// Note: This needs to stay in sync with the nsIURIFixup api.
|
2018-12-17 04:27:58 +03:00
|
|
|
nsCOMPtr<nsIURIFixup> fixup = components::URIFixup::Service();
|
2006-04-25 07:24:43 +04:00
|
|
|
if (!fixup) {
|
2013-10-09 06:32:38 +04:00
|
|
|
return rv;
|
2018-11-30 13:46:48 +03:00
|
|
|
}
|
|
|
|
|
2006-04-25 07:24:43 +04:00
|
|
|
uint32_t flags[] = {nsIURIFixup::FIXUP_FLAG_NONE,
|
2014-01-13 00:02:27 +04:00
|
|
|
nsIURIFixup::FIXUP_FLAG_FIX_SCHEME_TYPOS,
|
2012-07-30 18:20:58 +04:00
|
|
|
nsIURIFixup::FIXUP_FLAG_ALLOW_KEYWORD_LOOKUP,
|
2006-04-25 07:24:43 +04:00
|
|
|
nsIURIFixup::FIXUP_FLAGS_MAKE_ALTERNATE_URI,
|
|
|
|
nsIURIFixup::FIXUP_FLAG_ALLOW_KEYWORD_LOOKUP |
|
|
|
|
nsIURIFixup::FIXUP_FLAGS_MAKE_ALTERNATE_URI};
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2012-08-22 19:56:38 +04:00
|
|
|
for (uint32_t i = 0; i < ArrayLength(flags); ++i) {
|
2019-10-12 15:37:51 +03:00
|
|
|
uint32_t fixupFlags = flags[i];
|
|
|
|
if (aPrincipal->OriginAttributesRef().mPrivateBrowsingId > 0) {
|
|
|
|
fixupFlags |= nsIURIFixup::FIXUP_FLAG_PRIVATE_CONTEXT;
|
|
|
|
}
|
|
|
|
rv = fixup->CreateFixupURI(aTargetURIStr, fixupFlags, nullptr,
|
2006-04-25 07:24:43 +04:00
|
|
|
getter_AddRefs(target));
|
2001-04-17 05:21:44 +04:00
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
2006-04-25 07:24:43 +04:00
|
|
|
|
2006-08-22 02:15:20 +04:00
|
|
|
rv = CheckLoadURIWithPrincipal(aPrincipal, target, aFlags);
|
2013-10-09 06:32:38 +04:00
|
|
|
if (rv == NS_ERROR_DOM_BAD_URI) {
|
|
|
|
// Don't warn because NS_ERROR_DOM_BAD_URI is one of the expected
|
|
|
|
// return values.
|
|
|
|
return rv;
|
|
|
|
}
|
2006-04-25 07:24:43 +04:00
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
2018-11-30 13:46:48 +03:00
|
|
|
}
|
2006-04-25 07:24:43 +04:00
|
|
|
|
2013-10-09 06:32:38 +04:00
|
|
|
return rv;
|
2001-04-17 05:21:44 +04:00
|
|
|
}
|
|
|
|
|
2017-07-19 11:37:25 +03:00
|
|
|
NS_IMETHODIMP
|
2018-10-31 20:56:43 +03:00
|
|
|
nsScriptSecurityManager::InFileURIAllowlist(nsIURI* aUri, bool* aResult) {
|
2017-07-19 11:37:25 +03:00
|
|
|
MOZ_ASSERT(aUri);
|
|
|
|
MOZ_ASSERT(aResult);
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2017-07-19 11:37:25 +03:00
|
|
|
*aResult = false;
|
2018-10-31 20:56:43 +03:00
|
|
|
for (nsIURI* uri : EnsureFileURIAllowlist()) {
|
2017-07-19 11:37:25 +03:00
|
|
|
if (EqualOrSubdomain(aUri, uri)) {
|
|
|
|
*aResult = true;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
2018-11-30 13:46:48 +03:00
|
|
|
}
|
2017-07-19 11:37:25 +03:00
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2001-07-31 23:05:34 +04:00
|
|
|
///////////////// Principals ///////////////////////
|
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2001-05-08 20:46:42 +04:00
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsScriptSecurityManager::GetSystemPrincipal(nsIPrincipal** result) {
|
2003-10-22 02:11:49 +04:00
|
|
|
NS_ADDREF(*result = mSystemPrincipal);
|
|
|
|
|
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2001-05-08 20:46:42 +04:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2015-05-15 23:43:11 +03:00
|
|
|
NS_IMETHODIMP
|
2019-07-08 19:37:45 +03:00
|
|
|
nsScriptSecurityManager::CreateContentPrincipal(
|
2015-05-15 23:43:11 +03:00
|
|
|
nsIURI* aURI, JS::Handle<JS::Value> aOriginAttributes, JSContext* aCx,
|
|
|
|
nsIPrincipal** aPrincipal) {
|
2017-01-12 19:38:48 +03:00
|
|
|
OriginAttributes attrs;
|
2015-05-15 23:43:11 +03:00
|
|
|
if (!aOriginAttributes.isObject() || !attrs.Init(aCx, aOriginAttributes)) {
|
|
|
|
return NS_ERROR_INVALID_ARG;
|
|
|
|
}
|
|
|
|
nsCOMPtr<nsIPrincipal> prin =
|
2019-07-08 19:37:45 +03:00
|
|
|
BasePrincipal::CreateContentPrincipal(aURI, attrs);
|
2015-05-15 23:43:11 +03:00
|
|
|
prin.forget(aPrincipal);
|
|
|
|
return *aPrincipal ? NS_OK : NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
|
2015-08-26 14:12:13 +03:00
|
|
|
NS_IMETHODIMP
|
2019-07-08 19:37:45 +03:00
|
|
|
nsScriptSecurityManager::CreateContentPrincipalFromOrigin(
|
2015-08-26 14:12:13 +03:00
|
|
|
const nsACString& aOrigin, nsIPrincipal** aPrincipal) {
|
|
|
|
if (StringBeginsWith(aOrigin, NS_LITERAL_CSTRING("["))) {
|
|
|
|
return NS_ERROR_INVALID_ARG;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (StringBeginsWith(aOrigin,
|
|
|
|
NS_LITERAL_CSTRING(NS_NULLPRINCIPAL_SCHEME ":"))) {
|
|
|
|
return NS_ERROR_INVALID_ARG;
|
|
|
|
}
|
|
|
|
|
2019-07-08 19:37:45 +03:00
|
|
|
nsCOMPtr<nsIPrincipal> prin = BasePrincipal::CreateContentPrincipal(aOrigin);
|
2015-08-26 14:12:13 +03:00
|
|
|
prin.forget(aPrincipal);
|
|
|
|
return *aPrincipal ? NS_OK : NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
|
2019-06-03 15:37:12 +03:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsScriptSecurityManager::PrincipalToJSON(nsIPrincipal* aPrincipal,
|
|
|
|
nsACString& aJSON) {
|
|
|
|
aJSON.Truncate();
|
|
|
|
if (!aPrincipal) {
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
|
|
|
|
BasePrincipal::Cast(aPrincipal)->ToJSON(aJSON);
|
|
|
|
|
|
|
|
if (aJSON.IsEmpty()) {
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsScriptSecurityManager::JSONToPrincipal(const nsACString& aJSON,
|
|
|
|
nsIPrincipal** aPrincipal) {
|
|
|
|
if (aJSON.IsEmpty()) {
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsCOMPtr<nsIPrincipal> principal = BasePrincipal::FromJSON(aJSON);
|
|
|
|
|
|
|
|
if (!principal) {
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
|
|
|
|
principal.forget(aPrincipal);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2015-05-15 23:43:11 +03:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsScriptSecurityManager::CreateNullPrincipal(
|
|
|
|
JS::Handle<JS::Value> aOriginAttributes, JSContext* aCx,
|
|
|
|
nsIPrincipal** aPrincipal) {
|
2017-01-12 19:38:48 +03:00
|
|
|
OriginAttributes attrs;
|
2015-05-15 23:43:11 +03:00
|
|
|
if (!aOriginAttributes.isObject() || !attrs.Init(aCx, aOriginAttributes)) {
|
|
|
|
return NS_ERROR_INVALID_ARG;
|
|
|
|
}
|
2017-03-22 13:38:40 +03:00
|
|
|
nsCOMPtr<nsIPrincipal> prin = NullPrincipal::Create(attrs);
|
2015-05-15 23:43:11 +03:00
|
|
|
prin.forget(aPrincipal);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2014-05-17 02:59:36 +04:00
|
|
|
NS_IMETHODIMP
|
2019-07-08 19:37:45 +03:00
|
|
|
nsScriptSecurityManager::GetLoadContextContentPrincipal(
|
2014-05-17 02:59:36 +04:00
|
|
|
nsIURI* aURI, nsILoadContext* aLoadContext, nsIPrincipal** aPrincipal) {
|
2016-09-29 20:31:50 +03:00
|
|
|
NS_ENSURE_STATE(aLoadContext);
|
2017-01-12 19:38:48 +03:00
|
|
|
OriginAttributes docShellAttrs;
|
2017-03-18 23:08:12 +03:00
|
|
|
aLoadContext->GetOriginAttributes(docShellAttrs);
|
2015-09-23 11:10:21 +03:00
|
|
|
|
2017-03-08 09:41:51 +03:00
|
|
|
nsCOMPtr<nsIPrincipal> prin =
|
2019-07-08 19:37:45 +03:00
|
|
|
BasePrincipal::CreateContentPrincipal(aURI, docShellAttrs);
|
2015-05-15 23:43:11 +03:00
|
|
|
prin.forget(aPrincipal);
|
|
|
|
return *aPrincipal ? NS_OK : NS_ERROR_FAILURE;
|
2014-05-17 02:59:36 +04:00
|
|
|
}
|
|
|
|
|
2012-07-20 11:06:24 +04:00
|
|
|
NS_IMETHODIMP
|
2019-07-08 19:37:45 +03:00
|
|
|
nsScriptSecurityManager::GetDocShellContentPrincipal(
|
2012-07-20 11:06:24 +04:00
|
|
|
nsIURI* aURI, nsIDocShell* aDocShell, nsIPrincipal** aPrincipal) {
|
2019-07-08 19:37:45 +03:00
|
|
|
nsCOMPtr<nsIPrincipal> prin = BasePrincipal::CreateContentPrincipal(
|
2017-03-08 09:41:51 +03:00
|
|
|
aURI, nsDocShell::Cast(aDocShell)->GetOriginAttributes());
|
2015-05-15 23:43:11 +03:00
|
|
|
prin.forget(aPrincipal);
|
|
|
|
return *aPrincipal ? NS_OK : NS_ERROR_FAILURE;
|
1999-08-20 13:51:02 +04:00
|
|
|
}
|
|
|
|
|
2018-12-21 14:56:47 +03:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsScriptSecurityManager::PrincipalWithOA(
|
|
|
|
nsIPrincipal* aPrincipal, JS::Handle<JS::Value> aOriginAttributes,
|
|
|
|
JSContext* aCx, nsIPrincipal** aReturnPrincipal) {
|
|
|
|
if (!aPrincipal) {
|
|
|
|
return NS_OK;
|
|
|
|
}
|
2019-07-08 19:37:45 +03:00
|
|
|
if (aPrincipal->GetIsContentPrincipal()) {
|
2018-12-21 14:56:47 +03:00
|
|
|
OriginAttributes attrs;
|
|
|
|
if (!aOriginAttributes.isObject() || !attrs.Init(aCx, aOriginAttributes)) {
|
|
|
|
return NS_ERROR_INVALID_ARG;
|
|
|
|
}
|
|
|
|
RefPtr<ContentPrincipal> copy = new ContentPrincipal();
|
|
|
|
ContentPrincipal* contentPrincipal =
|
|
|
|
static_cast<ContentPrincipal*>(aPrincipal);
|
|
|
|
nsresult rv = copy->Init(contentPrincipal, attrs);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
copy.forget(aReturnPrincipal);
|
|
|
|
} else {
|
|
|
|
// We do this for null principals, system principals (both fine)
|
|
|
|
// ... and expanded principals, where we should probably do something
|
|
|
|
// cleverer, but I also don't think we care too much.
|
|
|
|
nsCOMPtr<nsIPrincipal> prin = aPrincipal;
|
|
|
|
prin.forget(aReturnPrincipal);
|
|
|
|
}
|
|
|
|
|
|
|
|
return *aReturnPrincipal ? NS_OK : NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
|
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2001-05-08 20:46:42 +04:00
|
|
|
NS_IMETHODIMP
|
2002-02-13 07:20:46 +03:00
|
|
|
nsScriptSecurityManager::CanCreateWrapper(JSContext* cx, const nsIID& aIID,
|
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2001-05-08 20:46:42 +04:00
|
|
|
nsISupports* aObj,
|
2013-12-14 07:15:43 +04:00
|
|
|
nsIClassInfo* aClassInfo) {
|
2018-02-06 00:34:04 +03:00
|
|
|
// XXX Special case for Exception ?
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2018-10-31 20:56:43 +03:00
|
|
|
// We give remote-XUL allowlisted domains a free pass here. See bug 932906.
|
2017-06-28 22:31:53 +03:00
|
|
|
JS::Rooted<JS::Realm*> contextRealm(cx, JS::GetCurrentRealmOrNull(cx));
|
|
|
|
MOZ_RELEASE_ASSERT(contextRealm);
|
2017-10-19 02:11:21 +03:00
|
|
|
if (!xpc::AllowContentXBLScope(contextRealm)) {
|
2013-12-05 07:15:40 +04:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2017-10-19 02:11:21 +03:00
|
|
|
if (nsContentUtils::IsCallerChrome()) {
|
2014-01-17 03:45:40 +04:00
|
|
|
return NS_OK;
|
2003-10-22 02:11:49 +04:00
|
|
|
}
|
|
|
|
|
2014-01-17 03:45:40 +04:00
|
|
|
//-- Access denied, report an error
|
2017-10-18 05:17:26 +03:00
|
|
|
nsAutoCString originUTF8;
|
2014-05-13 13:58:00 +04:00
|
|
|
nsIPrincipal* subjectPrincipal = nsContentUtils::SubjectPrincipal();
|
2017-10-18 05:17:26 +03:00
|
|
|
GetPrincipalDomainOrigin(subjectPrincipal, originUTF8);
|
|
|
|
NS_ConvertUTF8toUTF16 originUTF16(originUTF8);
|
|
|
|
nsAutoCString classInfoNameUTF8;
|
2017-10-19 02:11:21 +03:00
|
|
|
if (aClassInfo) {
|
|
|
|
aClassInfo->GetClassDescription(classInfoNameUTF8);
|
|
|
|
}
|
|
|
|
if (classInfoNameUTF8.IsEmpty()) {
|
|
|
|
classInfoNameUTF8.AssignLiteral("UnnamedClass");
|
|
|
|
}
|
2018-05-08 16:52:53 +03:00
|
|
|
|
|
|
|
nsCOMPtr<nsIStringBundle> bundle = BundleHelper::GetOrCreate();
|
|
|
|
if (NS_WARN_IF(!bundle)) {
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2017-10-18 05:17:26 +03:00
|
|
|
NS_ConvertUTF8toUTF16 classInfoUTF16(classInfoNameUTF8);
|
2017-07-12 08:13:37 +03:00
|
|
|
nsresult rv;
|
2017-08-04 07:40:52 +03:00
|
|
|
nsAutoString errorMsg;
|
2017-10-18 05:17:26 +03:00
|
|
|
if (originUTF16.IsEmpty()) {
|
2019-06-11 18:51:51 +03:00
|
|
|
AutoTArray<nsString, 1> formatStrings = {classInfoUTF16};
|
|
|
|
rv = bundle->FormatStringFromName("CreateWrapperDenied", formatStrings,
|
2018-05-08 16:52:53 +03:00
|
|
|
errorMsg);
|
2014-01-17 03:45:40 +04:00
|
|
|
} else {
|
2019-06-11 18:51:51 +03:00
|
|
|
AutoTArray<nsString, 2> formatStrings = {classInfoUTF16, originUTF16};
|
2018-05-08 16:52:53 +03:00
|
|
|
rv = bundle->FormatStringFromName("CreateWrapperDeniedForOrigin",
|
2019-06-11 18:51:51 +03:00
|
|
|
formatStrings, errorMsg);
|
2014-01-17 03:45:40 +04:00
|
|
|
}
|
2014-05-07 02:43:03 +04:00
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
2014-01-17 03:45:40 +04:00
|
|
|
|
|
|
|
SetPendingException(cx, errorMsg.get());
|
|
|
|
return NS_ERROR_DOM_XPCONNECT_ACCESS_DENIED;
|
1999-11-20 10:28:34 +03:00
|
|
|
}
|
|
|
|
|
2000-05-16 07:40:51 +04:00
|
|
|
NS_IMETHODIMP
|
2002-02-13 07:20:46 +03:00
|
|
|
nsScriptSecurityManager::CanCreateInstance(JSContext* cx, const nsCID& aCID) {
|
2014-05-19 15:39:00 +04:00
|
|
|
if (nsContentUtils::IsCallerChrome()) {
|
2014-01-17 03:45:40 +04:00
|
|
|
return NS_OK;
|
2001-08-14 04:18:58 +04:00
|
|
|
}
|
2014-01-17 03:45:40 +04:00
|
|
|
|
|
|
|
//-- Access denied, report an error
|
|
|
|
nsAutoCString errorMsg("Permission denied to create instance of class. CID=");
|
|
|
|
char cidStr[NSID_LENGTH];
|
|
|
|
aCID.ToProvidedString(cidStr);
|
|
|
|
errorMsg.Append(cidStr);
|
2016-08-15 13:20:01 +03:00
|
|
|
SetPendingExceptionASCII(cx, errorMsg.get());
|
2014-01-17 03:45:40 +04:00
|
|
|
return NS_ERROR_DOM_XPCONNECT_ACCESS_DENIED;
|
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2001-05-08 20:46:42 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2002-02-13 07:20:46 +03:00
|
|
|
nsScriptSecurityManager::CanGetService(JSContext* cx, const nsCID& aCID) {
|
2014-05-19 15:39:00 +04:00
|
|
|
if (nsContentUtils::IsCallerChrome()) {
|
2014-01-17 03:45:40 +04:00
|
|
|
return NS_OK;
|
2001-08-14 04:18:58 +04:00
|
|
|
}
|
2003-10-22 02:11:49 +04:00
|
|
|
|
2014-01-17 03:45:40 +04:00
|
|
|
//-- Access denied, report an error
|
|
|
|
nsAutoCString errorMsg("Permission denied to get service. CID=");
|
|
|
|
char cidStr[NSID_LENGTH];
|
|
|
|
aCID.ToProvidedString(cidStr);
|
|
|
|
errorMsg.Append(cidStr);
|
2016-08-15 13:20:01 +03:00
|
|
|
SetPendingExceptionASCII(cx, errorMsg.get());
|
2014-01-17 03:45:40 +04:00
|
|
|
return NS_ERROR_DOM_XPCONNECT_ACCESS_DENIED;
|
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2001-05-08 20:46:42 +04:00
|
|
|
}
|
|
|
|
|
2011-06-20 07:00:16 +04:00
|
|
|
const char sJSEnabledPrefName[] = "javascript.enabled";
|
|
|
|
const char sFileOriginPolicyPrefName[] =
|
|
|
|
"security.fileuri.strict_origin_policy";
|
2001-10-03 01:56:51 +04:00
|
|
|
|
2011-06-20 07:00:16 +04:00
|
|
|
static const char* kObservedPrefs[] = {sJSEnabledPrefName,
|
|
|
|
sFileOriginPolicyPrefName,
|
2014-05-09 20:59:22 +04:00
|
|
|
"capability.policy.", nullptr};
|
2011-06-20 07:00:16 +04:00
|
|
|
|
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2001-05-08 20:46:42 +04:00
|
|
|
/////////////////////////////////////////////
|
|
|
|
// Constructor, Destructor, Initialization //
|
|
|
|
/////////////////////////////////////////////
|
|
|
|
nsScriptSecurityManager::nsScriptSecurityManager(void)
|
2013-12-14 07:15:43 +04:00
|
|
|
: mPrefInitialized(false), mIsJavaScriptEnabled(false) {
|
2013-07-18 21:59:53 +04:00
|
|
|
static_assert(
|
|
|
|
sizeof(intptr_t) == sizeof(void*),
|
|
|
|
"intptr_t and void* have different lengths on this platform. "
|
|
|
|
"This may cause a security failure with the SecurityLevel union.");
|
2003-01-17 04:00:15 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
nsresult nsScriptSecurityManager::Init() {
|
2010-04-11 17:55:24 +04:00
|
|
|
nsresult rv = CallGetService(NS_IOSERVICE_CONTRACTID, &sIOService);
|
2003-10-22 02:11:49 +04:00
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
2014-09-16 23:30:32 +04:00
|
|
|
InitPrefs();
|
|
|
|
|
2006-04-03 01:10:23 +04:00
|
|
|
// Create our system principal singleton
|
2017-03-22 13:39:08 +03:00
|
|
|
RefPtr<SystemPrincipal> system = SystemPrincipal::Create();
|
2006-04-03 01:10:23 +04:00
|
|
|
|
|
|
|
mSystemPrincipal = system;
|
|
|
|
|
2019-11-22 15:40:17 +03:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
void nsScriptSecurityManager::InitJSCallbacks(JSContext* aCx) {
|
2001-11-16 09:17:24 +03:00
|
|
|
//-- Register security check callback in the JS engine
|
|
|
|
// Currently this is used to control access to function.caller
|
|
|
|
|
2012-03-09 13:48:50 +04:00
|
|
|
static const JSSecurityCallbacks securityCallbacks = {
|
2014-01-03 20:32:56 +04:00
|
|
|
ContentSecurityPolicyPermitsJSAction,
|
|
|
|
JSPrincipalsSubsume,
|
2008-09-06 03:26:04 +04:00
|
|
|
};
|
|
|
|
|
2019-11-22 15:40:17 +03:00
|
|
|
MOZ_ASSERT(!JS_GetSecurityCallbacks(aCx));
|
|
|
|
JS_SetSecurityCallbacks(aCx, &securityCallbacks);
|
|
|
|
JS_InitDestroyPrincipalsCallback(aCx, nsJSPrincipals::Destroy);
|
2001-11-16 09:17:24 +03:00
|
|
|
|
2019-11-22 15:40:17 +03:00
|
|
|
JS_SetTrustedPrincipals(aCx, BasePrincipal::Cast(mSystemPrincipal));
|
|
|
|
}
|
2011-06-30 20:26:56 +04:00
|
|
|
|
2019-11-27 23:57:43 +03:00
|
|
|
/* static */
|
2019-11-22 15:40:17 +03:00
|
|
|
void nsScriptSecurityManager::ClearJSCallbacks(JSContext* aCx) {
|
|
|
|
JS_SetSecurityCallbacks(aCx, nullptr);
|
|
|
|
JS_SetTrustedPrincipals(aCx, nullptr);
|
2000-05-16 07:40:51 +04:00
|
|
|
}
|
|
|
|
|
2012-07-26 23:33:45 +04:00
|
|
|
static StaticRefPtr<nsScriptSecurityManager> gScriptSecMan;
|
2003-01-17 04:00:15 +03:00
|
|
|
|
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2001-05-08 20:46:42 +04:00
|
|
|
nsScriptSecurityManager::~nsScriptSecurityManager(void) {
|
2018-07-06 00:53:14 +03:00
|
|
|
Preferences::UnregisterPrefixCallbacks(
|
2019-11-01 05:57:20 +03:00
|
|
|
nsScriptSecurityManager::ScriptSecurityPrefChanged, kObservedPrefs, this);
|
2015-03-24 17:29:16 +03:00
|
|
|
if (mDomainPolicy) {
|
2013-11-13 04:43:35 +04:00
|
|
|
mDomainPolicy->Deactivate();
|
2015-03-24 17:29:16 +03:00
|
|
|
}
|
|
|
|
// ContentChild might hold a reference to the domain policy,
|
|
|
|
// and it might release it only after the security manager is
|
|
|
|
// gone. But we can still assert this for the main process.
|
2015-07-04 04:29:00 +03:00
|
|
|
MOZ_ASSERT_IF(XRE_IsParentProcess(), !mDomainPolicy);
|
2002-02-13 07:20:46 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void nsScriptSecurityManager::Shutdown() {
|
2003-10-22 02:11:49 +04:00
|
|
|
NS_IF_RELEASE(sIOService);
|
2018-05-08 16:52:53 +03:00
|
|
|
BundleHelper::Shutdown();
|
2001-07-31 23:05:34 +04:00
|
|
|
}
|
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2001-05-08 20:46:42 +04:00
|
|
|
|
|
|
|
nsScriptSecurityManager* nsScriptSecurityManager::GetScriptSecurityManager() {
|
2014-05-07 10:17:43 +04:00
|
|
|
return gScriptSecMan;
|
|
|
|
}
|
2003-01-17 04:00:15 +03:00
|
|
|
|
2019-02-26 01:03:35 +03:00
|
|
|
/* static */
|
|
|
|
void nsScriptSecurityManager::InitStatics() {
|
2015-10-18 08:24:48 +03:00
|
|
|
RefPtr<nsScriptSecurityManager> ssManager = new nsScriptSecurityManager();
|
2014-05-07 10:17:43 +04:00
|
|
|
nsresult rv = ssManager->Init();
|
|
|
|
if (NS_FAILED(rv)) {
|
2016-06-09 06:09:58 +03:00
|
|
|
MOZ_CRASH("ssManager->Init() failed");
|
2000-02-11 07:18:39 +03:00
|
|
|
}
|
2014-05-07 10:17:43 +04:00
|
|
|
|
|
|
|
ClearOnShutdown(&gScriptSecMan);
|
|
|
|
gScriptSecMan = ssManager;
|
1999-10-29 02:09:03 +04:00
|
|
|
}
|
|
|
|
|
2001-08-07 07:59:29 +04:00
|
|
|
// Currently this nsGenericFactory constructor is used only from FastLoad
|
|
|
|
// (XPCOM object deserialization) code, when "creating" the system principal
|
|
|
|
// singleton.
|
2017-10-17 07:08:42 +03:00
|
|
|
already_AddRefed<SystemPrincipal>
|
2001-08-07 07:59:29 +04:00
|
|
|
nsScriptSecurityManager::SystemPrincipalSingletonConstructor() {
|
2003-01-17 04:00:15 +03:00
|
|
|
if (gScriptSecMan)
|
2017-10-26 05:46:50 +03:00
|
|
|
return do_AddRef(gScriptSecMan->mSystemPrincipal)
|
|
|
|
.downcast<SystemPrincipal>();
|
2017-10-17 07:08:42 +03:00
|
|
|
return nullptr;
|
2001-08-07 07:59:29 +04:00
|
|
|
}
|
|
|
|
|
2014-05-09 20:59:22 +04:00
|
|
|
struct IsWhitespace {
|
|
|
|
static bool Test(char aChar) { return NS_IsAsciiWhitespace(aChar); };
|
|
|
|
};
|
|
|
|
struct IsWhitespaceOrComma {
|
|
|
|
static bool Test(char aChar) {
|
|
|
|
return aChar == ',' || NS_IsAsciiWhitespace(aChar);
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
template <typename Predicate>
|
|
|
|
uint32_t SkipPast(const nsCString& str, uint32_t base) {
|
|
|
|
while (base < str.Length() && Predicate::Test(str[base])) {
|
|
|
|
++base;
|
|
|
|
}
|
|
|
|
return base;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename Predicate>
|
|
|
|
uint32_t SkipUntil(const nsCString& str, uint32_t base) {
|
|
|
|
while (base < str.Length() && !Predicate::Test(str[base])) {
|
|
|
|
++base;
|
|
|
|
}
|
|
|
|
return base;
|
|
|
|
}
|
|
|
|
|
2019-11-01 05:57:20 +03:00
|
|
|
// static
|
|
|
|
void nsScriptSecurityManager::ScriptSecurityPrefChanged(const char* aPref,
|
|
|
|
void* aSelf) {
|
|
|
|
static_cast<nsScriptSecurityManager*>(aSelf)->ScriptSecurityPrefChanged(
|
|
|
|
aPref);
|
|
|
|
}
|
|
|
|
|
2018-07-06 00:53:14 +03:00
|
|
|
inline void nsScriptSecurityManager::ScriptSecurityPrefChanged(
|
|
|
|
const char* aPref) {
|
2014-05-09 20:59:22 +04:00
|
|
|
MOZ_ASSERT(mPrefInitialized);
|
2011-06-20 07:00:16 +04:00
|
|
|
mIsJavaScriptEnabled =
|
|
|
|
Preferences::GetBool(sJSEnabledPrefName, mIsJavaScriptEnabled);
|
|
|
|
sStrictFileOriginPolicy =
|
2011-09-29 10:19:26 +04:00
|
|
|
Preferences::GetBool(sFileOriginPolicyPrefName, false);
|
2018-10-31 20:56:43 +03:00
|
|
|
mFileURIAllowlist.reset();
|
2014-05-09 20:59:22 +04:00
|
|
|
}
|
|
|
|
|
2018-10-31 20:56:43 +03:00
|
|
|
void nsScriptSecurityManager::AddSitesToFileURIAllowlist(
|
|
|
|
const nsCString& aSiteList) {
|
2014-05-09 20:59:22 +04:00
|
|
|
for (uint32_t base = SkipPast<IsWhitespace>(aSiteList, 0), bound = 0;
|
|
|
|
base < aSiteList.Length();
|
|
|
|
base = SkipPast<IsWhitespace>(aSiteList, bound)) {
|
|
|
|
// Grab the current site.
|
|
|
|
bound = SkipUntil<IsWhitespace>(aSiteList, base);
|
2014-09-06 07:01:06 +04:00
|
|
|
nsAutoCString site(Substring(aSiteList, base, bound - base));
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2014-09-06 07:01:06 +04:00
|
|
|
// Check if the URI is schemeless. If so, add both http and https.
|
|
|
|
nsAutoCString unused;
|
|
|
|
if (NS_FAILED(sIOService->ExtractScheme(site, unused))) {
|
2018-10-31 20:56:43 +03:00
|
|
|
AddSitesToFileURIAllowlist(NS_LITERAL_CSTRING("http://") + site);
|
|
|
|
AddSitesToFileURIAllowlist(NS_LITERAL_CSTRING("https://") + site);
|
2014-09-09 09:22:21 +04:00
|
|
|
continue;
|
2014-09-06 07:01:06 +04:00
|
|
|
}
|
2014-05-09 20:59:22 +04:00
|
|
|
|
|
|
|
// Convert it to a URI and add it to our list.
|
|
|
|
nsCOMPtr<nsIURI> uri;
|
2019-07-15 16:39:51 +03:00
|
|
|
nsresult rv = NS_NewURI(getter_AddRefs(uri), site);
|
2014-05-09 20:59:22 +04:00
|
|
|
if (NS_SUCCEEDED(rv)) {
|
2018-10-31 20:56:43 +03:00
|
|
|
mFileURIAllowlist.ref().AppendElement(uri);
|
2014-05-09 20:59:22 +04:00
|
|
|
} else {
|
|
|
|
nsCOMPtr<nsIConsoleService> console(
|
|
|
|
do_GetService("@mozilla.org/consoleservice;1"));
|
|
|
|
if (console) {
|
2018-10-31 20:56:43 +03:00
|
|
|
nsAutoString msg =
|
|
|
|
NS_LITERAL_STRING(
|
|
|
|
"Unable to to add site to file:// URI allowlist: ") +
|
2014-05-09 20:59:22 +04:00
|
|
|
NS_ConvertASCIItoUTF16(site);
|
|
|
|
console->LogStringMessage(msg.get());
|
|
|
|
}
|
|
|
|
}
|
2018-11-30 13:46:48 +03:00
|
|
|
}
|
2000-02-10 07:56:56 +03:00
|
|
|
}
|
|
|
|
|
2000-07-26 08:53:01 +04:00
|
|
|
nsresult nsScriptSecurityManager::InitPrefs() {
|
2011-06-20 07:00:16 +04:00
|
|
|
nsIPrefBranch* branch = Preferences::GetRootBranch();
|
|
|
|
NS_ENSURE_TRUE(branch, NS_ERROR_FAILURE);
|
|
|
|
|
2011-10-17 18:59:28 +04:00
|
|
|
mPrefInitialized = true;
|
2000-07-26 08:53:01 +04:00
|
|
|
|
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2001-05-08 20:46:42 +04:00
|
|
|
// Set the initial value of the "javascript.enabled" prefs
|
2007-09-06 11:02:57 +04:00
|
|
|
ScriptSecurityPrefChanged();
|
2011-06-20 07:00:16 +04:00
|
|
|
|
2002-02-13 07:20:46 +03:00
|
|
|
// set observer callbacks in case the value of the prefs change
|
2018-07-06 00:53:14 +03:00
|
|
|
Preferences::RegisterPrefixCallbacks(
|
2019-11-01 05:57:20 +03:00
|
|
|
nsScriptSecurityManager::ScriptSecurityPrefChanged, kObservedPrefs, this);
|
2011-06-20 07:00:16 +04:00
|
|
|
|
1999-11-12 01:10:36 +03:00
|
|
|
return NS_OK;
|
1999-09-15 08:05:43 +04:00
|
|
|
}
|
2002-02-13 07:20:46 +03:00
|
|
|
|
2013-11-13 04:43:35 +04:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsScriptSecurityManager::GetDomainPolicyActive(bool* aRv) {
|
|
|
|
*aRv = !!mDomainPolicy;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsScriptSecurityManager::ActivateDomainPolicy(nsIDomainPolicy** aRv) {
|
2015-07-04 04:29:00 +03:00
|
|
|
if (!XRE_IsParentProcess()) {
|
2015-03-24 17:29:16 +03:00
|
|
|
return NS_ERROR_SERVICE_NOT_AVAILABLE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return ActivateDomainPolicyInternal(aRv);
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsScriptSecurityManager::ActivateDomainPolicyInternal(nsIDomainPolicy** aRv) {
|
2013-11-13 04:43:35 +04:00
|
|
|
// We only allow one domain policy at a time. The holder of the previous
|
|
|
|
// policy must explicitly deactivate it first.
|
|
|
|
if (mDomainPolicy) {
|
|
|
|
return NS_ERROR_SERVICE_NOT_AVAILABLE;
|
|
|
|
}
|
|
|
|
|
2013-12-14 07:15:44 +04:00
|
|
|
mDomainPolicy = new DomainPolicy();
|
2013-11-13 04:43:35 +04:00
|
|
|
nsCOMPtr<nsIDomainPolicy> ptr = mDomainPolicy;
|
|
|
|
ptr.forget(aRv);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Intentionally non-scriptable. Script must have a reference to the
|
|
|
|
// nsIDomainPolicy to deactivate it.
|
|
|
|
void nsScriptSecurityManager::DeactivateDomainPolicy() {
|
|
|
|
mDomainPolicy = nullptr;
|
|
|
|
}
|
|
|
|
|
2015-03-24 17:29:16 +03:00
|
|
|
void nsScriptSecurityManager::CloneDomainPolicy(DomainPolicyClone* aClone) {
|
|
|
|
MOZ_ASSERT(aClone);
|
|
|
|
if (mDomainPolicy) {
|
|
|
|
mDomainPolicy->CloneDomainPolicy(aClone);
|
|
|
|
} else {
|
|
|
|
aClone->active() = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-11-13 04:43:35 +04:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsScriptSecurityManager::PolicyAllowsScript(nsIURI* aURI, bool* aRv) {
|
|
|
|
nsresult rv;
|
|
|
|
|
|
|
|
// Compute our rule. If we don't have any domain policy set up that might
|
2018-10-31 20:56:43 +03:00
|
|
|
// provide exceptions to this rule, we're done.
|
2013-11-13 04:43:35 +04:00
|
|
|
*aRv = mIsJavaScriptEnabled;
|
2018-10-31 20:56:43 +03:00
|
|
|
if (!mDomainPolicy) {
|
|
|
|
return NS_OK;
|
2013-11-13 04:43:35 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
// We have a domain policy. Grab the appropriate set of exceptions to the
|
|
|
|
// rule (either the blocklist or the allowlist, depending on whether script
|
|
|
|
// is enabled or disabled by default).
|
|
|
|
nsCOMPtr<nsIDomainSet> exceptions;
|
|
|
|
nsCOMPtr<nsIDomainSet> superExceptions;
|
|
|
|
if (*aRv) {
|
|
|
|
mDomainPolicy->GetBlocklist(getter_AddRefs(exceptions));
|
|
|
|
mDomainPolicy->GetSuperBlocklist(getter_AddRefs(superExceptions));
|
2018-11-30 13:46:48 +03:00
|
|
|
} else {
|
2013-11-13 04:43:35 +04:00
|
|
|
mDomainPolicy->GetAllowlist(getter_AddRefs(exceptions));
|
|
|
|
mDomainPolicy->GetSuperAllowlist(getter_AddRefs(superExceptions));
|
|
|
|
}
|
|
|
|
|
2017-06-08 12:44:09 +03:00
|
|
|
bool contains;
|
2013-11-13 04:43:35 +04:00
|
|
|
rv = exceptions->Contains(aURI, &contains);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
if (contains) {
|
|
|
|
*aRv = !*aRv;
|
|
|
|
return NS_OK;
|
2018-11-30 13:46:48 +03:00
|
|
|
}
|
2013-11-13 04:43:35 +04:00
|
|
|
rv = superExceptions->ContainsSuperDomain(aURI, &contains);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
if (contains) {
|
|
|
|
*aRv = !*aRv;
|
2018-11-30 13:46:48 +03:00
|
|
|
}
|
|
|
|
|
2013-11-13 04:43:35 +04:00
|
|
|
return NS_OK;
|
|
|
|
}
|
2016-10-03 07:43:17 +03:00
|
|
|
|
|
|
|
const nsTArray<nsCOMPtr<nsIURI>>&
|
2018-10-31 20:56:43 +03:00
|
|
|
nsScriptSecurityManager::EnsureFileURIAllowlist() {
|
|
|
|
if (mFileURIAllowlist.isSome()) {
|
|
|
|
return mFileURIAllowlist.ref();
|
2016-10-03 07:43:17 +03:00
|
|
|
}
|
|
|
|
|
2018-11-30 13:46:48 +03:00
|
|
|
//
|
2016-10-03 07:43:17 +03:00
|
|
|
// Rebuild the set of principals for which we allow file:// URI loads. This
|
|
|
|
// implements a small subset of an old pref-based CAPS people that people
|
|
|
|
// have come to depend on. See bug 995943.
|
2018-11-30 13:46:48 +03:00
|
|
|
//
|
|
|
|
|
2016-10-03 07:43:17 +03:00
|
|
|
mFileURIAllowlist.emplace();
|
|
|
|
nsAutoCString policies;
|
|
|
|
mozilla::Preferences::GetCString("capability.policy.policynames", policies);
|
|
|
|
for (uint32_t base = SkipPast<IsWhitespaceOrComma>(policies, 0), bound = 0;
|
|
|
|
base < policies.Length();
|
|
|
|
base = SkipPast<IsWhitespaceOrComma>(policies, bound)) {
|
|
|
|
// Grab the current policy name.
|
|
|
|
bound = SkipUntil<IsWhitespaceOrComma>(policies, base);
|
|
|
|
auto policyName = Substring(policies, base, bound - base);
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2016-10-03 07:43:17 +03:00
|
|
|
// Figure out if this policy allows loading file:// URIs. If not, we can
|
|
|
|
// skip it.
|
|
|
|
nsCString checkLoadURIPrefName =
|
|
|
|
NS_LITERAL_CSTRING("capability.policy.") + policyName +
|
|
|
|
NS_LITERAL_CSTRING(".checkloaduri.enabled");
|
2017-07-31 07:28:48 +03:00
|
|
|
nsAutoString value;
|
|
|
|
nsresult rv = Preferences::GetString(checkLoadURIPrefName.get(), value);
|
2018-10-31 20:56:43 +03:00
|
|
|
if (NS_FAILED(rv) || !value.LowerCaseEqualsLiteral("allaccess")) {
|
|
|
|
continue;
|
2016-10-03 07:43:17 +03:00
|
|
|
}
|
|
|
|
|
2018-10-31 20:56:43 +03:00
|
|
|
// Grab the list of domains associated with this policy.
|
2016-10-03 07:43:17 +03:00
|
|
|
nsCString domainPrefName = NS_LITERAL_CSTRING("capability.policy.") +
|
|
|
|
policyName + NS_LITERAL_CSTRING(".sites");
|
2012-09-02 06:35:17 +04:00
|
|
|
nsAutoCString siteList;
|
2017-07-31 07:23:50 +03:00
|
|
|
Preferences::GetCString(domainPrefName.get(), siteList);
|
2018-10-31 20:56:43 +03:00
|
|
|
AddSitesToFileURIAllowlist(siteList);
|
2018-11-30 13:46:48 +03:00
|
|
|
}
|
|
|
|
|
2018-10-31 20:56:43 +03:00
|
|
|
return mFileURIAllowlist.ref();
|
2016-10-03 07:43:17 +03:00
|
|
|
}
|