mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-11-01 03:57:30 +09:00
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:
parent
08e2f9aaea
commit
712d19e1b7
22 changed files with 515 additions and 1 deletions
5
dom/security/test/general/browser.ini
Normal file
5
dom/security/test/general/browser.ini
Normal 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
|
||||
|
|
@ -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");
|
||||
});
|
||||
});
|
||||
|
|
@ -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>
|
||||
|
|
@ -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>
|
||||
|
|
@ -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>
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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>
|
||||
14
dom/security/test/general/file_toplevel_data_navigations.sjs
Normal file
14
dom/security/test/general/file_toplevel_data_navigations.sjs
Normal 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);
|
||||
}
|
||||
|
|
@ -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'
|
||||
|
|
|
|||
39
dom/security/test/general/test_allow_opening_data_json.html
Normal file
39
dom/security/test/general/test_allow_opening_data_json.html
Normal 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>
|
||||
41
dom/security/test/general/test_allow_opening_data_pdf.html
Normal file
41
dom/security/test/general/test_allow_opening_data_pdf.html
Normal 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>
|
||||
|
|
@ -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>
|
||||
|
|
@ -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>
|
||||
|
|
@ -27,5 +27,6 @@ MOCHITEST_CHROME_MANIFESTS += [
|
|||
BROWSER_CHROME_MANIFESTS += [
|
||||
'contentverifier/browser.ini',
|
||||
'csp/browser.ini',
|
||||
'general/browser.ini',
|
||||
'hsts/browser.ini',
|
||||
]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue