diff --git a/caps/nsScriptSecurityManager.cpp b/caps/nsScriptSecurityManager.cpp index d8239f823c31..4eb993821a7e 100644 --- a/caps/nsScriptSecurityManager.cpp +++ b/caps/nsScriptSecurityManager.cpp @@ -932,6 +932,19 @@ nsresult nsScriptSecurityManager::CheckLoadURIFlags( return rv; } + // 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; + } + } + // Check for chrome target URI bool hasFlags = false; rv = NS_URIChainHasFlags(aTargetURI, nsIProtocolHandler::URI_IS_UI_RESOURCE, diff --git a/netwerk/base/nsIProtocolHandler.idl b/netwerk/base/nsIProtocolHandler.idl index 5ec77bf5b1d1..58a166d2313e 100644 --- a/netwerk/base/nsIProtocolHandler.idl +++ b/netwerk/base/nsIProtocolHandler.idl @@ -330,4 +330,9 @@ interface nsIProtocolHandler : nsISupports * The URIs for this protocol can be loaded by extensions. */ const unsigned long URI_LOADABLE_BY_EXTENSIONS = (1 << 21); + + /** + * The URIs for this protocol can not be loaded into private contexts. + */ + const unsigned long URI_DISALLOW_IN_PRIVATE_CONTEXT = (1 << 22); }; diff --git a/netwerk/protocol/res/ExtensionProtocolHandler.cpp b/netwerk/protocol/res/ExtensionProtocolHandler.cpp index cad78736b89d..7e06d22c1152 100644 --- a/netwerk/protocol/res/ExtensionProtocolHandler.cpp +++ b/netwerk/protocol/res/ExtensionProtocolHandler.cpp @@ -341,20 +341,27 @@ static inline ExtensionPolicyService& EPS() { nsresult ExtensionProtocolHandler::GetFlagsForURI(nsIURI* aURI, uint32_t* aFlags) { - // In general a moz-extension URI is only loadable by chrome, but a - // whitelisted subset are web-accessible (and cross-origin fetchable). Check - // that whitelist. - bool loadableByAnyone = false; + uint32_t flags = + URI_STD | URI_IS_LOCAL_RESOURCE | URI_IS_POTENTIALLY_TRUSTWORTHY; URLInfo url(aURI); if (auto* policy = EPS().GetByURL(url)) { - loadableByAnyone = policy->IsPathWebAccessible(url.FilePath()); + // In general a moz-extension URI is only loadable by chrome, but a + // whitelisted subset are web-accessible (and cross-origin fetchable). Check + // that whitelist. + if (policy->IsPathWebAccessible(url.FilePath())) { + flags |= URI_LOADABLE_BY_ANYONE | URI_FETCHABLE_BY_ANYONE; + } else { + flags |= URI_DANGEROUS_TO_LOAD; + } + + // Disallow in private windows if the extension does not have permission. + if (!policy->PrivateBrowsingAllowed()) { + flags |= URI_DISALLOW_IN_PRIVATE_CONTEXT; + } } - *aFlags = - URI_STD | URI_IS_LOCAL_RESOURCE | URI_IS_POTENTIALLY_TRUSTWORTHY | - (loadableByAnyone ? (URI_LOADABLE_BY_ANYONE | URI_FETCHABLE_BY_ANYONE) - : URI_DANGEROUS_TO_LOAD); + *aFlags = flags; return NS_OK; } diff --git a/toolkit/components/extensions/test/mochitest/mochitest-common.ini b/toolkit/components/extensions/test/mochitest/mochitest-common.ini index 5e1170bdf94c..8f0a0f167206 100644 --- a/toolkit/components/extensions/test/mochitest/mochitest-common.ini +++ b/toolkit/components/extensions/test/mochitest/mochitest-common.ini @@ -122,6 +122,8 @@ skip-if = os == 'android' || verify # bug 1489771 skip-if = os == 'android' [test_ext_web_accessible_resources.html] skip-if = os == 'android' && debug # bug 1397615 +[test_ext_web_accessible_incognito.html] +skip-if = os == 'android' # bug 1397615 and bug 1513544 [test_ext_webnavigation.html] skip-if = os == 'android' && debug # bug 1397615 [test_ext_webnavigation_filters.html] diff --git a/toolkit/components/extensions/test/mochitest/test_ext_web_accessible_incognito.html b/toolkit/components/extensions/test/mochitest/test_ext_web_accessible_incognito.html new file mode 100644 index 000000000000..ad5cae62ac15 --- /dev/null +++ b/toolkit/components/extensions/test/mochitest/test_ext_web_accessible_incognito.html @@ -0,0 +1,175 @@ + + +
+