moebius#223: Consider blocking top level window data: URIs (part 1/3 without tests)

https://github.com/MoonchildProductions/moebius/pull/223
This commit is contained in:
janekptacijarabaci 2018-04-22 18:51:38 +02:00 committed by Roy Tam
commit 712d19e1b7
22 changed files with 515 additions and 1 deletions

View file

@ -42,6 +42,7 @@
#include "nsArray.h"
#include "nsArrayUtils.h"
#include "nsContentSecurityManager.h"
#include "nsICaptivePortalService.h"
#include "nsIDOMStorage.h"
#include "nsIContentViewer.h"
@ -9884,6 +9885,15 @@ nsDocShell::InternalLoad(nsIURI* aURI,
contentType = nsIContentPolicy::TYPE_DOCUMENT;
}
if (!nsContentSecurityManager::AllowTopLevelNavigationToDataURI(
aURI,
contentType,
aTriggeringPrincipal,
(aLoadType == LOAD_NORMAL_EXTERNAL))) {
// logging to console happens within AllowTopLevelNavigationToDataURI
return NS_OK;
}
// If there's no targetDocShell, that means we are about to create a new window,
// perform a content policy check before creating the window.
if (!targetDocShell) {
@ -10232,8 +10242,11 @@ nsDocShell::InternalLoad(nsIURI* aURI,
}
}
bool loadFromExternal = false;
// Before going any further vet loads initiated by external programs.
if (aLoadType == LOAD_NORMAL_EXTERNAL) {
loadFromExternal = true;
// Disallow external chrome: loads targetted at content windows
bool isChrome = false;
if (NS_SUCCEEDED(aURI->SchemeIs("chrome", &isChrome)) && isChrome) {
@ -10724,7 +10737,7 @@ nsDocShell::InternalLoad(nsIURI* aURI,
nsINetworkPredictor::PREDICT_LOAD, this, nullptr);
nsCOMPtr<nsIRequest> req;
rv = DoURILoad(aURI, aOriginalURI, aLoadReplace, aReferrer,
rv = DoURILoad(aURI, aOriginalURI, aLoadReplace, loadFromExternal, aReferrer,
!(aFlags & INTERNAL_LOAD_FLAGS_DONT_SEND_REFERRER),
aReferrerPolicy,
aTriggeringPrincipal, principalToInherit, aTypeHint,
@ -10804,6 +10817,7 @@ nsresult
nsDocShell::DoURILoad(nsIURI* aURI,
nsIURI* aOriginalURI,
bool aLoadReplace,
bool aLoadFromExternal,
nsIURI* aReferrerURI,
bool aSendReferrer,
uint32_t aReferrerPolicy,

View file

@ -369,6 +369,7 @@ protected:
nsresult DoURILoad(nsIURI* aURI,
nsIURI* aOriginalURI,
bool aLoadReplace,
bool aLoadFromExternal,
nsIURI* aReferrer,
bool aSendReferrer,
uint32_t aReferrerPolicy,

View file

@ -81,3 +81,6 @@ MimeTypeMismatch=The resource from “%1$S” was blocked due to MIME type misma
XCTOHeaderValueMissing=X-Content-Type-Options header warning: value was “%1$S”; did you mean to send “nosniff”?
BlockScriptWithWrongMimeType=Script from “%1$S” was blocked because of a disallowed MIME type.
# LOCALIZATION NOTE: Do not translate "data: URI".
BlockTopLevelDataURINavigation=Navigation to toplevel data: URI not allowed (Blocked loading of: “%1$S”)

View file

@ -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<nsILoadInfo> newLoadInfo = aNewChannel->GetLoadInfo();
if (newLoadInfo) {
nsCOMPtr<nsIURI> uri;
nsresult rv = NS_GetFinalChannelURI(aNewChannel, getter_AddRefs(uri));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIPrincipal> 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<nsIPrincipal> oldPrincipal;

View file

@ -32,6 +32,11 @@ public:
static nsresult doContentSecurityCheck(nsIChannel* aChannel,
nsCOMPtr<nsIStreamListener>& aInAndOutListener);
static bool AllowTopLevelNavigationToDataURI(nsIURI* aURI,
nsContentPolicyType aContentPolicyType,
nsIPrincipal* aTriggeringPrincipal,
bool aLoadFromExternal);
private:
static nsresult CheckChannel(nsIChannel* aChannel);

View file

@ -0,0 +1,5 @@
[DEFAULT]
[browser_test_toplevel_data_navigations.js]
support-files =
file_toplevel_data_navigations.sjs
file_toplevel_data_meta_redirect.html

View file

@ -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,<body>" + kDataBody + "</body>";
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");
});
});

View file

@ -0,0 +1,14 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Toplevel data navigation</title>
</head>
<body>
test1: clicking data: URI tries to navigate window<br/>
<a id="testlink" href="data:text/html,<body>toplevel data: URI navigations should be blocked</body>">click me</a>
<script>
document.getElementById('testlink').click();
</script>
</body>
</html>

View file

@ -0,0 +1,29 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Toplevel data navigation</title>
</head>
<body>
test2: data: URI in iframe tries to window.open(data:, _blank);<br/>
<iframe id="testFrame" src=""></iframe>
<script>
let DATA_URI = `data:text/html,<body><script>
var win = window.open("data:text/html,<body>toplevel data: URI navigations should be blocked</body>", "_blank");
setTimeout(function () {
var result = win.document.body.innerHTML === "" ? "blocked" : "navigated";
parent.postMessage(result, "*");
win.close();
}, 1000);
<\/script></body>`;
window.addEventListener("message", receiveMessage);
function receiveMessage(event) {
window.removeEventListener("message", receiveMessage);
// propagate the information back to the caller
window.opener.postMessage(event.data, "*");
}
document.getElementById('testFrame').src = DATA_URI;
</script>
</body>
</html>

View file

@ -0,0 +1,13 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Toplevel data navigation</title>
</head>
<body>
test3: performing data: URI navigation through win.loc.href<br/>
<script>
window.location.href = "data:text/html,<body>toplevel data: URI navigations should be blocked</body>";
</script>
</body>
</html>

View file

@ -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 =
"<body>toplevel data: URI navigations after redirect should be blocked</body>";
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);
}

View file

@ -0,0 +1,10 @@
<html>
<body>
<head>
<meta http-equiv="refresh"
content="0; url='data:text/html,<body>toplevel meta redirect to data: URI should be blocked</body>'">
</head>
<body>
Meta Redirect to data: URI
</body>
</html>

View file

@ -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,<body>toplevel data: URI navigations after redirect should be blocked</body>";
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);
}

View file

@ -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'

View file

@ -0,0 +1,39 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Bug 1403814: Allow toplevel data URI navigation data:application/json</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<script class="testbody" type="text/javascript">
SimpleTest.waitForExplicitFinish();
function test_toplevel_data_json() {
const DATA_JSON = "data:application/json,{'my_json_key':'my_json_value'}";
let win = window.open(DATA_JSON);
let wrappedWin = SpecialPowers.wrap(win);
// Unfortunately we can't detect whether the JSON has loaded or not using some
// event, hence we are constantly polling location.href till we see that
// the data: URI appears. Test times out on failure.
var jsonLoaded = setInterval(function() {
if (wrappedWin.document.location.href.startsWith("data:application/json")) {
clearInterval(jsonLoaded);
ok(true, "navigating to data:application/json allowed");
wrappedWin.close();
SimpleTest.finish();
}
}, 200);
}
SpecialPowers.pushPrefEnv({
set: [["security.data_uri.block_toplevel_data_uri_navigations", true]]
}, test_toplevel_data_json);
</script>
</body>
</html>

View file

@ -0,0 +1,41 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Bug 1398692: Allow toplevel navigation to a data:application/pdf</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<script class="testbody" type="text/javascript">
SimpleTest.waitForExplicitFinish();
function test_toplevel_data_pdf() {
// The PDF contains one page and it is a 3/72" square, the minimum allowed by the spec
const DATA_PDF =
"data:application/pdf;base64,JVBERi0xLjANCjEgMCBvYmo8PC9UeXBlL0NhdGFsb2cvUGFnZXMgMiAwIFI+PmVuZG9iaiAyIDAgb2JqPDwvVHlwZS9QYWdlcy9LaWRzWzMgMCBSXS9Db3VudCAxPj5lbmRvYmogMyAwIG9iajw8L1R5cGUvUGFnZS9NZWRpYUJveFswIDAgMyAzXT4+ZW5kb2JqDQp4cmVmDQowIDQNCjAwMDAwMDAwMDAgNjU1MzUgZg0KMDAwMDAwMDAxMCAwMDAwMCBuDQowMDAwMDAwMDUzIDAwMDAwIG4NCjAwMDAwMDAxMDIgMDAwMDAgbg0KdHJhaWxlcjw8L1NpemUgNC9Sb290IDEgMCBSPj4NCnN0YXJ0eHJlZg0KMTQ5DQolRU9G";
let win = window.open(DATA_PDF);
let wrappedWin = SpecialPowers.wrap(win);
// Unfortunately we can't detect whether the PDF has loaded or not using some
// event, hence we are constantly polling location.href till we see that
// the data: URI appears. Test times out on failure.
var pdfLoaded = setInterval(function() {
if (wrappedWin.document.location.href.startsWith("data:application/pdf")) {
clearInterval(pdfLoaded);
ok(true, "navigating to data:application/pdf allowed");
wrappedWin.close();
SimpleTest.finish();
}
}, 200);
}
SpecialPowers.pushPrefEnv({
set: [["security.data_uri.block_toplevel_data_uri_navigations", true]]
}, test_toplevel_data_pdf);
</script>
</body>
</html>

View file

@ -0,0 +1,51 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Bug 1396798: Do not block toplevel data: navigation to image (except svgs)</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<script class="testbody" type="text/javascript">
SpecialPowers.setBoolPref("security.data_uri.block_toplevel_data_uri_navigations", true);
SimpleTest.registerCleanupFunction(() => {
SpecialPowers.clearUserPref("security.data_uri.block_toplevel_data_uri_navigations");
});
SimpleTest.waitForExplicitFinish();
SimpleTest.requestFlakyTimeout("have to test that top level data:image loading is blocked/allowed");
function test_toplevel_data_image() {
const DATA_PNG =
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==";
let win1 = window.open(DATA_PNG);
let wrappedWin1 = SpecialPowers.wrap(win1);
setTimeout(function () {
let images = wrappedWin1.document.getElementsByTagName('img');
is(images.length, 1, "Loading data:image/png should be allowed");
is(images[0].src, DATA_PNG, "Sanity: img src matches");
wrappedWin1.close();
test_toplevel_data_image_svg();
}, 1000);
}
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);
}
// fire up the tests
test_toplevel_data_image();
</script>
</body>
</html>

View file

@ -0,0 +1,90 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Bug 1331351 - Block top level window data: URI navigations</title>
<!-- Including SimpleTest.js so we can use waitForExplicitFinish !-->
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<script class="testbody" type="text/javascript">
SpecialPowers.setBoolPref("security.data_uri.block_toplevel_data_uri_navigations", true);
SimpleTest.registerCleanupFunction(() => {
SpecialPowers.clearUserPref("security.data_uri.block_toplevel_data_uri_navigations");
});
SimpleTest.waitForExplicitFinish();
SimpleTest.requestFlakyTimeout("have to test that top level data: URI navgiation is blocked");
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);
}
function test2() {
// data: URI in iframe which opens data: URI in _blank should be blocked
let win2 = window.open("file_block_toplevel_data_navigation2.html");
window.addEventListener("message", receiveMessage);
function receiveMessage(event) {
window.removeEventListener("message", receiveMessage);
is(event.data, "blocked",
"data: URI navigation using _blank from data: URI should be blocked");
win2.close();
test3();
}
}
function test3() {
// navigating to a data: URI using window.location.href should be blocked
let win3 = window.open("file_block_toplevel_data_navigation3.html");
setTimeout(function () {
ok(win3.document.body.innerHTML.indexOf("test3:") !== -1,
"data: URI navigation through win.loc.href should be blocked");
win3.close();
test4();
}, 1000);
}
function test4() {
// navigating to a data: URI using window.open() should be blocked
let win4 = window.open("data:text/html,<body>toplevel data: URI navigations should be blocked</body>");
setTimeout(function () {
// Please note that the data: URI will be displayed in the URL-Bar but not
// loaded, hence we rather rely on document.body than document.location
is(win4.document.body.innerHTML, "",
"navigating to a data: URI using window.open() should be blocked");
test5();
}, 1000);
}
function test5() {
// navigating to a URI which redirects to a data: URI using window.open() should be blocked
let win5 = window.open("file_block_toplevel_data_redirect.sjs");
setTimeout(function () {
// Please note that the data: URI will be displayed in the URL-Bar but not
// loaded, hence we rather rely on document.body than document.location
is(SpecialPowers.wrap(win5).document.body.innerHTML, "",
"navigating to URI which redirects to a data: URI using window.open() should be blocked");
win5.close();
SimpleTest.finish();
}, 1000);
}
// fire up the tests
test1();
</script>
</body>
</html>

View file

@ -27,5 +27,6 @@ MOCHITEST_CHROME_MANIFESTS += [
BROWSER_CHROME_MANIFESTS += [
'contentverifier/browser.ini',
'csp/browser.ini',
'general/browser.ini',
'hsts/browser.ini',
]

View file

@ -5572,6 +5572,12 @@ pref("security.mixed_content.use_hsts", true);
// Approximately 1 week default cache for HSTS priming failures
pref ("security.mixed_content.hsts_priming_cache_timeout", 10080);
// TODO: Bug 1380959: Block toplevel data: URI navigations
// If true, all toplevel data: URI navigations will be blocked.
// Please note that manually entering a data: URI in the
// URL-Bar will not be blocked when flipping this pref.
pref("security.data_uri.block_toplevel_data_uri_navigations", false);
// Disable Storage api in release builds.
#ifdef NIGHTLY_BUILD
pref("dom.storageManager.enabled", true);

View file

@ -173,6 +173,8 @@ uint32_t nsIOService::gDefaultSegmentCount = 24;
bool nsIOService::sTelemetryEnabled = false;
bool nsIOService::sBlockToplevelDataUriNavigations = false;
////////////////////////////////////////////////////////////////////////////////
nsIOService::nsIOService()
@ -251,6 +253,8 @@ nsIOService::Init()
NS_WARNING("failed to get observer service");
Preferences::AddBoolVarCache(&sTelemetryEnabled, "toolkit.telemetry.enabled", false);
Preferences::AddBoolVarCache(&sBlockToplevelDataUriNavigations,
"security.data_uri.block_toplevel_data_uri_navigations", false);
Preferences::AddBoolVarCache(&mOfflineMirrorsConnectivity, OFFLINE_MIRRORS_CONNECTIVITY, true);
gIOService = this;
@ -1876,5 +1880,11 @@ nsIOService::SpeculativeAnonymousConnect2(nsIURI *aURI,
return SpeculativeConnectInternal(aURI, aPrincipal, aCallbacks, true);
}
/*static*/ bool
nsIOService::BlockToplevelDataUriNavigations()
{
return sBlockToplevelDataUriNavigations;
}
} // namespace net
} // namespace mozilla

View file

@ -95,6 +95,8 @@ public:
bool IsLinkUp();
static bool BlockToplevelDataUriNavigations();
// Used to trigger a recheck of the captive portal status
nsresult RecheckCaptivePortal();
private:
@ -176,6 +178,8 @@ private:
static bool sTelemetryEnabled;
static bool sBlockToplevelDataUriNavigations;
// These timestamps are needed for collecting telemetry on PR_Connect,
// PR_ConnectContinue and PR_Close blocking time. If we spend very long
// time in any of these functions we want to know if and what network