From 1b4c4256ee7705724b02919b4d432b2a391bcd04 Mon Sep 17 00:00:00 2001 From: janekptacijarabaci Date: Sun, 22 Apr 2018 18:51:38 +0200 Subject: moebius#223: Consider blocking top level window data: URIs (part 1/3 without tests) https://github.com/MoonchildProductions/moebius/pull/223 --- dom/security/nsContentSecurityManager.cpp | 84 ++++++++++++++++++++ dom/security/nsContentSecurityManager.h | 5 ++ dom/security/test/general/browser.ini | 5 ++ .../browser_test_toplevel_data_navigations.js | 54 +++++++++++++ .../file_block_toplevel_data_navigation.html | 14 ++++ .../file_block_toplevel_data_navigation2.html | 29 +++++++ .../file_block_toplevel_data_navigation3.html | 13 ++++ .../general/file_block_toplevel_data_redirect.sjs | 14 ++++ .../general/file_toplevel_data_meta_redirect.html | 10 +++ .../general/file_toplevel_data_navigations.sjs | 14 ++++ dom/security/test/general/mochitest.ini | 12 +++ .../test/general/test_allow_opening_data_json.html | 39 ++++++++++ .../test/general/test_allow_opening_data_pdf.html | 41 ++++++++++ .../test_block_toplevel_data_img_navigation.html | 51 ++++++++++++ .../test_block_toplevel_data_navigation.html | 90 ++++++++++++++++++++++ dom/security/test/moz.build | 1 + 16 files changed, 476 insertions(+) create mode 100644 dom/security/test/general/browser.ini create mode 100644 dom/security/test/general/browser_test_toplevel_data_navigations.js create mode 100644 dom/security/test/general/file_block_toplevel_data_navigation.html create mode 100644 dom/security/test/general/file_block_toplevel_data_navigation2.html create mode 100644 dom/security/test/general/file_block_toplevel_data_navigation3.html create mode 100644 dom/security/test/general/file_block_toplevel_data_redirect.sjs create mode 100644 dom/security/test/general/file_toplevel_data_meta_redirect.html create mode 100644 dom/security/test/general/file_toplevel_data_navigations.sjs create mode 100644 dom/security/test/general/test_allow_opening_data_json.html create mode 100644 dom/security/test/general/test_allow_opening_data_pdf.html create mode 100644 dom/security/test/general/test_block_toplevel_data_img_navigation.html create mode 100644 dom/security/test/general/test_block_toplevel_data_navigation.html (limited to 'dom/security') diff --git a/dom/security/nsContentSecurityManager.cpp b/dom/security/nsContentSecurityManager.cpp index c4e1ed8e1..069e7d6a7 100644 --- a/dom/security/nsContentSecurityManager.cpp +++ b/dom/security/nsContentSecurityManager.cpp @@ -1,13 +1,16 @@ #include "nsContentSecurityManager.h" +#include "nsEscape.h" #include "nsIChannel.h" #include "nsIHttpChannelInternal.h" #include "nsIStreamListener.h" #include "nsILoadInfo.h" +#include "nsIOService.h" #include "nsContentUtils.h" #include "nsCORSListenerProxy.h" #include "nsIStreamListener.h" #include "nsIDocument.h" #include "nsMixedContentBlocker.h" +#include "nsNullPrincipal.h" #include "mozilla/dom/Element.h" @@ -15,6 +18,66 @@ NS_IMPL_ISUPPORTS(nsContentSecurityManager, nsIContentSecurityManager, nsIChannelEventSink) +/* static */ bool +nsContentSecurityManager::AllowTopLevelNavigationToDataURI( + nsIURI* aURI, + nsContentPolicyType aContentPolicyType, + nsIPrincipal* aTriggeringPrincipal, + bool aLoadFromExternal) +{ + // Let's block all toplevel document navigations to a data: URI. + // In all cases where the toplevel document is navigated to a + // data: URI the triggeringPrincipal is a codeBasePrincipal, or + // a NullPrincipal. In other cases, e.g. typing a data: URL into + // the URL-Bar, the triggeringPrincipal is a SystemPrincipal; + // we don't want to block those loads. Only exception, loads coming + // from an external applicaton (e.g. Thunderbird) don't load + // using a codeBasePrincipal, but we want to block those loads. + if (!mozilla::net::nsIOService::BlockToplevelDataUriNavigations()) { + return true; + } + if (aContentPolicyType != nsIContentPolicy::TYPE_DOCUMENT) { + return true; + } + bool isDataURI = + (NS_SUCCEEDED(aURI->SchemeIs("data", &isDataURI)) && isDataURI); + if (!isDataURI) { + return true; + } + // Whitelist data: images as long as they are not SVGs + nsAutoCString filePath; + aURI->GetFilePath(filePath); + if (StringBeginsWith(filePath, NS_LITERAL_CSTRING("image/")) && + !StringBeginsWith(filePath, NS_LITERAL_CSTRING("image/svg+xml"))) { + return true; + } + // Whitelist data: PDFs and JSON + if (StringBeginsWith(filePath, NS_LITERAL_CSTRING("application/pdf")) || + StringBeginsWith(filePath, NS_LITERAL_CSTRING("application/json"))) { + return true; + } + if (!aLoadFromExternal && + nsContentUtils::IsSystemPrincipal(aTriggeringPrincipal)) { + return true; + } + nsAutoCString dataSpec; + aURI->GetSpec(dataSpec); + if (dataSpec.Length() > 50) { + dataSpec.Truncate(50); + dataSpec.AppendLiteral("..."); + } + NS_ConvertUTF8toUTF16 specUTF16(NS_UnescapeURL(dataSpec)); + const char16_t* params[] = { specUTF16.get() }; + nsContentUtils::ReportToConsole(nsIScriptError::warningFlag, + NS_LITERAL_CSTRING("DATA_URI_BLOCKED"), + // no doc available, log to browser console + nullptr, + nsContentUtils::eSECURITY_PROPERTIES, + "BlockTopLevelDataURINavigation", + params, ArrayLength(params)); + return false; +} + static nsresult ValidateSecurityFlags(nsILoadInfo* aLoadInfo) { @@ -478,6 +541,27 @@ nsContentSecurityManager::AsyncOnChannelRedirect(nsIChannel* aOldChannel, } } + // Redirecting to a toplevel data: URI is not allowed, hence we pass + // a NullPrincipal as the TriggeringPrincipal to + // AllowTopLevelNavigationToDataURI() which definitely blocks any + // data: URI load. + nsCOMPtr newLoadInfo = aNewChannel->GetLoadInfo(); + if (newLoadInfo) { + nsCOMPtr uri; + nsresult rv = NS_GetFinalChannelURI(aNewChannel, getter_AddRefs(uri)); + NS_ENSURE_SUCCESS(rv, rv); + nsCOMPtr nullTriggeringPrincipal = nsNullPrincipal::Create(); + if (!nsContentSecurityManager::AllowTopLevelNavigationToDataURI( + uri, + newLoadInfo->GetExternalContentPolicyType(), + nullTriggeringPrincipal, + false)) { + // logging to console happens within AllowTopLevelNavigationToDataURI + aOldChannel->Cancel(NS_ERROR_DOM_BAD_URI); + return NS_ERROR_DOM_BAD_URI; + } + } + // Also verify that the redirecting server is allowed to redirect to the // given URI nsCOMPtr oldPrincipal; diff --git a/dom/security/nsContentSecurityManager.h b/dom/security/nsContentSecurityManager.h index 912c0e89f..09b6c86aa 100644 --- a/dom/security/nsContentSecurityManager.h +++ b/dom/security/nsContentSecurityManager.h @@ -32,6 +32,11 @@ public: static nsresult doContentSecurityCheck(nsIChannel* aChannel, nsCOMPtr& aInAndOutListener); + static bool AllowTopLevelNavigationToDataURI(nsIURI* aURI, + nsContentPolicyType aContentPolicyType, + nsIPrincipal* aTriggeringPrincipal, + bool aLoadFromExternal); + private: static nsresult CheckChannel(nsIChannel* aChannel); diff --git a/dom/security/test/general/browser.ini b/dom/security/test/general/browser.ini new file mode 100644 index 000000000..97ddae3bf --- /dev/null +++ b/dom/security/test/general/browser.ini @@ -0,0 +1,5 @@ +[DEFAULT] +[browser_test_toplevel_data_navigations.js] +support-files = + file_toplevel_data_navigations.sjs + file_toplevel_data_meta_redirect.html diff --git a/dom/security/test/general/browser_test_toplevel_data_navigations.js b/dom/security/test/general/browser_test_toplevel_data_navigations.js new file mode 100644 index 000000000..a13a6350e --- /dev/null +++ b/dom/security/test/general/browser_test_toplevel_data_navigations.js @@ -0,0 +1,54 @@ +/* eslint-disable mozilla/no-arbitrary-setTimeout */ + +"use strict"; + +const kDataBody = "toplevel navigation to data: URI allowed"; +const kDataURI = "data:text/html," + kDataBody + ""; +const kTestPath = getRootDirectory(gTestPath) + .replace("chrome://mochitests/content", "http://example.com") +const kRedirectURI = kTestPath + "file_toplevel_data_navigations.sjs"; +const kMetaRedirectURI = kTestPath + "file_toplevel_data_meta_redirect.html"; + +add_task(async function test_nav_data_uri() { + await SpecialPowers.pushPrefEnv({ + "set": [["security.data_uri.block_toplevel_data_uri_navigations", true]], + }); + await BrowserTestUtils.withNewTab(kDataURI, async function(browser) { + await ContentTask.spawn(gBrowser.selectedBrowser, {kDataBody}, async function({kDataBody}) { // eslint-disable-line + is(content.document.body.innerHTML, kDataBody, + "data: URI navigation from system should be allowed"); + }); + }); +}); + +add_task(async function test_nav_data_uri_redirect() { + await SpecialPowers.pushPrefEnv({ + "set": [["security.data_uri.block_toplevel_data_uri_navigations", true]], + }); + let tab = BrowserTestUtils.addTab(gBrowser, kRedirectURI); + registerCleanupFunction(async function() { + await BrowserTestUtils.removeTab(tab); + }); + // wait to make sure data: URI did not load before checking that it got blocked + await new Promise(resolve => setTimeout(resolve, 500)); + await ContentTask.spawn(gBrowser.selectedBrowser, {}, async function() { + is(content.document.body.innerHTML, "", + "data: URI navigation after server redirect should be blocked"); + }); +}); + +add_task(async function test_nav_data_uri_meta_redirect() { + await SpecialPowers.pushPrefEnv({ + "set": [["security.data_uri.block_toplevel_data_uri_navigations", true]], + }); + let tab = BrowserTestUtils.addTab(gBrowser, kMetaRedirectURI); + registerCleanupFunction(async function() { + await BrowserTestUtils.removeTab(tab); + }); + // wait to make sure data: URI did not load before checking that it got blocked + await new Promise(resolve => setTimeout(resolve, 500)); + await ContentTask.spawn(gBrowser.selectedBrowser, {}, async function() { + is(content.document.body.innerHTML, "", + "data: URI navigation after meta redirect should be blocked"); + }); +}); diff --git a/dom/security/test/general/file_block_toplevel_data_navigation.html b/dom/security/test/general/file_block_toplevel_data_navigation.html new file mode 100644 index 000000000..5fbfdfdef --- /dev/null +++ b/dom/security/test/general/file_block_toplevel_data_navigation.html @@ -0,0 +1,14 @@ + + + + + Toplevel data navigation + + +test1: clicking data: URI tries to navigate window
+click me + + + diff --git a/dom/security/test/general/file_block_toplevel_data_navigation2.html b/dom/security/test/general/file_block_toplevel_data_navigation2.html new file mode 100644 index 000000000..e0308e1ae --- /dev/null +++ b/dom/security/test/general/file_block_toplevel_data_navigation2.html @@ -0,0 +1,29 @@ + + + + + Toplevel data navigation + + +test2: data: URI in iframe tries to window.open(data:, _blank);
+ + + + diff --git a/dom/security/test/general/file_block_toplevel_data_navigation3.html b/dom/security/test/general/file_block_toplevel_data_navigation3.html new file mode 100644 index 000000000..34aeddab3 --- /dev/null +++ b/dom/security/test/general/file_block_toplevel_data_navigation3.html @@ -0,0 +1,13 @@ + + + + + Toplevel data navigation + + +test3: performing data: URI navigation through win.loc.href
+ + + diff --git a/dom/security/test/general/file_block_toplevel_data_redirect.sjs b/dom/security/test/general/file_block_toplevel_data_redirect.sjs new file mode 100644 index 000000000..64e294cab --- /dev/null +++ b/dom/security/test/general/file_block_toplevel_data_redirect.sjs @@ -0,0 +1,14 @@ +// Custom *.sjs file specifically for the needs of Bug: +// Bug 1394554 - Block toplevel data: URI navigations after redirect + +var DATA_URI = + "toplevel data: URI navigations after redirect should be blocked"; + +function handleRequest(request, response) +{ + // avoid confusing cache behaviors + response.setHeader("Cache-Control", "no-cache", false); + + response.setStatusLine("1.1", 302, "Found"); + response.setHeader("Location", "data:text/html," + escape(DATA_URI), false); +} diff --git a/dom/security/test/general/file_toplevel_data_meta_redirect.html b/dom/security/test/general/file_toplevel_data_meta_redirect.html new file mode 100644 index 000000000..f4f5deb52 --- /dev/null +++ b/dom/security/test/general/file_toplevel_data_meta_redirect.html @@ -0,0 +1,10 @@ + + + + + + +Meta Redirect to data: URI + + diff --git a/dom/security/test/general/file_toplevel_data_navigations.sjs b/dom/security/test/general/file_toplevel_data_navigations.sjs new file mode 100644 index 000000000..501b833e5 --- /dev/null +++ b/dom/security/test/general/file_toplevel_data_navigations.sjs @@ -0,0 +1,14 @@ +// Custom *.sjs file specifically for the needs of Bug: +// Bug 1394554 - Block toplevel data: URI navigations after redirect + +var DATA_URI = + "data:text/html,toplevel data: URI navigations after redirect should be blocked"; + +function handleRequest(request, response) +{ + // avoid confusing cache behaviors + response.setHeader("Cache-Control", "no-cache", false); + + response.setStatusLine("1.1", 302, "Found"); + response.setHeader("Location", DATA_URI, false); +} diff --git a/dom/security/test/general/mochitest.ini b/dom/security/test/general/mochitest.ini index 70c0c9fb6..f3bcca072 100644 --- a/dom/security/test/general/mochitest.ini +++ b/dom/security/test/general/mochitest.ini @@ -3,7 +3,19 @@ support-files = file_contentpolicytype_targeted_link_iframe.sjs file_nosniff_testserver.sjs file_block_script_wrong_mime_server.sjs + file_block_toplevel_data_navigation.html + file_block_toplevel_data_navigation2.html + file_block_toplevel_data_navigation3.html + file_block_toplevel_data_redirect.sjs [test_contentpolicytype_targeted_link_iframe.html] [test_nosniff.html] [test_block_script_wrong_mime.html] +[test_block_toplevel_data_navigation.html] +skip-if = toolkit == 'android' # intermittent failure +[test_block_toplevel_data_img_navigation.html] +skip-if = toolkit == 'android' # intermittent failure +[test_allow_opening_data_pdf.html] +skip-if = toolkit == 'android' +[test_allow_opening_data_json.html] +skip-if = toolkit == 'android' diff --git a/dom/security/test/general/test_allow_opening_data_json.html b/dom/security/test/general/test_allow_opening_data_json.html new file mode 100644 index 000000000..1530a24e8 --- /dev/null +++ b/dom/security/test/general/test_allow_opening_data_json.html @@ -0,0 +1,39 @@ + + + + + Bug 1403814: Allow toplevel data URI navigation data:application/json + + + + + + + diff --git a/dom/security/test/general/test_allow_opening_data_pdf.html b/dom/security/test/general/test_allow_opening_data_pdf.html new file mode 100644 index 000000000..6b51fe57b --- /dev/null +++ b/dom/security/test/general/test_allow_opening_data_pdf.html @@ -0,0 +1,41 @@ + + + + + Bug 1398692: Allow toplevel navigation to a data:application/pdf + + + + + + + diff --git a/dom/security/test/general/test_block_toplevel_data_img_navigation.html b/dom/security/test/general/test_block_toplevel_data_img_navigation.html new file mode 100644 index 000000000..2b8f62760 --- /dev/null +++ b/dom/security/test/general/test_block_toplevel_data_img_navigation.html @@ -0,0 +1,51 @@ + + + + + Bug 1396798: Do not block toplevel data: navigation to image (except svgs) + + + + + + + diff --git a/dom/security/test/general/test_block_toplevel_data_navigation.html b/dom/security/test/general/test_block_toplevel_data_navigation.html new file mode 100644 index 000000000..fc91f2ec0 --- /dev/null +++ b/dom/security/test/general/test_block_toplevel_data_navigation.html @@ -0,0 +1,90 @@ + + + + + Bug 1331351 - Block top level window data: URI navigations + + + + + + + + diff --git a/dom/security/test/moz.build b/dom/security/test/moz.build index ddb4e9b89..946959dee 100644 --- a/dom/security/test/moz.build +++ b/dom/security/test/moz.build @@ -27,5 +27,6 @@ MOCHITEST_CHROME_MANIFESTS += [ BROWSER_CHROME_MANIFESTS += [ 'contentverifier/browser.ini', 'csp/browser.ini', + 'general/browser.ini', 'hsts/browser.ini', ] -- cgit v1.2.3 From f1e5578718ea8883438cfea06d3c55d25f5c0278 Mon Sep 17 00:00:00 2001 From: janekptacijarabaci Date: Sun, 22 Apr 2018 19:03:22 +0200 Subject: moebius#226: Consider blocking top level window data: URIs (part 2/2 without tests) https://github.com/MoonchildProductions/moebius/pull/226 --- dom/security/nsContentSecurityManager.cpp | 59 +++++++++------------- dom/security/nsContentSecurityManager.h | 5 +- dom/security/test/general/browser.ini | 6 +++ .../test/general/browser_test_data_download.js | 37 ++++++++++++++ .../test/general/browser_test_data_text_csv.js | 37 ++++++++++++++ dom/security/test/general/file_data_download.html | 14 +++++ dom/security/test/general/file_data_text_csv.html | 14 +++++ .../test_block_toplevel_data_img_navigation.html | 18 ++++--- .../test_block_toplevel_data_navigation.html | 16 +++--- 9 files changed, 149 insertions(+), 57 deletions(-) create mode 100644 dom/security/test/general/browser_test_data_download.js create mode 100644 dom/security/test/general/browser_test_data_text_csv.js create mode 100644 dom/security/test/general/file_data_download.html create mode 100644 dom/security/test/general/file_data_text_csv.html (limited to 'dom/security') diff --git a/dom/security/nsContentSecurityManager.cpp b/dom/security/nsContentSecurityManager.cpp index 069e7d6a7..c987fed67 100644 --- a/dom/security/nsContentSecurityManager.cpp +++ b/dom/security/nsContentSecurityManager.cpp @@ -10,20 +10,16 @@ #include "nsIStreamListener.h" #include "nsIDocument.h" #include "nsMixedContentBlocker.h" -#include "nsNullPrincipal.h" #include "mozilla/dom/Element.h" +#include "mozilla/dom/TabChild.h" NS_IMPL_ISUPPORTS(nsContentSecurityManager, nsIContentSecurityManager, nsIChannelEventSink) /* static */ bool -nsContentSecurityManager::AllowTopLevelNavigationToDataURI( - nsIURI* aURI, - nsContentPolicyType aContentPolicyType, - nsIPrincipal* aTriggeringPrincipal, - bool aLoadFromExternal) +nsContentSecurityManager::AllowTopLevelNavigationToDataURI(nsIChannel* aChannel) { // Let's block all toplevel document navigations to a data: URI. // In all cases where the toplevel document is navigated to a @@ -36,17 +32,24 @@ nsContentSecurityManager::AllowTopLevelNavigationToDataURI( if (!mozilla::net::nsIOService::BlockToplevelDataUriNavigations()) { return true; } - if (aContentPolicyType != nsIContentPolicy::TYPE_DOCUMENT) { + nsCOMPtr loadInfo = aChannel->GetLoadInfo(); + if (!loadInfo) { + return true; + } + if (loadInfo->GetExternalContentPolicyType() != nsIContentPolicy::TYPE_DOCUMENT) { return true; } + nsCOMPtr uri; + nsresult rv = NS_GetFinalChannelURI(aChannel, getter_AddRefs(uri)); + NS_ENSURE_SUCCESS(rv, true); bool isDataURI = - (NS_SUCCEEDED(aURI->SchemeIs("data", &isDataURI)) && isDataURI); + (NS_SUCCEEDED(uri->SchemeIs("data", &isDataURI)) && isDataURI); if (!isDataURI) { return true; } // Whitelist data: images as long as they are not SVGs nsAutoCString filePath; - aURI->GetFilePath(filePath); + uri->GetFilePath(filePath); if (StringBeginsWith(filePath, NS_LITERAL_CSTRING("image/")) && !StringBeginsWith(filePath, NS_LITERAL_CSTRING("image/svg+xml"))) { return true; @@ -56,22 +59,29 @@ nsContentSecurityManager::AllowTopLevelNavigationToDataURI( StringBeginsWith(filePath, NS_LITERAL_CSTRING("application/json"))) { return true; } - if (!aLoadFromExternal && - nsContentUtils::IsSystemPrincipal(aTriggeringPrincipal)) { + // Redirecting to a toplevel data: URI is not allowed, hence we make + // sure the RedirectChain is empty. + if (!loadInfo->GetLoadTriggeredFromExternal() && + nsContentUtils::IsSystemPrincipal(loadInfo->TriggeringPrincipal()) && + loadInfo->RedirectChain().IsEmpty()) { return true; } nsAutoCString dataSpec; - aURI->GetSpec(dataSpec); + uri->GetSpec(dataSpec); if (dataSpec.Length() > 50) { dataSpec.Truncate(50); dataSpec.AppendLiteral("..."); } + nsCOMPtr tabChild = do_QueryInterface(loadInfo->ContextForTopLevelLoad()); + nsCOMPtr doc; + if (tabChild) { + doc = static_cast(tabChild.get())->GetDocument(); + } NS_ConvertUTF8toUTF16 specUTF16(NS_UnescapeURL(dataSpec)); const char16_t* params[] = { specUTF16.get() }; nsContentUtils::ReportToConsole(nsIScriptError::warningFlag, NS_LITERAL_CSTRING("DATA_URI_BLOCKED"), - // no doc available, log to browser console - nullptr, + doc, nsContentUtils::eSECURITY_PROPERTIES, "BlockTopLevelDataURINavigation", params, ArrayLength(params)); @@ -541,27 +551,6 @@ nsContentSecurityManager::AsyncOnChannelRedirect(nsIChannel* aOldChannel, } } - // Redirecting to a toplevel data: URI is not allowed, hence we pass - // a NullPrincipal as the TriggeringPrincipal to - // AllowTopLevelNavigationToDataURI() which definitely blocks any - // data: URI load. - nsCOMPtr newLoadInfo = aNewChannel->GetLoadInfo(); - if (newLoadInfo) { - nsCOMPtr uri; - nsresult rv = NS_GetFinalChannelURI(aNewChannel, getter_AddRefs(uri)); - NS_ENSURE_SUCCESS(rv, rv); - nsCOMPtr nullTriggeringPrincipal = nsNullPrincipal::Create(); - if (!nsContentSecurityManager::AllowTopLevelNavigationToDataURI( - uri, - newLoadInfo->GetExternalContentPolicyType(), - nullTriggeringPrincipal, - false)) { - // logging to console happens within AllowTopLevelNavigationToDataURI - aOldChannel->Cancel(NS_ERROR_DOM_BAD_URI); - return NS_ERROR_DOM_BAD_URI; - } - } - // Also verify that the redirecting server is allowed to redirect to the // given URI nsCOMPtr oldPrincipal; diff --git a/dom/security/nsContentSecurityManager.h b/dom/security/nsContentSecurityManager.h index 09b6c86aa..bab847743 100644 --- a/dom/security/nsContentSecurityManager.h +++ b/dom/security/nsContentSecurityManager.h @@ -32,10 +32,7 @@ public: static nsresult doContentSecurityCheck(nsIChannel* aChannel, nsCOMPtr& aInAndOutListener); - static bool AllowTopLevelNavigationToDataURI(nsIURI* aURI, - nsContentPolicyType aContentPolicyType, - nsIPrincipal* aTriggeringPrincipal, - bool aLoadFromExternal); + static bool AllowTopLevelNavigationToDataURI(nsIChannel* aChannel); private: static nsresult CheckChannel(nsIChannel* aChannel); diff --git a/dom/security/test/general/browser.ini b/dom/security/test/general/browser.ini index 97ddae3bf..73ae72ddd 100644 --- a/dom/security/test/general/browser.ini +++ b/dom/security/test/general/browser.ini @@ -3,3 +3,9 @@ support-files = file_toplevel_data_navigations.sjs file_toplevel_data_meta_redirect.html +[browser_test_data_download.js] +support-files = + file_data_download.html +[browser_test_data_text_csv.js] +support-files = + file_data_text_csv.html diff --git a/dom/security/test/general/browser_test_data_download.js b/dom/security/test/general/browser_test_data_download.js new file mode 100644 index 000000000..1ee8d5844 --- /dev/null +++ b/dom/security/test/general/browser_test_data_download.js @@ -0,0 +1,37 @@ +"use strict"; + +const kTestPath = getRootDirectory(gTestPath) + .replace("chrome://mochitests/content", "http://example.com") +const kTestURI = kTestPath + "file_data_download.html"; + +function addWindowListener(aURL, aCallback) { + Services.wm.addListener({ + onOpenWindow(aXULWindow) { + info("window opened, waiting for focus"); + Services.wm.removeListener(this); + var domwindow = aXULWindow.QueryInterface(Ci.nsIInterfaceRequestor) + .getInterface(Ci.nsIDOMWindow); + waitForFocus(function() { + is(domwindow.document.location.href, aURL, "should have seen the right window open"); + aCallback(domwindow); + }, domwindow); + }, + onCloseWindow(aXULWindow) { }, + onWindowTitleChange(aXULWindow, aNewTitle) { } + }); +} + +function test() { + waitForExplicitFinish(); + Services.prefs.setBoolPref("security.data_uri.block_toplevel_data_uri_navigations", true); + registerCleanupFunction(function() { + Services.prefs.clearUserPref("security.data_uri.block_toplevel_data_uri_navigations"); + }); + addWindowListener("chrome://mozapps/content/downloads/unknownContentType.xul", function(win) { + is(win.document.getElementById("location").value, "data-foo.html", + "file name of download should match"); + win.close(); + finish(); + }); + gBrowser.loadURI(kTestURI); +} diff --git a/dom/security/test/general/browser_test_data_text_csv.js b/dom/security/test/general/browser_test_data_text_csv.js new file mode 100644 index 000000000..c45e40cc2 --- /dev/null +++ b/dom/security/test/general/browser_test_data_text_csv.js @@ -0,0 +1,37 @@ +"use strict"; + +const kTestPath = getRootDirectory(gTestPath) + .replace("chrome://mochitests/content", "http://example.com") +const kTestURI = kTestPath + "file_data_text_csv.html"; + +function addWindowListener(aURL, aCallback) { + Services.wm.addListener({ + onOpenWindow(aXULWindow) { + info("window opened, waiting for focus"); + Services.wm.removeListener(this); + var domwindow = aXULWindow.QueryInterface(Ci.nsIInterfaceRequestor) + .getInterface(Ci.nsIDOMWindow); + waitForFocus(function() { + is(domwindow.document.location.href, aURL, "should have seen the right window open"); + aCallback(domwindow); + }, domwindow); + }, + onCloseWindow(aXULWindow) { }, + onWindowTitleChange(aXULWindow, aNewTitle) { } + }); +} + +function test() { + waitForExplicitFinish(); + Services.prefs.setBoolPref("security.data_uri.block_toplevel_data_uri_navigations", true); + registerCleanupFunction(function() { + Services.prefs.clearUserPref("security.data_uri.block_toplevel_data_uri_navigations"); + }); + addWindowListener("chrome://mozapps/content/downloads/unknownContentType.xul", function(win) { + is(win.document.getElementById("location").value, "text/csv;foo,bar,foobar", + "file name of download should match"); + win.close(); + finish(); + }); + gBrowser.loadURI(kTestURI); +} diff --git a/dom/security/test/general/file_data_download.html b/dom/security/test/general/file_data_download.html new file mode 100644 index 000000000..4cc92fe8f --- /dev/null +++ b/dom/security/test/general/file_data_download.html @@ -0,0 +1,14 @@ + + + + Test download attribute for data: URI + + + download data + + + diff --git a/dom/security/test/general/file_data_text_csv.html b/dom/security/test/general/file_data_text_csv.html new file mode 100644 index 000000000..a9ac369d1 --- /dev/null +++ b/dom/security/test/general/file_data_text_csv.html @@ -0,0 +1,14 @@ + + + + Test open data:text/csv + + + test text/csv + + + diff --git a/dom/security/test/general/test_block_toplevel_data_img_navigation.html b/dom/security/test/general/test_block_toplevel_data_img_navigation.html index 2b8f62760..7f8dfc748 100644 --- a/dom/security/test/general/test_block_toplevel_data_img_navigation.html +++ b/dom/security/test/general/test_block_toplevel_data_img_navigation.html @@ -34,15 +34,17 @@ function test_toplevel_data_image_svg() { const DATA_SVG = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgaGVpZ2h0PSIxNiIgdmlld0JveD0iMCAwIDE2IDE2Ij4KICA8cGF0aCBkPSJNOCwxMkwzLDcsNCw2bDQsNCw0LTQsMSwxWiIgZmlsbD0iIzZBNkE2QSIgLz4KPC9zdmc+Cg=="; let win2 = window.open(DATA_SVG); - let wrappedWin2 = SpecialPowers.wrap(win2); - setTimeout(function () { - isnot(wrappedWin2.document.documentElement.localName, "svg", - "Loading data:image/svg+xml should be blocked"); - wrappedWin2.close(); - SimpleTest.finish(); - }, 1000); + // Unfortunately we can't detect whether the window was closed using some event, + // hence we are constantly polling till we see that win == null. + // Test times out on failure. + var win2Closed = setInterval(function() { + if (win2 == null || win2.closed) { + clearInterval(win2Closed); + ok(true, "Loading data:image/svg+xml should be blocked"); + SimpleTest.finish(); + } + }, 200); } - // fire up the tests test_toplevel_data_image(); diff --git a/dom/security/test/general/test_block_toplevel_data_navigation.html b/dom/security/test/general/test_block_toplevel_data_navigation.html index fc91f2ec0..cef232b65 100644 --- a/dom/security/test/general/test_block_toplevel_data_navigation.html +++ b/dom/security/test/general/test_block_toplevel_data_navigation.html @@ -21,16 +21,12 @@ function test1() { // simple data: URI click navigation should be prevented let TEST_FILE = "file_block_toplevel_data_navigation.html"; let win1 = window.open(TEST_FILE); - var readyStateCheckInterval = setInterval(function() { - let state = win1.document.readyState; - if (state === "interactive" || state === "complete") { - clearInterval(readyStateCheckInterval); - ok(win1.document.body.innerHTML.indexOf("test1:") !== -1, - "toplevel data: URI navigation through click() should be blocked"); - win1.close(); - test2(); - } - }, 200); + setTimeout(function () { + ok(SpecialPowers.wrap(win1).document.body.innerHTML.indexOf("test1:") !== -1, + "toplevel data: URI navigation through click() should be blocked"); + win1.close(); + test2(); + }, 1000); } function test2() { -- cgit v1.2.3 From 660d01438a6a29ebd43f592ac7d6df2dad6a6962 Mon Sep 17 00:00:00 2001 From: janekptacijarabaci Date: Sun, 22 Apr 2018 20:28:18 +0200 Subject: moebius#230: Consider blocking top level window data: URIs (part 3/3 without tests) https://github.com/MoonchildProductions/moebius/pull/230 --- dom/security/nsContentSecurityManager.cpp | 4 +++ dom/security/test/general/browser.ini | 3 +++ .../browser_test_view_image_data_navigation.js | 30 ++++++++++++++++++++++ .../general/file_view_image_data_navigation.html | 12 +++++++++ 4 files changed, 49 insertions(+) create mode 100644 dom/security/test/general/browser_test_view_image_data_navigation.js create mode 100644 dom/security/test/general/file_view_image_data_navigation.html (limited to 'dom/security') diff --git a/dom/security/nsContentSecurityManager.cpp b/dom/security/nsContentSecurityManager.cpp index c987fed67..9329c558a 100644 --- a/dom/security/nsContentSecurityManager.cpp +++ b/dom/security/nsContentSecurityManager.cpp @@ -39,6 +39,10 @@ nsContentSecurityManager::AllowTopLevelNavigationToDataURI(nsIChannel* aChannel) if (loadInfo->GetExternalContentPolicyType() != nsIContentPolicy::TYPE_DOCUMENT) { return true; } + if (loadInfo->GetForceAllowDataURI()) { + // if the loadinfo explicitly allows the data URI navigation, let's allow it now + return true; + } nsCOMPtr uri; nsresult rv = NS_GetFinalChannelURI(aChannel, getter_AddRefs(uri)); NS_ENSURE_SUCCESS(rv, true); diff --git a/dom/security/test/general/browser.ini b/dom/security/test/general/browser.ini index 73ae72ddd..b00baa95d 100644 --- a/dom/security/test/general/browser.ini +++ b/dom/security/test/general/browser.ini @@ -9,3 +9,6 @@ support-files = [browser_test_data_text_csv.js] support-files = file_data_text_csv.html +[browser_test_view_image_data_navigation.js] +support-files = + file_view_image_data_navigation.html diff --git a/dom/security/test/general/browser_test_view_image_data_navigation.js b/dom/security/test/general/browser_test_view_image_data_navigation.js new file mode 100644 index 000000000..22de35894 --- /dev/null +++ b/dom/security/test/general/browser_test_view_image_data_navigation.js @@ -0,0 +1,30 @@ +"use strict"; + +const TEST_PAGE = getRootDirectory(gTestPath) + "file_view_image_data_navigation.html"; + +add_task(async function test_principal_right_click_open_link_in_new_tab() { + await SpecialPowers.pushPrefEnv({ + "set": [["security.data_uri.block_toplevel_data_uri_navigations", true]], + }); + + await BrowserTestUtils.withNewTab(TEST_PAGE, async function(browser) { + let loadPromise = BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser, true); + + // simulate right-click->view-image + BrowserTestUtils.waitForEvent(document, "popupshown", false, event => { + // These are operations that must be executed synchronously with the event. + document.getElementById("context-viewimage").doCommand(); + event.target.hidePopup(); + return true; + }); + BrowserTestUtils.synthesizeMouseAtCenter("#testimage", + { type: "contextmenu", button: 2 }, + gBrowser.selectedBrowser); + await loadPromise; + + await ContentTask.spawn(gBrowser.selectedBrowser, {}, async function() { + ok(content.document.location.toString().startsWith("data:image/svg+xml;"), + "data:image/svg navigation allowed through right-click view-image") + }); + }); +}); diff --git a/dom/security/test/general/file_view_image_data_navigation.html b/dom/security/test/general/file_view_image_data_navigation.html new file mode 100644 index 000000000..a3f9acfb4 --- /dev/null +++ b/dom/security/test/general/file_view_image_data_navigation.html @@ -0,0 +1,12 @@ + + + + + Bug 1407891: Test navigation for right-click view-image on data:image/svg + + + + + + + -- cgit v1.2.3 From a38e87d455f6ad3637deeae20d2ddc57430b498d Mon Sep 17 00:00:00 2001 From: janekptacijarabaci Date: Sun, 22 Apr 2018 20:37:09 +0200 Subject: Bug 1329288 - Test ContentPolicy blocks opening a new window --- .../test/general/test_contentpolicytype_targeted_link_iframe.html | 1 + 1 file changed, 1 insertion(+) (limited to 'dom/security') diff --git a/dom/security/test/general/test_contentpolicytype_targeted_link_iframe.html b/dom/security/test/general/test_contentpolicytype_targeted_link_iframe.html index 7b1ab72dc..3ef243824 100644 --- a/dom/security/test/general/test_contentpolicytype_targeted_link_iframe.html +++ b/dom/security/test/general/test_contentpolicytype_targeted_link_iframe.html @@ -61,6 +61,7 @@ var policy = { "content policy type should TYPESUBDOCUMENT"); categoryManager.deleteCategoryEntry("content-policy", POLICYNAME, false); SimpleTest.finish(); + return Ci.nsIContentPolicy.REJECT_REQUEST; } return Ci.nsIContentPolicy.ACCEPT; }, -- cgit v1.2.3 From 95c46082414632687e3ddd52435d476ab9dc320f Mon Sep 17 00:00:00 2001 From: janekptacijarabaci Date: Sun, 22 Apr 2018 20:38:02 +0200 Subject: Bug 1329288: Allow content policy consumers to identify contentPolicy checks from docshell --- dom/security/nsCSPContext.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'dom/security') diff --git a/dom/security/nsCSPContext.cpp b/dom/security/nsCSPContext.cpp index a7517f65e..979bd915f 100644 --- a/dom/security/nsCSPContext.cpp +++ b/dom/security/nsCSPContext.cpp @@ -171,9 +171,10 @@ nsCSPContext::ShouldLoad(nsContentPolicyType aContentType, } } - // aExtra is only non-null if the channel got redirected. - bool wasRedirected = (aExtra != nullptr); + // aExtra holds the original URI of the channel if the + // channel got redirected (until we fix Bug 1332422). nsCOMPtr originalURI = do_QueryInterface(aExtra); + bool wasRedirected = originalURI; bool permitted = permitsInternal(dir, aContentLocation, -- cgit v1.2.3 From 2e33335820b2816bee111e78588ac82e401c86ae Mon Sep 17 00:00:00 2001 From: janekptacijarabaci Date: Sun, 22 Apr 2018 21:51:49 +0200 Subject: Bug 1182569: Update ContentSecurityManager to handle docshell loads native in moebius --- dom/security/nsContentSecurityManager.cpp | 81 ++++++++++++++++++++++++------- 1 file changed, 64 insertions(+), 17 deletions(-) (limited to 'dom/security') diff --git a/dom/security/nsContentSecurityManager.cpp b/dom/security/nsContentSecurityManager.cpp index 9329c558a..458f41144 100644 --- a/dom/security/nsContentSecurityManager.cpp +++ b/dom/security/nsContentSecurityManager.cpp @@ -10,6 +10,9 @@ #include "nsIStreamListener.h" #include "nsIDocument.h" #include "nsMixedContentBlocker.h" +#include "nsCDefaultURIFixup.h" +#include "nsIURIFixup.h" +#include "nsINestedURI.h" #include "mozilla/dom/Element.h" #include "mozilla/dom/TabChild.h" @@ -244,10 +247,6 @@ DoCORSChecks(nsIChannel* aChannel, nsILoadInfo* aLoadInfo, static nsresult DoContentSecurityChecks(nsIChannel* aChannel, nsILoadInfo* aLoadInfo) { - nsCOMPtr uri; - nsresult rv = NS_GetFinalChannelURI(aChannel, getter_AddRefs(uri)); - NS_ENSURE_SUCCESS(rv, rv); - nsContentPolicyType contentPolicyType = aLoadInfo->GetExternalContentPolicyType(); nsContentPolicyType internalContentPolicyType = @@ -255,12 +254,24 @@ DoContentSecurityChecks(nsIChannel* aChannel, nsILoadInfo* aLoadInfo) nsCString mimeTypeGuess; nsCOMPtr requestingContext = nullptr; -#ifdef DEBUG - // Don't enforce TYPE_DOCUMENT assertions for loads - // initiated by javascript tests. - bool skipContentTypeCheck = false; - skipContentTypeCheck = Preferences::GetBool("network.loadinfo.skip_type_assertion"); -#endif + nsCOMPtr uri; + nsresult rv = NS_GetFinalChannelURI(aChannel, getter_AddRefs(uri)); + NS_ENSURE_SUCCESS(rv, rv); + + if (contentPolicyType == nsIContentPolicy::TYPE_DOCUMENT || + contentPolicyType == nsIContentPolicy::TYPE_SUBDOCUMENT) { + // TYPE_DOCUMENT and TYPE_SUBDOCUMENT loads might potentially + // be wyciwyg:// channels. Let's fix up the URI so we can + // perform proper security checks. + nsCOMPtr urifixup(do_GetService(NS_URIFIXUP_CONTRACTID, &rv)); + if (NS_SUCCEEDED(rv) && urifixup) { + nsCOMPtr fixedURI; + rv = urifixup->CreateExposableURI(uri, getter_AddRefs(fixedURI)); + if (NS_SUCCEEDED(rv)) { + uri = fixedURI; + } + } + } switch(contentPolicyType) { case nsIContentPolicy::TYPE_OTHER: { @@ -294,16 +305,14 @@ DoContentSecurityChecks(nsIChannel* aChannel, nsILoadInfo* aLoadInfo) } case nsIContentPolicy::TYPE_DOCUMENT: { - MOZ_ASSERT(skipContentTypeCheck || false, "contentPolicyType not supported yet"); + mimeTypeGuess = EmptyCString(); + requestingContext = aLoadInfo->LoadingNode(); break; } case nsIContentPolicy::TYPE_SUBDOCUMENT: { mimeTypeGuess = NS_LITERAL_CSTRING("text/html"); requestingContext = aLoadInfo->LoadingNode(); - MOZ_ASSERT(!requestingContext || - requestingContext->NodeType() == nsIDOMNode::DOCUMENT_NODE, - "type_subdocument requires requestingContext of type Document"); break; } @@ -447,18 +456,32 @@ DoContentSecurityChecks(nsIChannel* aChannel, nsILoadInfo* aLoadInfo) MOZ_ASSERT(false, "can not perform security check without a valid contentType"); } + // For document loads we use the triggeringPrincipal as the originPrincipal. + // Note the the loadingPrincipal for loads of TYPE_DOCUMENT is a nullptr. + nsCOMPtr principal = + (contentPolicyType == nsIContentPolicy::TYPE_DOCUMENT || + contentPolicyType == nsIContentPolicy::TYPE_SUBDOCUMENT) + ? aLoadInfo->TriggeringPrincipal() + : aLoadInfo->LoadingPrincipal(); + int16_t shouldLoad = nsIContentPolicy::ACCEPT; rv = NS_CheckContentLoadPolicy(internalContentPolicyType, uri, - aLoadInfo->LoadingPrincipal(), + principal, requestingContext, mimeTypeGuess, nullptr, //extra, &shouldLoad, nsContentUtils::GetContentPolicy(), nsContentUtils::GetSecurityManager()); - NS_ENSURE_SUCCESS(rv, rv); - if (NS_CP_REJECTED(shouldLoad)) { + + if (NS_FAILED(rv) || NS_CP_REJECTED(shouldLoad)) { + if ((NS_SUCCEEDED(rv) && shouldLoad == nsIContentPolicy::REJECT_TYPE) && + (contentPolicyType == nsIContentPolicy::TYPE_DOCUMENT || + contentPolicyType == nsIContentPolicy::TYPE_SUBDOCUMENT)) { + // for docshell loads we might have to return SHOW_ALT. + return NS_ERROR_CONTENT_BLOCKED_SHOW_ALT; + } return NS_ERROR_CONTENT_BLOCKED; } @@ -606,6 +629,30 @@ nsContentSecurityManager::CheckChannel(nsIChannel* aChannel) nsresult rv = NS_GetFinalChannelURI(aChannel, getter_AddRefs(uri)); NS_ENSURE_SUCCESS(rv, rv); + nsContentPolicyType contentPolicyType = + loadInfo->GetExternalContentPolicyType(); + + if (contentPolicyType == nsIContentPolicy::TYPE_DOCUMENT || + contentPolicyType == nsIContentPolicy::TYPE_SUBDOCUMENT) { + // query the nested URI for security checks like in the case of view-source + nsCOMPtr nestedURI = do_QueryInterface(uri); + if (nestedURI) { + nestedURI->GetInnerURI(getter_AddRefs(uri)); + } + + // TYPE_DOCUMENT and TYPE_SUBDOCUMENT loads might potentially + // be wyciwyg:// channels. Let's fix up the URI so we can + // perform proper security checks. + nsCOMPtr urifixup(do_GetService(NS_URIFIXUP_CONTRACTID, &rv)); + if (NS_SUCCEEDED(rv) && urifixup) { + nsCOMPtr fixedURI; + rv = urifixup->CreateExposableURI(uri, getter_AddRefs(fixedURI)); + if (NS_SUCCEEDED(rv)) { + uri = fixedURI; + } + } + } + // Handle cookie policies uint32_t cookiePolicy = loadInfo->GetCookiePolicy(); if (cookiePolicy == nsILoadInfo::SEC_COOKIES_SAME_ORIGIN) { -- cgit v1.2.3 From 115cf1e322bdabaee001781e1d5a8ee4928992af Mon Sep 17 00:00:00 2001 From: janekptacijarabaci Date: Sun, 22 Apr 2018 22:17:09 +0200 Subject: Revert "Bug 1182569: Update ContentSecurityManager to handle docshell loads" This reverts commit 2e33335820b2816bee111e78588ac82e401c86ae. --- dom/security/nsContentSecurityManager.cpp | 81 +++++++------------------------ 1 file changed, 17 insertions(+), 64 deletions(-) (limited to 'dom/security') diff --git a/dom/security/nsContentSecurityManager.cpp b/dom/security/nsContentSecurityManager.cpp index 458f41144..9329c558a 100644 --- a/dom/security/nsContentSecurityManager.cpp +++ b/dom/security/nsContentSecurityManager.cpp @@ -10,9 +10,6 @@ #include "nsIStreamListener.h" #include "nsIDocument.h" #include "nsMixedContentBlocker.h" -#include "nsCDefaultURIFixup.h" -#include "nsIURIFixup.h" -#include "nsINestedURI.h" #include "mozilla/dom/Element.h" #include "mozilla/dom/TabChild.h" @@ -247,6 +244,10 @@ DoCORSChecks(nsIChannel* aChannel, nsILoadInfo* aLoadInfo, static nsresult DoContentSecurityChecks(nsIChannel* aChannel, nsILoadInfo* aLoadInfo) { + nsCOMPtr uri; + nsresult rv = NS_GetFinalChannelURI(aChannel, getter_AddRefs(uri)); + NS_ENSURE_SUCCESS(rv, rv); + nsContentPolicyType contentPolicyType = aLoadInfo->GetExternalContentPolicyType(); nsContentPolicyType internalContentPolicyType = @@ -254,24 +255,12 @@ DoContentSecurityChecks(nsIChannel* aChannel, nsILoadInfo* aLoadInfo) nsCString mimeTypeGuess; nsCOMPtr requestingContext = nullptr; - nsCOMPtr uri; - nsresult rv = NS_GetFinalChannelURI(aChannel, getter_AddRefs(uri)); - NS_ENSURE_SUCCESS(rv, rv); - - if (contentPolicyType == nsIContentPolicy::TYPE_DOCUMENT || - contentPolicyType == nsIContentPolicy::TYPE_SUBDOCUMENT) { - // TYPE_DOCUMENT and TYPE_SUBDOCUMENT loads might potentially - // be wyciwyg:// channels. Let's fix up the URI so we can - // perform proper security checks. - nsCOMPtr urifixup(do_GetService(NS_URIFIXUP_CONTRACTID, &rv)); - if (NS_SUCCEEDED(rv) && urifixup) { - nsCOMPtr fixedURI; - rv = urifixup->CreateExposableURI(uri, getter_AddRefs(fixedURI)); - if (NS_SUCCEEDED(rv)) { - uri = fixedURI; - } - } - } +#ifdef DEBUG + // Don't enforce TYPE_DOCUMENT assertions for loads + // initiated by javascript tests. + bool skipContentTypeCheck = false; + skipContentTypeCheck = Preferences::GetBool("network.loadinfo.skip_type_assertion"); +#endif switch(contentPolicyType) { case nsIContentPolicy::TYPE_OTHER: { @@ -305,14 +294,16 @@ DoContentSecurityChecks(nsIChannel* aChannel, nsILoadInfo* aLoadInfo) } case nsIContentPolicy::TYPE_DOCUMENT: { - mimeTypeGuess = EmptyCString(); - requestingContext = aLoadInfo->LoadingNode(); + MOZ_ASSERT(skipContentTypeCheck || false, "contentPolicyType not supported yet"); break; } case nsIContentPolicy::TYPE_SUBDOCUMENT: { mimeTypeGuess = NS_LITERAL_CSTRING("text/html"); requestingContext = aLoadInfo->LoadingNode(); + MOZ_ASSERT(!requestingContext || + requestingContext->NodeType() == nsIDOMNode::DOCUMENT_NODE, + "type_subdocument requires requestingContext of type Document"); break; } @@ -456,32 +447,18 @@ DoContentSecurityChecks(nsIChannel* aChannel, nsILoadInfo* aLoadInfo) MOZ_ASSERT(false, "can not perform security check without a valid contentType"); } - // For document loads we use the triggeringPrincipal as the originPrincipal. - // Note the the loadingPrincipal for loads of TYPE_DOCUMENT is a nullptr. - nsCOMPtr principal = - (contentPolicyType == nsIContentPolicy::TYPE_DOCUMENT || - contentPolicyType == nsIContentPolicy::TYPE_SUBDOCUMENT) - ? aLoadInfo->TriggeringPrincipal() - : aLoadInfo->LoadingPrincipal(); - int16_t shouldLoad = nsIContentPolicy::ACCEPT; rv = NS_CheckContentLoadPolicy(internalContentPolicyType, uri, - principal, + aLoadInfo->LoadingPrincipal(), requestingContext, mimeTypeGuess, nullptr, //extra, &shouldLoad, nsContentUtils::GetContentPolicy(), nsContentUtils::GetSecurityManager()); - - if (NS_FAILED(rv) || NS_CP_REJECTED(shouldLoad)) { - if ((NS_SUCCEEDED(rv) && shouldLoad == nsIContentPolicy::REJECT_TYPE) && - (contentPolicyType == nsIContentPolicy::TYPE_DOCUMENT || - contentPolicyType == nsIContentPolicy::TYPE_SUBDOCUMENT)) { - // for docshell loads we might have to return SHOW_ALT. - return NS_ERROR_CONTENT_BLOCKED_SHOW_ALT; - } + NS_ENSURE_SUCCESS(rv, rv); + if (NS_CP_REJECTED(shouldLoad)) { return NS_ERROR_CONTENT_BLOCKED; } @@ -629,30 +606,6 @@ nsContentSecurityManager::CheckChannel(nsIChannel* aChannel) nsresult rv = NS_GetFinalChannelURI(aChannel, getter_AddRefs(uri)); NS_ENSURE_SUCCESS(rv, rv); - nsContentPolicyType contentPolicyType = - loadInfo->GetExternalContentPolicyType(); - - if (contentPolicyType == nsIContentPolicy::TYPE_DOCUMENT || - contentPolicyType == nsIContentPolicy::TYPE_SUBDOCUMENT) { - // query the nested URI for security checks like in the case of view-source - nsCOMPtr nestedURI = do_QueryInterface(uri); - if (nestedURI) { - nestedURI->GetInnerURI(getter_AddRefs(uri)); - } - - // TYPE_DOCUMENT and TYPE_SUBDOCUMENT loads might potentially - // be wyciwyg:// channels. Let's fix up the URI so we can - // perform proper security checks. - nsCOMPtr urifixup(do_GetService(NS_URIFIXUP_CONTRACTID, &rv)); - if (NS_SUCCEEDED(rv) && urifixup) { - nsCOMPtr fixedURI; - rv = urifixup->CreateExposableURI(uri, getter_AddRefs(fixedURI)); - if (NS_SUCCEEDED(rv)) { - uri = fixedURI; - } - } - } - // Handle cookie policies uint32_t cookiePolicy = loadInfo->GetCookiePolicy(); if (cookiePolicy == nsILoadInfo::SEC_COOKIES_SAME_ORIGIN) { -- cgit v1.2.3 From ccbd5ecf57fcd53ac8b28ddf7466b6c930f764df Mon Sep 17 00:00:00 2001 From: janekptacijarabaci Date: Mon, 23 Apr 2018 00:13:56 +0200 Subject: moebius#187: DOM - nsIContentPolicy - context (document) https://github.com/MoonchildProductions/moebius/pull/187 --- dom/security/nsContentSecurityManager.cpp | 63 +++++++++++++++++++++---------- 1 file changed, 43 insertions(+), 20 deletions(-) (limited to 'dom/security') diff --git a/dom/security/nsContentSecurityManager.cpp b/dom/security/nsContentSecurityManager.cpp index 9329c558a..0cc4933fe 100644 --- a/dom/security/nsContentSecurityManager.cpp +++ b/dom/security/nsContentSecurityManager.cpp @@ -253,7 +253,7 @@ DoContentSecurityChecks(nsIChannel* aChannel, nsILoadInfo* aLoadInfo) nsContentPolicyType internalContentPolicyType = aLoadInfo->InternalContentPolicyType(); nsCString mimeTypeGuess; - nsCOMPtr requestingContext = nullptr; + nsCOMPtr requestingContext = nullptr; #ifdef DEBUG // Don't enforce TYPE_DOCUMENT assertions for loads @@ -327,10 +327,13 @@ DoContentSecurityChecks(nsIChannel* aChannel, nsILoadInfo* aLoadInfo) case nsIContentPolicy::TYPE_XMLHTTPREQUEST: { // alias nsIContentPolicy::TYPE_DATAREQUEST: requestingContext = aLoadInfo->LoadingNode(); - MOZ_ASSERT(!requestingContext || - requestingContext->NodeType() == nsIDOMNode::DOCUMENT_NODE, - "type_xml requires requestingContext of type Document"); - +#ifdef DEBUG + { + nsCOMPtr node = do_QueryInterface(requestingContext); + MOZ_ASSERT(!node || node->NodeType() == nsIDOMNode::DOCUMENT_NODE, + "type_xml requires requestingContext of type Document"); + } +#endif // We're checking for the external TYPE_XMLHTTPREQUEST here in case // an addon creates a request with that type. if (internalContentPolicyType == @@ -351,18 +354,26 @@ DoContentSecurityChecks(nsIChannel* aChannel, nsILoadInfo* aLoadInfo) case nsIContentPolicy::TYPE_OBJECT_SUBREQUEST: { mimeTypeGuess = EmptyCString(); requestingContext = aLoadInfo->LoadingNode(); - MOZ_ASSERT(!requestingContext || - requestingContext->NodeType() == nsIDOMNode::ELEMENT_NODE, - "type_subrequest requires requestingContext of type Element"); +#ifdef DEBUG + { + nsCOMPtr node = do_QueryInterface(requestingContext); + MOZ_ASSERT(!node || node->NodeType() == nsIDOMNode::ELEMENT_NODE, + "type_subrequest requires requestingContext of type Element"); + } +#endif break; } case nsIContentPolicy::TYPE_DTD: { mimeTypeGuess = EmptyCString(); requestingContext = aLoadInfo->LoadingNode(); - MOZ_ASSERT(!requestingContext || - requestingContext->NodeType() == nsIDOMNode::DOCUMENT_NODE, - "type_dtd requires requestingContext of type Document"); +#ifdef DEBUG + { + nsCOMPtr node = do_QueryInterface(requestingContext); + MOZ_ASSERT(!node || node->NodeType() == nsIDOMNode::DOCUMENT_NODE, + "type_dtd requires requestingContext of type Document"); + } +#endif break; } @@ -380,9 +391,13 @@ DoContentSecurityChecks(nsIChannel* aChannel, nsILoadInfo* aLoadInfo) mimeTypeGuess = EmptyCString(); } requestingContext = aLoadInfo->LoadingNode(); - MOZ_ASSERT(!requestingContext || - requestingContext->NodeType() == nsIDOMNode::ELEMENT_NODE, - "type_media requires requestingContext of type Element"); +#ifdef DEBUG + { + nsCOMPtr node = do_QueryInterface(requestingContext); + MOZ_ASSERT(!node || node->NodeType() == nsIDOMNode::ELEMENT_NODE, + "type_media requires requestingContext of type Element"); + } +#endif break; } @@ -409,18 +424,26 @@ DoContentSecurityChecks(nsIChannel* aChannel, nsILoadInfo* aLoadInfo) case nsIContentPolicy::TYPE_XSLT: { mimeTypeGuess = NS_LITERAL_CSTRING("application/xml"); requestingContext = aLoadInfo->LoadingNode(); - MOZ_ASSERT(!requestingContext || - requestingContext->NodeType() == nsIDOMNode::DOCUMENT_NODE, - "type_xslt requires requestingContext of type Document"); +#ifdef DEBUG + { + nsCOMPtr node = do_QueryInterface(requestingContext); + MOZ_ASSERT(!node || node->NodeType() == nsIDOMNode::DOCUMENT_NODE, + "type_xslt requires requestingContext of type Document"); + } +#endif break; } case nsIContentPolicy::TYPE_BEACON: { mimeTypeGuess = EmptyCString(); requestingContext = aLoadInfo->LoadingNode(); - MOZ_ASSERT(!requestingContext || - requestingContext->NodeType() == nsIDOMNode::DOCUMENT_NODE, - "type_beacon requires requestingContext of type Document"); +#ifdef DEBUG + { + nsCOMPtr node = do_QueryInterface(requestingContext); + MOZ_ASSERT(!node || node->NodeType() == nsIDOMNode::DOCUMENT_NODE, + "type_beacon requires requestingContext of type Document"); + } +#endif break; } -- cgit v1.2.3