mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-10-08 00:07:30 +09:00
import FIREFOX_52_6_0esr_RELEASE from mozilla-esr52 hg repo
This commit is contained in:
commit
dcd9973243
150858 changed files with 23884658 additions and 0 deletions
19
dom/security/test/contentverifier/browser.ini
Normal file
19
dom/security/test/contentverifier/browser.ini
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
[DEFAULT]
|
||||
support-files =
|
||||
file_contentserver.sjs
|
||||
file_about_newtab.html
|
||||
file_about_newtab_bad.html
|
||||
file_about_newtab_bad_csp.html
|
||||
file_about_newtab_bad_csp_signature
|
||||
file_about_newtab_good_signature
|
||||
file_about_newtab_bad_signature
|
||||
file_about_newtab_broken_signature
|
||||
file_about_newtab_sri.html
|
||||
file_about_newtab_sri_signature
|
||||
goodChain.pem
|
||||
head.js
|
||||
script.js
|
||||
style.css
|
||||
|
||||
[browser_verify_content_about_newtab.js]
|
||||
[browser_verify_content_about_newtab2.js]
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
|
||||
const TESTS = [
|
||||
// { newtab (aboutURI) or regular load (url) : url,
|
||||
// testStrings : expected strings in the loaded page }
|
||||
{ "aboutURI" : URI_GOOD, "testStrings" : [GOOD_ABOUT_STRING] },
|
||||
{ "aboutURI" : URI_ERROR_HEADER, "testStrings" : [ABOUT_BLANK] },
|
||||
{ "url" : URI_BAD_FILE_CACHED, "testStrings" : [BAD_ABOUT_STRING] },
|
||||
{ "aboutURI" : URI_BAD_FILE_CACHED, "testStrings" : [ABOUT_BLANK] },
|
||||
{ "aboutURI" : URI_GOOD, "testStrings" : [GOOD_ABOUT_STRING] },
|
||||
{ "aboutURI" : URI_SRI, "testStrings" : [
|
||||
STYLESHEET_WITHOUT_SRI_BLOCKED,
|
||||
STYLESHEET_WITH_SRI_LOADED,
|
||||
SCRIPT_WITHOUT_SRI_BLOCKED,
|
||||
SCRIPT_WITH_SRI_LOADED,
|
||||
]},
|
||||
{ "aboutURI" : URI_BAD_CSP, "testStrings" : [CSP_TEST_SUCCESS_STRING] },
|
||||
{ "url" : URI_CLEANUP, "testStrings" : [CLEANUP_DONE] },
|
||||
];
|
||||
|
||||
add_task(runTests);
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
|
||||
const TESTS = [
|
||||
// { newtab (aboutURI) or regular load (url) : url,
|
||||
// testStrings : expected strings in the loaded page }
|
||||
{ "aboutURI" : URI_GOOD, "testStrings" : [GOOD_ABOUT_STRING] },
|
||||
{ "aboutURI" : URI_ERROR_HEADER, "testStrings" : [ABOUT_BLANK] },
|
||||
{ "aboutURI" : URI_KEYERROR_HEADER, "testStrings" : [ABOUT_BLANK] },
|
||||
{ "aboutURI" : URI_SIGERROR_HEADER, "testStrings" : [ABOUT_BLANK] },
|
||||
{ "aboutURI" : URI_NO_HEADER, "testStrings" : [ABOUT_BLANK] },
|
||||
{ "aboutURI" : URI_BAD_SIG, "testStrings" : [ABOUT_BLANK] },
|
||||
{ "aboutURI" : URI_BROKEN_SIG, "testStrings" : [ABOUT_BLANK] },
|
||||
{ "aboutURI" : URI_BAD_X5U, "testStrings" : [ABOUT_BLANK] },
|
||||
{ "aboutURI" : URI_HTTP_X5U, "testStrings" : [ABOUT_BLANK] },
|
||||
{ "aboutURI" : URI_BAD_FILE, "testStrings" : [ABOUT_BLANK] },
|
||||
{ "aboutURI" : URI_BAD_ALL, "testStrings" : [ABOUT_BLANK] },
|
||||
{ "url" : URI_CLEANUP, "testStrings" : [CLEANUP_DONE] },
|
||||
];
|
||||
|
||||
add_task(runTests);
|
||||
11
dom/security/test/contentverifier/file_about_newtab.html
Normal file
11
dom/security/test/contentverifier/file_about_newtab.html
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!-- https://bugzilla.mozilla.org/show_bug.cgi?id=1226928 -->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Testpage for bug 1226928</title>
|
||||
</head>
|
||||
<body>
|
||||
Just a fully good testpage for Bug 1226928<br/>
|
||||
</body>
|
||||
</html>
|
||||
11
dom/security/test/contentverifier/file_about_newtab_bad.html
Normal file
11
dom/security/test/contentverifier/file_about_newtab_bad.html
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!-- https://bugzilla.mozilla.org/show_bug.cgi?id=1226928 -->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Testpage for bug 1226928</title>
|
||||
</head>
|
||||
<body>
|
||||
Just a bad testpage for Bug 1226928<br/>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Testpage for CSP violation (inline script)</title>
|
||||
</head>
|
||||
<body>
|
||||
CSP violation test succeeded.
|
||||
<script>
|
||||
// This inline script would override the success string if loaded.
|
||||
document.body.innerHTML = "CSP violation test failed.";
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1 @@
|
|||
oiypz3lb-IyJsmKNsnlp2zDrqncste8yONn9WUE6ksgJWMhSEQ9lp8vRqN0W3JPwJb6uSk16RI-tDv7uy0jxon5jL1BZpqlqIpvimg7FCQEedMKoHZwtE9an-e95sOTd
|
||||
|
|
@ -0,0 +1 @@
|
|||
KirX94omQL7lKfWGhc777t8U29enDg0O0UcJLH3PRXcvWGO8KA6mmLS3yNCFnGiTjP3vNnVtm-sUkXr4ix8WTkKABkU4fEAi77sNOkLCKw40M9sDJOesmYInS_J2AuXX
|
||||
|
|
@ -0,0 +1 @@
|
|||
MGUCMFwSs3o95ukwBWXN1WbLgnpJ_uHWFiQROPm9zjrSqzlfiSMyLwJwIZzldWo_pBJtOwIxAJIfhXIiMVfl5NkFEJUUMxzu6FuxOJl5DCpG2wHLy9AhayLUzm4X4SpwZ6QBPapdTg
|
||||
|
|
@ -0,0 +1 @@
|
|||
HUndgHvxHNMiAe1SXoeyOOraUJCdxHqWkAYTu0Cq1KpAHcWZEVelNTvyXGbTLWj8btsmqNLAm08UlyK43q_2oO9DQfez3Fo8DhsKvm7TqgSXCkhUoxsYNanxWXhqw-Jw
|
||||
36
dom/security/test/contentverifier/file_about_newtab_sri.html
Normal file
36
dom/security/test/contentverifier/file_about_newtab_sri.html
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!-- https://bugzilla.mozilla.org/show_bug.cgi?id=1235572 -->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Testpage for bug 1235572</title>
|
||||
<script>
|
||||
function loaded(resource) {
|
||||
document.getElementById("result").innerHTML += resource + " loaded\n";
|
||||
}
|
||||
function blocked(resource) {
|
||||
document.getElementById("result").innerHTML += resource + " blocked\n";
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
Testing script loading without SRI for Bug 1235572<br/>
|
||||
<div id="result"></div>
|
||||
|
||||
<!-- use css1 and css2 to make urls different to avoid the resource being cached-->
|
||||
<link rel="stylesheet" href="https://example.com/browser/dom/security/test/contentverifier/file_contentserver.sjs?resource=css1"
|
||||
onload="loaded('Stylesheet without SRI')"
|
||||
onerror="blocked('Stylesheet without SRI')">
|
||||
<link rel="stylesheet" href="https://example.com/browser/dom/security/test/contentverifier/file_contentserver.sjs?resource=css2"
|
||||
integrity="sha384-/6Tvxh7SX39y62qePcvYoi5Vrf0lK8Ix3wJFLCYKI5KNJ5wIlCR8UsFC1OXwmwgd"
|
||||
onload="loaded('Stylesheet with SRI')"
|
||||
onerror="blocked('Stylesheet with SRI')">
|
||||
<script src="https://example.com/browser/dom/security/test/contentverifier/file_contentserver.sjs?resource=script"
|
||||
onload="loaded('Script without SRI')"
|
||||
onerror="blocked('Script without SRI')"></script>
|
||||
<script src="https://example.com/browser/dom/security/test/contentverifier/file_contentserver.sjs?resource=script"
|
||||
integrity="sha384-zDCkvKOHXk8mM6Nk07oOGXGME17PA4+ydFw+hq0r9kgF6ZDYFWK3fLGPEy7FoOAo"
|
||||
onload="loaded('Script with SRI')"
|
||||
onerror="blocked('Script with SRI')"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1 @@
|
|||
yoIyAYiiEzdP1zpkRy3KaqdsjUy62Notku89cytwVwcH0x6fKsMCdM-df1wbk9N28CSTaIOW5kcSenFy5K3nU-zPIoqZDjQo6aSjF8hF6lrw1a1xbhfl9K3g4YJsuWsO
|
||||
261
dom/security/test/contentverifier/file_contentserver.sjs
Normal file
261
dom/security/test/contentverifier/file_contentserver.sjs
Normal file
|
|
@ -0,0 +1,261 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
// sjs for remote about:newtab (bug 1226928)
|
||||
"use strict";
|
||||
|
||||
const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
|
||||
Cu.import("resource://gre/modules/NetUtil.jsm");
|
||||
Cu.import("resource://gre/modules/FileUtils.jsm");
|
||||
Cu.importGlobalProperties(["URLSearchParams"]);
|
||||
|
||||
const path = "browser/dom/security/test/contentverifier/";
|
||||
|
||||
const goodFileName = "file_about_newtab.html";
|
||||
const goodFileBase = path + goodFileName;
|
||||
const goodFile = FileUtils.getDir("TmpD", [], true);
|
||||
goodFile.append(goodFileName);
|
||||
const goodSignature = path + "file_about_newtab_good_signature";
|
||||
const goodX5UString = "\"https://example.com/browser/dom/security/test/contentverifier/file_contentserver.sjs?x5u=default\"";
|
||||
|
||||
const scriptFileName = "script.js";
|
||||
const cssFileName = "style.css";
|
||||
const badFile = path + "file_about_newtab_bad.html";
|
||||
const brokenSignature = path + "file_about_newtab_broken_signature";
|
||||
const badSignature = path + "file_about_newtab_bad_signature";
|
||||
const badX5UString = "\"https://example.com/browser/dom/security/test/contentverifier/file_contentserver.sjs?x5u=bad\"";
|
||||
const httpX5UString = "\"http://example.com/browser/dom/security/test/contentverifier/file_contentserver.sjs?x5u=default\"";
|
||||
|
||||
const sriFile = path + "file_about_newtab_sri.html";
|
||||
const sriSignature = path + "file_about_newtab_sri_signature";
|
||||
|
||||
const badCspFile = path + "file_about_newtab_bad_csp.html";
|
||||
const badCspSignature = path + "file_about_newtab_bad_csp_signature";
|
||||
|
||||
// This cert chain is copied from
|
||||
// security/manager/ssl/tests/unit/test_content_signing/
|
||||
// using the certificates
|
||||
// * content_signing_remote_newtab_ee.pem
|
||||
// * content_signing_int.pem
|
||||
// * content_signing_root.pem
|
||||
const goodCertChainPath = path + "goodChain.pem";
|
||||
|
||||
const tempFileNames = [goodFileName, scriptFileName, cssFileName];
|
||||
|
||||
// we copy the file to serve as newtab to a temp directory because
|
||||
// we modify it during tests.
|
||||
setupTestFiles();
|
||||
|
||||
function setupTestFiles() {
|
||||
for (let fileName of tempFileNames) {
|
||||
let tempFile = FileUtils.getDir("TmpD", [], true);
|
||||
tempFile.append(fileName);
|
||||
if (!tempFile.exists()) {
|
||||
let fileIn = getFileName(path + fileName, "CurWorkD");
|
||||
fileIn.copyTo(FileUtils.getDir("TmpD", [], true), "");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getFileName(filePath, dir) {
|
||||
// Since it's relative to the cwd of the test runner, we start there and
|
||||
// append to get to the actual path of the file.
|
||||
let testFile =
|
||||
Cc["@mozilla.org/file/directory_service;1"].
|
||||
getService(Components.interfaces.nsIProperties).
|
||||
get(dir, Components.interfaces.nsILocalFile);
|
||||
let dirs = filePath.split("/");
|
||||
for (let i = 0; i < dirs.length; i++) {
|
||||
testFile.append(dirs[i]);
|
||||
}
|
||||
return testFile;
|
||||
}
|
||||
|
||||
function loadFile(file) {
|
||||
// Load a file to return it.
|
||||
let testFileStream =
|
||||
Cc["@mozilla.org/network/file-input-stream;1"]
|
||||
.createInstance(Components.interfaces.nsIFileInputStream);
|
||||
testFileStream.init(file, -1, 0, 0);
|
||||
return NetUtil.readInputStreamToString(testFileStream,
|
||||
testFileStream.available());
|
||||
}
|
||||
|
||||
function appendToFile(aFile, content) {
|
||||
try {
|
||||
let file = FileUtils.openFileOutputStream(aFile, FileUtils.MODE_APPEND |
|
||||
FileUtils.MODE_WRONLY);
|
||||
file.write(content, content.length);
|
||||
file.close();
|
||||
} catch (e) {
|
||||
dump(">>> Error in appendToFile "+e);
|
||||
return "Error";
|
||||
}
|
||||
return "Done";
|
||||
}
|
||||
|
||||
function truncateFile(aFile, length) {
|
||||
let fileIn = loadFile(aFile);
|
||||
fileIn = fileIn.slice(0, -length);
|
||||
|
||||
try {
|
||||
let file = FileUtils.openFileOutputStream(aFile, FileUtils.MODE_WRONLY |
|
||||
FileUtils.MODE_TRUNCATE);
|
||||
file.write(fileIn, fileIn.length);
|
||||
file.close();
|
||||
} catch (e) {
|
||||
dump(">>> Error in truncateFile "+e);
|
||||
return "Error";
|
||||
}
|
||||
return "Done";
|
||||
}
|
||||
|
||||
function cleanupTestFiles() {
|
||||
for (let fileName of tempFileNames) {
|
||||
let tempFile = FileUtils.getDir("TmpD", [], true);
|
||||
tempFile.append(fileName);
|
||||
tempFile.remove(true);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* handle requests of the following form:
|
||||
* sig=good&key=good&file=good&header=good&cached=no to serve pages with
|
||||
* content signatures
|
||||
*
|
||||
* it further handles invalidateFile=yep and validateFile=yep to change the
|
||||
* served file
|
||||
*/
|
||||
function handleRequest(request, response) {
|
||||
let params = new URLSearchParams(request.queryString);
|
||||
let x5uType = params.get("x5u");
|
||||
let signatureType = params.get("sig");
|
||||
let fileType = params.get("file");
|
||||
let headerType = params.get("header");
|
||||
let cached = params.get("cached");
|
||||
let invalidateFile = params.get("invalidateFile");
|
||||
let validateFile = params.get("validateFile");
|
||||
let resource = params.get("resource");
|
||||
let x5uParam = params.get("x5u");
|
||||
|
||||
if (params.get("cleanup")) {
|
||||
cleanupTestFiles();
|
||||
response.setHeader("Content-Type", "text/html", false);
|
||||
response.write("Done");
|
||||
return;
|
||||
}
|
||||
|
||||
if (resource) {
|
||||
if (resource == "script") {
|
||||
response.setHeader("Content-Type", "application/javascript", false);
|
||||
response.write(loadFile(getFileName(scriptFileName, "TmpD")));
|
||||
} else { // resource == "css1" || resource == "css2"
|
||||
response.setHeader("Content-Type", "text/css", false);
|
||||
response.write(loadFile(getFileName(cssFileName, "TmpD")));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// if invalidateFile is set, this doesn't actually return a newtab page
|
||||
// but changes the served file to invalidate the signature
|
||||
// NOTE: make sure to make the file valid again afterwards!
|
||||
if (invalidateFile) {
|
||||
let r = "Done";
|
||||
for (let fileName of tempFileNames) {
|
||||
if (appendToFile(getFileName(fileName, "TmpD"), "!") != "Done") {
|
||||
r = "Error";
|
||||
}
|
||||
}
|
||||
response.setHeader("Content-Type", "text/html", false);
|
||||
response.write(r);
|
||||
return;
|
||||
}
|
||||
|
||||
// if validateFile is set, this doesn't actually return a newtab page
|
||||
// but changes the served file to make the signature valid again
|
||||
if (validateFile) {
|
||||
let r = "Done";
|
||||
for (let fileName of tempFileNames) {
|
||||
if (truncateFile(getFileName(fileName, "TmpD"), 1) != "Done") {
|
||||
r = "Error";
|
||||
}
|
||||
}
|
||||
response.setHeader("Content-Type", "text/html", false);
|
||||
response.write(r);
|
||||
return;
|
||||
}
|
||||
|
||||
// we have to return the certificate chain on request for the x5u parameter
|
||||
if (x5uParam && x5uParam == "default") {
|
||||
response.setHeader("Cache-Control", "max-age=216000", false);
|
||||
response.setHeader("Content-Type", "text/plain", false);
|
||||
response.write(loadFile(getFileName(goodCertChainPath, "CurWorkD")));
|
||||
return;
|
||||
}
|
||||
|
||||
// avoid confusing cache behaviours
|
||||
if (!cached) {
|
||||
response.setHeader("Cache-Control", "no-cache", false);
|
||||
} else {
|
||||
response.setHeader("Cache-Control", "max-age=3600", false);
|
||||
}
|
||||
|
||||
// send HTML to test allowed/blocked behaviours
|
||||
response.setHeader("Content-Type", "text/html", false);
|
||||
|
||||
// set signature header and key for Content-Signature header
|
||||
/* By default a good content-signature header is returned. Any broken return
|
||||
* value has to be indicated in the url.
|
||||
*/
|
||||
let csHeader = "";
|
||||
let x5uString = goodX5UString;
|
||||
let signature = goodSignature;
|
||||
let file = goodFile;
|
||||
if (x5uType == "bad") {
|
||||
x5uString = badX5UString;
|
||||
} else if (x5uType == "http") {
|
||||
x5uString = httpX5UString;
|
||||
}
|
||||
if (signatureType == "bad") {
|
||||
signature = badSignature;
|
||||
} else if (signatureType == "broken") {
|
||||
signature = brokenSignature;
|
||||
} else if (signatureType == "sri") {
|
||||
signature = sriSignature;
|
||||
} else if (signatureType == "bad-csp") {
|
||||
signature = badCspSignature;
|
||||
}
|
||||
if (fileType == "bad") {
|
||||
file = getFileName(badFile, "CurWorkD");
|
||||
} else if (fileType == "sri") {
|
||||
file = getFileName(sriFile, "CurWorkD");
|
||||
} else if (fileType == "bad-csp") {
|
||||
file = getFileName(badCspFile, "CurWorkD");
|
||||
}
|
||||
|
||||
if (headerType == "good") {
|
||||
// a valid content-signature header
|
||||
csHeader = "x5u=" + x5uString + ";p384ecdsa=" +
|
||||
loadFile(getFileName(signature, "CurWorkD"));
|
||||
} else if (headerType == "error") {
|
||||
// this content-signature header is missing ; before p384ecdsa
|
||||
csHeader = "x5u=" + x5uString + "p384ecdsa=" +
|
||||
loadFile(getFileName(signature, "CurWorkD"));
|
||||
} else if (headerType == "errorInX5U") {
|
||||
// this content-signature header is missing the keyid directive
|
||||
csHeader = "x6u=" + x5uString + ";p384ecdsa=" +
|
||||
loadFile(getFileName(signature, "CurWorkD"));
|
||||
} else if (headerType == "errorInSignature") {
|
||||
// this content-signature header is missing the p384ecdsa directive
|
||||
csHeader = "x5u=" + x5uString + ";p385ecdsa=" +
|
||||
loadFile(getFileName(signature, "CurWorkD"));
|
||||
}
|
||||
|
||||
if (csHeader) {
|
||||
response.setHeader("Content-Signature", csHeader, false);
|
||||
}
|
||||
let result = loadFile(file);
|
||||
|
||||
response.write(result);
|
||||
}
|
||||
51
dom/security/test/contentverifier/goodChain.pem
Normal file
51
dom/security/test/contentverifier/goodChain.pem
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIICUzCCAT2gAwIBAgIUJ1BtYqWRwUsVaZCGPp9eTHIC04QwCwYJKoZIhvcNAQEL
|
||||
MBExDzANBgNVBAMMBmludC1DQTAiGA8yMDE1MTEyODAwMDAwMFoYDzIwMTgwMjA1
|
||||
MDAwMDAwWjAUMRIwEAYDVQQDDAllZS1pbnQtQ0EwdjAQBgcqhkjOPQIBBgUrgQQA
|
||||
IgNiAAShaHJDNitcexiJ83kVRhWhxz+0je6GPgIpFdtgjiUt5LcTLajOmOgxU05q
|
||||
nAwLCcjWOa3oMgbluoE0c6EfozDgXajJbkOD/ieHPalxA74oiM/wAvBa9xof3cyD
|
||||
dKpuqc6jTjBMMBMGA1UdJQQMMAoGCCsGAQUFBwMDMDUGA1UdEQQuMCyCKnJlbW90
|
||||
ZW5ld3RhYi5jb250ZW50LXNpZ25hdHVyZS5tb3ppbGxhLm9yZzALBgkqhkiG9w0B
|
||||
AQsDggEBALiLck6k50ok9ahVq45P3feY1PeUXcIYZkJd8aPDYM+0kfg5+JyJBykA
|
||||
mtHWPE1QQjs7VRMfaLfu04E4UJMI2V1AON1qtgR9BQLctW85KFACg2omfiCKwJh0
|
||||
5Q8cxBFx9BpNMayqLJwHttB6oluxZFTB8CL/hfpbYpHz1bMEDCVSRP588YBrc8mV
|
||||
OLqzQK+k3ewwGvfD6SvXmTny37MxqwxdTPFJNnpqzKAsQIvz8Skic9BkA1NFk0Oq
|
||||
lsKKoiibbOCmwS9XY/laAkBaC3winuhciYAC0ImAopZ4PBCU0AOHGrNbhZXWYQxt
|
||||
uHBj34FqvIRCqgM06JCEwN0ULgix4kI=
|
||||
-----END CERTIFICATE-----
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIC0TCCAbugAwIBAgIUPcKbBQpKwTzrrlqzM+d3z5DWiNUwCwYJKoZIhvcNAQEL
|
||||
MA0xCzAJBgNVBAMMAmNhMCIYDzIwMTUxMTI4MDAwMDAwWhgPMjAxODAyMDUwMDAw
|
||||
MDBaMBExDzANBgNVBAMMBmludC1DQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
|
||||
AQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72x
|
||||
nAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk27lM
|
||||
wmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCxV5A90jvF
|
||||
4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20
|
||||
yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xx
|
||||
j5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAAaMlMCMwDAYDVR0TBAUwAwEB/zAT
|
||||
BgNVHSUEDDAKBggrBgEFBQcDAzALBgkqhkiG9w0BAQsDggEBADDPjITgz8joxLRW
|
||||
wpLxELKSgO/KQ6iAXztjMHq9ovT7Fy0fqBnQ1mMVFr+sBXLgtUCM45aip6PjhUXc
|
||||
zs5Dq5STg+kz7qtmAjEQvOPcyictbgdu/K7+uMhXQhlzhOgyW88Uk5vrAezNTc/e
|
||||
TvSmWp1FcgVAfaeMN/90nzD1KIHoUt7zqZIz9ub8jXPVzQNZq4vh33smZhmbdTdV
|
||||
DaHUyef5cR1VTEGB+L1qzUIQqpHmD4UkMNP1nYedWfauiQhRt6Ql3rJSCRuEvsOA
|
||||
iBTJlwai/EFwfyfHkOV2GNgv+A5wHHEjBtF5c4PCxQEL5Vw+mfZHLsDVqF3279ZY
|
||||
lQ6jQ9g=
|
||||
-----END CERTIFICATE-----
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIICzTCCAbegAwIBAgIUKRLJoCmk0A6PHrNc8CxFn//4BYcwCwYJKoZIhvcNAQEL
|
||||
MA0xCzAJBgNVBAMMAmNhMCIYDzIwMTUxMTI4MDAwMDAwWhgPMjAxODAyMDUwMDAw
|
||||
MDBaMA0xCzAJBgNVBAMMAmNhMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
|
||||
AQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptu
|
||||
Gobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmTqyDDSeTbuUzCa2wO
|
||||
7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXkD3SO8XguEgf
|
||||
qDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR3bTK9/yt
|
||||
HSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/Fosv5fGPmRcx
|
||||
uLP+SSP6clHEMdUDrNoYCjXtjQIDAQABoyUwIzAMBgNVHRMEBTADAQH/MBMGA1Ud
|
||||
JQQMMAoGCCsGAQUFBwMDMAsGCSqGSIb3DQEBCwOCAQEAABgMK6EyVIXTjD5qaxPO
|
||||
DWz6yREACmAQBcowKWvfhwgi27DPSXyFGDbzTPEo+7RrIcXJkVAhLouGT51fCwTZ
|
||||
zb6Sgf6ztX7VSppY9AT4utvlZKP1xQ5WhIYsMtdHCHLHIkRjeWyoBEfUx50UXNLK
|
||||
Snl+A02GKYWiX+TLLg2DPN2s7v/mm8NLMQNgUlL7KakB2FHFyPa8otPpL4llg7UJ
|
||||
iBTVQ0c3JoiVbwZaY1Z8QinfMXUrTK9egUC4BAcId1dE8glzA5RRlw1fTLWpGApt
|
||||
hUmbDnl9N2a9NhGX323ypNzIATexafipzWe7bc4u/+bFdrUqnKUoEka73pZBdHdA
|
||||
FQ==
|
||||
-----END CERTIFICATE-----
|
||||
210
dom/security/test/contentverifier/head.js
Normal file
210
dom/security/test/contentverifier/head.js
Normal file
|
|
@ -0,0 +1,210 @@
|
|||
/*
|
||||
* Test Content-Signature for remote about:newtab
|
||||
* - Bug 1226928 - allow about:newtab to load remote content
|
||||
*
|
||||
* This tests content-signature verification on remote about:newtab in the
|
||||
* following cases (see TESTS, all failed loads display about:blank fallback):
|
||||
* - good case (signature should verify and correct page is displayed)
|
||||
* - reload of newtab when the siganture was invalidated after the last correct
|
||||
* load
|
||||
* - malformed content-signature header
|
||||
* - malformed keyid directive
|
||||
* - malformed p384ecdsa directive
|
||||
* - wrong signature (this is not a siganture for the delivered document)
|
||||
* - invalid signature (this is not even a signature)
|
||||
* - loading a file that doesn't fit the key or signature
|
||||
* - cache poisoning (load a malicious remote page not in newtab, subsequent
|
||||
* newtab load has to load the fallback)
|
||||
*/
|
||||
|
||||
const ABOUT_NEWTAB_URI = "about:newtab";
|
||||
|
||||
const BASE = "https://example.com/browser/dom/security/test/contentverifier/file_contentserver.sjs?";
|
||||
const URI_GOOD = BASE + "sig=good&x5u=good&file=good&header=good";
|
||||
|
||||
const INVALIDATE_FILE = BASE + "invalidateFile=yep";
|
||||
const VALIDATE_FILE = BASE + "validateFile=yep";
|
||||
|
||||
const URI_HEADER_BASE = BASE + "sig=good&x5u=good&file=good&header=";
|
||||
const URI_ERROR_HEADER = URI_HEADER_BASE + "error";
|
||||
const URI_KEYERROR_HEADER = URI_HEADER_BASE + "errorInX5U";
|
||||
const URI_SIGERROR_HEADER = URI_HEADER_BASE + "errorInSignature";
|
||||
const URI_NO_HEADER = URI_HEADER_BASE + "noHeader";
|
||||
|
||||
const URI_BAD_SIG = BASE + "sig=bad&x5u=good&file=good&header=good";
|
||||
const URI_BROKEN_SIG = BASE + "sig=broken&x5u=good&file=good&header=good";
|
||||
const URI_BAD_X5U = BASE + "sig=good&x5u=bad&file=good&header=good";
|
||||
const URI_HTTP_X5U = BASE + "sig=good&x5u=http&file=good&header=good";
|
||||
const URI_BAD_FILE = BASE + "sig=good&x5u=good&file=bad&header=good";
|
||||
const URI_BAD_ALL = BASE + "sig=bad&x5u=bad&file=bad&header=bad";
|
||||
const URI_BAD_CSP = BASE + "sig=bad-csp&x5u=good&file=bad-csp&header=good";
|
||||
|
||||
const URI_BAD_FILE_CACHED = BASE + "sig=good&x5u=good&file=bad&header=good&cached=true";
|
||||
|
||||
const GOOD_ABOUT_STRING = "Just a fully good testpage for Bug 1226928";
|
||||
const BAD_ABOUT_STRING = "Just a bad testpage for Bug 1226928";
|
||||
const ABOUT_BLANK = "<head></head><body></body>";
|
||||
|
||||
const URI_CLEANUP = BASE + "cleanup=true";
|
||||
const CLEANUP_DONE = "Done";
|
||||
|
||||
const URI_SRI = BASE + "sig=sri&x5u=good&file=sri&header=good";
|
||||
const STYLESHEET_WITHOUT_SRI_BLOCKED = "Stylesheet without SRI blocked";
|
||||
const STYLESHEET_WITH_SRI_BLOCKED = "Stylesheet with SRI blocked";
|
||||
const STYLESHEET_WITH_SRI_LOADED = "Stylesheet with SRI loaded";
|
||||
const SCRIPT_WITHOUT_SRI_BLOCKED = "Script without SRI blocked";
|
||||
const SCRIPT_WITH_SRI_BLOCKED = "Script with SRI blocked";
|
||||
const SCRIPT_WITH_SRI_LOADED = "Script with SRI loaded";
|
||||
|
||||
const CSP_TEST_SUCCESS_STRING = "CSP violation test succeeded.";
|
||||
|
||||
// Needs to sync with pref "security.signed_content.CSP.default".
|
||||
const SIGNED_CONTENT_CSP = `{"csp-policies":[{"report-only":false,"script-src":["https://example.com","'unsafe-inline'"],"style-src":["https://example.com"]}]}`;
|
||||
|
||||
var browser = null;
|
||||
var aboutNewTabService = Cc["@mozilla.org/browser/aboutnewtab-service;1"]
|
||||
.getService(Ci.nsIAboutNewTabService);
|
||||
|
||||
function pushPrefs(...aPrefs) {
|
||||
return new Promise((resolve) => {
|
||||
SpecialPowers.pushPrefEnv({"set": aPrefs}, resolve);
|
||||
});
|
||||
}
|
||||
|
||||
/*
|
||||
* run tests with input from TESTS
|
||||
*/
|
||||
function doTest(aExpectedStrings, reload, aUrl, aNewTabPref) {
|
||||
// set about:newtab location for this test if it's a newtab test
|
||||
if (aNewTabPref) {
|
||||
aboutNewTabService.newTabURL = aNewTabPref;
|
||||
}
|
||||
|
||||
// set prefs
|
||||
yield pushPrefs(
|
||||
["browser.newtabpage.remote.content-signing-test", true],
|
||||
["browser.newtabpage.remote", true],
|
||||
["security.content.signature.root_hash",
|
||||
"CC:BE:04:87:74:B2:98:24:4A:C6:7A:71:BC:6F:DB:D6:C0:48:17:29:57:51:96:47:38:CC:24:C8:E4:F9:DD:CB"]);
|
||||
|
||||
if (aNewTabPref === URI_BAD_CSP) {
|
||||
// Use stricter CSP to test CSP violation.
|
||||
yield pushPrefs(["security.signed_content.CSP.default", "script-src 'self'; style-src 'self'"]);
|
||||
} else {
|
||||
// Use weaker CSP to test normal content.
|
||||
yield pushPrefs(["security.signed_content.CSP.default", "script-src 'self' 'unsafe-inline'; style-src 'self'"]);
|
||||
}
|
||||
|
||||
// start the test
|
||||
yield BrowserTestUtils.withNewTab({
|
||||
gBrowser,
|
||||
url: aUrl,
|
||||
},
|
||||
function * (browser) {
|
||||
// check if everything's set correct for testing
|
||||
ok(Services.prefs.getBoolPref(
|
||||
"browser.newtabpage.remote.content-signing-test"),
|
||||
"sanity check: remote newtab signing test should be used");
|
||||
ok(Services.prefs.getBoolPref("browser.newtabpage.remote"),
|
||||
"sanity check: remote newtab should be used");
|
||||
// we only check this if we really do a newtab test
|
||||
if (aNewTabPref) {
|
||||
ok(aboutNewTabService.overridden,
|
||||
"sanity check: default URL for about:newtab should be overriden");
|
||||
is(aboutNewTabService.newTabURL, aNewTabPref,
|
||||
"sanity check: default URL for about:newtab should return the new URL");
|
||||
}
|
||||
|
||||
// Every valid remote newtab page must have built-in CSP.
|
||||
let shouldHaveCSP = ((aUrl === ABOUT_NEWTAB_URI) &&
|
||||
(aNewTabPref === URI_GOOD || aNewTabPref === URI_SRI));
|
||||
|
||||
if (shouldHaveCSP) {
|
||||
is(browser.contentDocument.nodePrincipal.cspJSON, SIGNED_CONTENT_CSP,
|
||||
"Valid remote newtab page must have built-in CSP.");
|
||||
}
|
||||
|
||||
yield ContentTask.spawn(
|
||||
browser, aExpectedStrings, function * (aExpectedStrings) {
|
||||
for (let expectedString of aExpectedStrings) {
|
||||
ok(content.document.documentElement.innerHTML.includes(expectedString),
|
||||
"Expect the following value in the result\n" + expectedString +
|
||||
"\nand got " + content.document.documentElement.innerHTML);
|
||||
}
|
||||
});
|
||||
|
||||
// for good test cases we check if a reload fails if the remote page
|
||||
// changed from valid to invalid in the meantime
|
||||
if (reload) {
|
||||
yield BrowserTestUtils.withNewTab({
|
||||
gBrowser,
|
||||
url: INVALIDATE_FILE,
|
||||
},
|
||||
function * (browser2) {
|
||||
yield ContentTask.spawn(browser2, null, function * () {
|
||||
ok(content.document.documentElement.innerHTML.includes("Done"),
|
||||
"Expect the following value in the result\n" + "Done" +
|
||||
"\nand got " + content.document.documentElement.innerHTML);
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
browser.reload();
|
||||
yield BrowserTestUtils.browserLoaded(browser);
|
||||
|
||||
let expectedStrings = [ABOUT_BLANK];
|
||||
if (aNewTabPref == URI_SRI) {
|
||||
expectedStrings = [
|
||||
STYLESHEET_WITHOUT_SRI_BLOCKED,
|
||||
STYLESHEET_WITH_SRI_BLOCKED,
|
||||
SCRIPT_WITHOUT_SRI_BLOCKED,
|
||||
SCRIPT_WITH_SRI_BLOCKED
|
||||
];
|
||||
}
|
||||
yield ContentTask.spawn(browser, expectedStrings,
|
||||
function * (expectedStrings) {
|
||||
for (let expectedString of expectedStrings) {
|
||||
ok(content.document.documentElement.innerHTML.includes(expectedString),
|
||||
"Expect the following value in the result\n" + expectedString +
|
||||
"\nand got " + content.document.documentElement.innerHTML);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
yield BrowserTestUtils.withNewTab({
|
||||
gBrowser,
|
||||
url: VALIDATE_FILE,
|
||||
},
|
||||
function * (browser2) {
|
||||
yield ContentTask.spawn(browser2, null, function * () {
|
||||
ok(content.document.documentElement.innerHTML.includes("Done"),
|
||||
"Expect the following value in the result\n" + "Done" +
|
||||
"\nand got " + content.document.documentElement.innerHTML);
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function runTests() {
|
||||
// run tests from TESTS
|
||||
for (let i = 0; i < TESTS.length; i++) {
|
||||
let testCase = TESTS[i];
|
||||
let url = "", aNewTabPref = "";
|
||||
let reload = false;
|
||||
var aExpectedStrings = testCase.testStrings;
|
||||
if (testCase.aboutURI) {
|
||||
url = ABOUT_NEWTAB_URI;
|
||||
aNewTabPref = testCase.aboutURI;
|
||||
if (aNewTabPref == URI_GOOD || aNewTabPref == URI_SRI) {
|
||||
reload = true;
|
||||
}
|
||||
} else {
|
||||
url = testCase.url;
|
||||
}
|
||||
|
||||
yield doTest(aExpectedStrings, reload, url, aNewTabPref);
|
||||
}
|
||||
}
|
||||
1
dom/security/test/contentverifier/script.js
Normal file
1
dom/security/test/contentverifier/script.js
Normal file
|
|
@ -0,0 +1 @@
|
|||
var load=true;
|
||||
BIN
dom/security/test/contentverifier/signature.der
Normal file
BIN
dom/security/test/contentverifier/signature.der
Normal file
Binary file not shown.
9
dom/security/test/contentverifier/sk.pem
Normal file
9
dom/security/test/contentverifier/sk.pem
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
-----BEGIN EC PARAMETERS-----
|
||||
BgUrgQQAIg==
|
||||
-----END EC PARAMETERS-----
|
||||
-----BEGIN EC PRIVATE KEY-----
|
||||
MIGkAgEBBDAzX2TrGOr0WE92AbAl+nqnpqh25pKCLYNMTV2hJHztrkVPWOp8w0mh
|
||||
scIodK8RMpagBwYFK4EEACKhZANiAATiTcWYbt0Wg63dO7OXvpptNG0ryxv+v+Js
|
||||
JJ5Upr3pFus5fZyKxzP9NPzB+oFhL/xw3jMx7X5/vBGaQ2sJSiNlHVkqZgzYF6JQ
|
||||
4yUyiqTY7v67CyfUPA1BJg/nxOS9m3o=
|
||||
-----END EC PRIVATE KEY-----
|
||||
3
dom/security/test/contentverifier/style.css
Normal file
3
dom/security/test/contentverifier/style.css
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
#red-text {
|
||||
color: red;
|
||||
}
|
||||
49
dom/security/test/cors/file_CrossSiteXHR_cache_server.sjs
Normal file
49
dom/security/test/cors/file_CrossSiteXHR_cache_server.sjs
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
function handleRequest(request, response)
|
||||
{
|
||||
var query = {};
|
||||
request.queryString.split('&').forEach(function (val) {
|
||||
var [name, value] = val.split('=');
|
||||
query[name] = unescape(value);
|
||||
});
|
||||
|
||||
if ("setState" in query) {
|
||||
setState("test/dom/security/test_CrossSiteXHR_cache:secData",
|
||||
query.setState);
|
||||
|
||||
response.setHeader("Cache-Control", "no-cache", false);
|
||||
response.setHeader("Content-Type", "text/plain", false);
|
||||
response.write("hi");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
var isPreflight = request.method == "OPTIONS";
|
||||
|
||||
// Send response
|
||||
|
||||
secData =
|
||||
eval(getState("test/dom/security/test_CrossSiteXHR_cache:secData"));
|
||||
|
||||
if (secData.allowOrigin)
|
||||
response.setHeader("Access-Control-Allow-Origin", secData.allowOrigin);
|
||||
|
||||
if (secData.withCred)
|
||||
response.setHeader("Access-Control-Allow-Credentials", "true");
|
||||
|
||||
if (isPreflight) {
|
||||
if (secData.allowHeaders)
|
||||
response.setHeader("Access-Control-Allow-Headers", secData.allowHeaders);
|
||||
|
||||
if (secData.allowMethods)
|
||||
response.setHeader("Access-Control-Allow-Methods", secData.allowMethods);
|
||||
|
||||
if (secData.cacheTime)
|
||||
response.setHeader("Access-Control-Max-Age", secData.cacheTime.toString());
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
response.setHeader("Cache-Control", "no-cache", false);
|
||||
response.setHeader("Content-Type", "application/xml", false);
|
||||
response.write("<res>hello pass</res>\n");
|
||||
}
|
||||
121
dom/security/test/cors/file_CrossSiteXHR_inner.html
Normal file
121
dom/security/test/cors/file_CrossSiteXHR_inner.html
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
<!DOCTYPE HTML>
|
||||
<!--
|
||||
NOTE! The content of this file is duplicated in file_CrossSiteXHR_inner.jar
|
||||
and file_CrossSiteXHR_inner_data.sjs
|
||||
Please update those files if you update this one.
|
||||
-->
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<script>
|
||||
function trimString(stringValue) {
|
||||
return stringValue.replace(/^\s+|\s+$/g, '');
|
||||
};
|
||||
|
||||
window.addEventListener("message", function(e) {
|
||||
|
||||
sendData = null;
|
||||
|
||||
req = eval(e.data);
|
||||
var res = {
|
||||
didFail: false,
|
||||
events: [],
|
||||
progressEvents: 0,
|
||||
status: 0,
|
||||
responseText: "",
|
||||
statusText: "",
|
||||
responseXML: null,
|
||||
sendThrew: false
|
||||
};
|
||||
|
||||
var xhr = new XMLHttpRequest();
|
||||
for (type of ["load", "abort", "error", "loadstart", "loadend"]) {
|
||||
xhr.addEventListener(type, function(e) {
|
||||
res.events.push(e.type);
|
||||
}, false);
|
||||
}
|
||||
xhr.addEventListener("readystatechange", function(e) {
|
||||
res.events.push("rs" + xhr.readyState);
|
||||
}, false);
|
||||
xhr.addEventListener("progress", function(e) {
|
||||
res.progressEvents++;
|
||||
}, false);
|
||||
if (req.uploadProgress) {
|
||||
xhr.upload.addEventListener(req.uploadProgress, function(e) {
|
||||
res.progressEvents++;
|
||||
}, false);
|
||||
}
|
||||
xhr.onerror = function(e) {
|
||||
res.didFail = true;
|
||||
};
|
||||
xhr.onloadend = function (event) {
|
||||
res.status = xhr.status;
|
||||
try {
|
||||
res.statusText = xhr.statusText;
|
||||
} catch (e) {
|
||||
delete(res.statusText);
|
||||
}
|
||||
res.responseXML = xhr.responseXML ?
|
||||
(new XMLSerializer()).serializeToString(xhr.responseXML) :
|
||||
null;
|
||||
res.responseText = xhr.responseText;
|
||||
|
||||
res.responseHeaders = {};
|
||||
for (responseHeader in req.responseHeaders) {
|
||||
res.responseHeaders[responseHeader] =
|
||||
xhr.getResponseHeader(responseHeader);
|
||||
}
|
||||
res.allResponseHeaders = {};
|
||||
var splitHeaders = xhr.getAllResponseHeaders().split("\r\n");
|
||||
for (var i = 0; i < splitHeaders.length; i++) {
|
||||
var headerValuePair = splitHeaders[i].split(":");
|
||||
if(headerValuePair[1] != null) {
|
||||
var headerName = trimString(headerValuePair[0]);
|
||||
var headerValue = trimString(headerValuePair[1]);
|
||||
res.allResponseHeaders[headerName] = headerValue;
|
||||
}
|
||||
}
|
||||
post(e, res);
|
||||
}
|
||||
|
||||
if (req.withCred)
|
||||
xhr.withCredentials = true;
|
||||
if (req.body)
|
||||
sendData = req.body;
|
||||
|
||||
res.events.push("opening");
|
||||
// Allow passign in falsy usernames/passwords so we can test them
|
||||
try {
|
||||
xhr.open(req.method, req.url, true,
|
||||
("username" in req) ? req.username : "",
|
||||
("password" in req) ? req.password : "aa");
|
||||
} catch (ex) {
|
||||
res.didFail = true;
|
||||
post(e, res);
|
||||
}
|
||||
|
||||
for (header in req.headers) {
|
||||
xhr.setRequestHeader(header, req.headers[header]);
|
||||
}
|
||||
|
||||
res.events.push("sending");
|
||||
try {
|
||||
xhr.send(sendData);
|
||||
} catch (ex) {
|
||||
res.didFail = true;
|
||||
res.sendThrew = true;
|
||||
post(e, res);
|
||||
}
|
||||
|
||||
}, false);
|
||||
|
||||
function post(e, res) {
|
||||
e.source.postMessage(res.toSource(), "http://mochi.test:8888");
|
||||
}
|
||||
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
Inner page
|
||||
</body>
|
||||
</html>
|
||||
BIN
dom/security/test/cors/file_CrossSiteXHR_inner.jar
Normal file
BIN
dom/security/test/cors/file_CrossSiteXHR_inner.jar
Normal file
Binary file not shown.
103
dom/security/test/cors/file_CrossSiteXHR_inner_data.sjs
Normal file
103
dom/security/test/cors/file_CrossSiteXHR_inner_data.sjs
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
var data = '<!DOCTYPE HTML>\n\
|
||||
<html>\n\
|
||||
<head>\n\
|
||||
<script>\n\
|
||||
window.addEventListener("message", function(e) {\n\
|
||||
\n\
|
||||
sendData = null;\n\
|
||||
\n\
|
||||
req = eval(e.data);\n\
|
||||
var res = {\n\
|
||||
didFail: false,\n\
|
||||
events: [],\n\
|
||||
progressEvents: 0\n\
|
||||
};\n\
|
||||
\n\
|
||||
var xhr = new XMLHttpRequest();\n\
|
||||
for (type of ["load", "abort", "error", "loadstart", "loadend"]) {\n\
|
||||
xhr.addEventListener(type, function(e) {\n\
|
||||
res.events.push(e.type);\n\
|
||||
}, false);\n\
|
||||
}\n\
|
||||
xhr.addEventListener("readystatechange", function(e) {\n\
|
||||
res.events.push("rs" + xhr.readyState);\n\
|
||||
}, false);\n\
|
||||
xhr.addEventListener("progress", function(e) {\n\
|
||||
res.progressEvents++;\n\
|
||||
}, false);\n\
|
||||
if (req.uploadProgress) {\n\
|
||||
xhr.upload.addEventListener(req.uploadProgress, function(e) {\n\
|
||||
res.progressEvents++;\n\
|
||||
}, false);\n\
|
||||
}\n\
|
||||
xhr.onerror = function(e) {\n\
|
||||
res.didFail = true;\n\
|
||||
};\n\
|
||||
xhr.onloadend = function (event) {\n\
|
||||
res.status = xhr.status;\n\
|
||||
try {\n\
|
||||
res.statusText = xhr.statusText;\n\
|
||||
} catch (e) {\n\
|
||||
delete(res.statusText);\n\
|
||||
}\n\
|
||||
res.responseXML = xhr.responseXML ?\n\
|
||||
(new XMLSerializer()).serializeToString(xhr.responseXML) :\n\
|
||||
null;\n\
|
||||
res.responseText = xhr.responseText;\n\
|
||||
\n\
|
||||
res.responseHeaders = {};\n\
|
||||
for (responseHeader in req.responseHeaders) {\n\
|
||||
res.responseHeaders[responseHeader] =\n\
|
||||
xhr.getResponseHeader(responseHeader);\n\
|
||||
}\n\
|
||||
res.allResponseHeaders = {};\n\
|
||||
var splitHeaders = xhr.getAllResponseHeaders().split("\\r\\n");\n\
|
||||
for (var i = 0; i < splitHeaders.length; i++) {\n\
|
||||
var headerValuePair = splitHeaders[i].split(":");\n\
|
||||
if(headerValuePair[1] != null){\n\
|
||||
var headerName = trimString(headerValuePair[0]);\n\
|
||||
var headerValue = trimString(headerValuePair[1]); \n\
|
||||
res.allResponseHeaders[headerName] = headerValue;\n\
|
||||
}\n\
|
||||
}\n\
|
||||
post(e, res);\n\
|
||||
}\n\
|
||||
\n\
|
||||
if (req.withCred)\n\
|
||||
xhr.withCredentials = true;\n\
|
||||
if (req.body)\n\
|
||||
sendData = req.body;\n\
|
||||
\n\
|
||||
res.events.push("opening");\n\
|
||||
xhr.open(req.method, req.url, true);\n\
|
||||
\n\
|
||||
for (header in req.headers) {\n\
|
||||
xhr.setRequestHeader(header, req.headers[header]);\n\
|
||||
}\n\
|
||||
\n\
|
||||
res.events.push("sending");\n\
|
||||
xhr.send(sendData);\n\
|
||||
\n\
|
||||
}, false);\n\
|
||||
\n\
|
||||
function post(e, res) {\n\
|
||||
e.source.postMessage(res.toSource(), "*");\n\
|
||||
}\n\
|
||||
function trimString(stringValue) {\n\
|
||||
return stringValue.replace("/^\s+|\s+$/g","");\n\
|
||||
};\n\
|
||||
\n\
|
||||
</script>\n\
|
||||
</head>\n\
|
||||
<body>\n\
|
||||
Inner page\n\
|
||||
</body>\n\
|
||||
</html>'
|
||||
|
||||
function handleRequest(request, response)
|
||||
{
|
||||
response.setStatusLine(null, 302, "Follow me");
|
||||
response.setHeader("Location", "data:text/html," + escape(data));
|
||||
response.setHeader("Content-Type", "text/plain");
|
||||
response.write("Follow that guy!");
|
||||
}
|
||||
179
dom/security/test/cors/file_CrossSiteXHR_server.sjs
Normal file
179
dom/security/test/cors/file_CrossSiteXHR_server.sjs
Normal file
|
|
@ -0,0 +1,179 @@
|
|||
const CC = Components.Constructor;
|
||||
const BinaryInputStream = CC("@mozilla.org/binaryinputstream;1",
|
||||
"nsIBinaryInputStream",
|
||||
"setInputStream");
|
||||
|
||||
function handleRequest(request, response)
|
||||
{
|
||||
var query = {};
|
||||
request.queryString.split('&').forEach(function (val) {
|
||||
var [name, value] = val.split('=');
|
||||
query[name] = unescape(value);
|
||||
});
|
||||
|
||||
var isPreflight = request.method == "OPTIONS";
|
||||
|
||||
var bodyStream = new BinaryInputStream(request.bodyInputStream);
|
||||
var bodyBytes = [];
|
||||
while ((bodyAvail = bodyStream.available()) > 0)
|
||||
Array.prototype.push.apply(bodyBytes, bodyStream.readByteArray(bodyAvail));
|
||||
|
||||
var body = decodeURIComponent(
|
||||
escape(String.fromCharCode.apply(null, bodyBytes)));
|
||||
|
||||
if (query.hop) {
|
||||
query.hop = parseInt(query.hop, 10);
|
||||
hops = eval(query.hops);
|
||||
var curHop = hops[query.hop - 1];
|
||||
query.allowOrigin = curHop.allowOrigin;
|
||||
query.allowHeaders = curHop.allowHeaders;
|
||||
query.allowMethods = curHop.allowMethods;
|
||||
query.allowCred = curHop.allowCred;
|
||||
query.noAllowPreflight = curHop.noAllowPreflight;
|
||||
if (curHop.setCookie) {
|
||||
query.setCookie = unescape(curHop.setCookie);
|
||||
}
|
||||
if (curHop.cookie) {
|
||||
query.cookie = unescape(curHop.cookie);
|
||||
}
|
||||
query.noCookie = curHop.noCookie;
|
||||
}
|
||||
|
||||
// Check that request was correct
|
||||
|
||||
if (!isPreflight && query.body && body != query.body) {
|
||||
sendHttp500(response, "Wrong body. Expected " + query.body + " got " +
|
||||
body);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isPreflight && "headers" in query) {
|
||||
headers = eval(query.headers);
|
||||
for(headerName in headers) {
|
||||
// Content-Type is changed if there was a body
|
||||
if (!(headerName == "Content-Type" && body) &&
|
||||
(!request.hasHeader(headerName) ||
|
||||
request.getHeader(headerName) != headers[headerName])) {
|
||||
var actual = request.hasHeader(headerName) ? request.getHeader(headerName)
|
||||
: "<missing header>";
|
||||
sendHttp500(response,
|
||||
"Header " + headerName + " had wrong value. Expected " +
|
||||
headers[headerName] + " got " + actual);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isPreflight && "requestHeaders" in query &&
|
||||
request.getHeader("Access-Control-Request-Headers") != query.requestHeaders) {
|
||||
sendHttp500(response,
|
||||
"Access-Control-Request-Headers had wrong value. Expected " +
|
||||
query.requestHeaders + " got " +
|
||||
request.getHeader("Access-Control-Request-Headers"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (isPreflight && "requestMethod" in query &&
|
||||
request.getHeader("Access-Control-Request-Method") != query.requestMethod) {
|
||||
sendHttp500(response,
|
||||
"Access-Control-Request-Method had wrong value. Expected " +
|
||||
query.requestMethod + " got " +
|
||||
request.getHeader("Access-Control-Request-Method"));
|
||||
return;
|
||||
}
|
||||
|
||||
if ("origin" in query && request.getHeader("Origin") != query.origin) {
|
||||
sendHttp500(response,
|
||||
"Origin had wrong value. Expected " + query.origin + " got " +
|
||||
request.getHeader("Origin"));
|
||||
return;
|
||||
}
|
||||
|
||||
if ("cookie" in query) {
|
||||
cookies = {};
|
||||
request.getHeader("Cookie").split(/ *; */).forEach(function (val) {
|
||||
var [name, value] = val.split('=');
|
||||
cookies[name] = unescape(value);
|
||||
});
|
||||
|
||||
query.cookie.split(",").forEach(function (val) {
|
||||
var [name, value] = val.split('=');
|
||||
if (cookies[name] != value) {
|
||||
sendHttp500(response,
|
||||
"Cookie " + name + " had wrong value. Expected " + value +
|
||||
" got " + cookies[name]);
|
||||
return;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (query.noCookie && request.hasHeader("Cookie")) {
|
||||
sendHttp500(response,
|
||||
"Got cookies when didn't expect to: " + request.getHeader("Cookie"));
|
||||
return;
|
||||
}
|
||||
|
||||
// Send response
|
||||
|
||||
if (!isPreflight && query.status) {
|
||||
response.setStatusLine(null, query.status, query.statusMessage);
|
||||
}
|
||||
if (isPreflight && query.preflightStatus) {
|
||||
response.setStatusLine(null, query.preflightStatus, "preflight status");
|
||||
}
|
||||
|
||||
if (query.allowOrigin && (!isPreflight || !query.noAllowPreflight))
|
||||
response.setHeader("Access-Control-Allow-Origin", query.allowOrigin);
|
||||
|
||||
if (query.allowCred)
|
||||
response.setHeader("Access-Control-Allow-Credentials", "true");
|
||||
|
||||
if (query.setCookie)
|
||||
response.setHeader("Set-Cookie", query.setCookie + "; path=/");
|
||||
|
||||
if (isPreflight) {
|
||||
if (query.allowHeaders)
|
||||
response.setHeader("Access-Control-Allow-Headers", query.allowHeaders);
|
||||
|
||||
if (query.allowMethods)
|
||||
response.setHeader("Access-Control-Allow-Methods", query.allowMethods);
|
||||
}
|
||||
else {
|
||||
if (query.responseHeaders) {
|
||||
let responseHeaders = eval(query.responseHeaders);
|
||||
for (let responseHeader in responseHeaders) {
|
||||
response.setHeader(responseHeader, responseHeaders[responseHeader]);
|
||||
}
|
||||
}
|
||||
|
||||
if (query.exposeHeaders)
|
||||
response.setHeader("Access-Control-Expose-Headers", query.exposeHeaders);
|
||||
}
|
||||
|
||||
if (!isPreflight && query.hop && query.hop < hops.length) {
|
||||
newURL = hops[query.hop].server +
|
||||
"/tests/dom/security/test/cors/file_CrossSiteXHR_server.sjs?" +
|
||||
"hop=" + (query.hop + 1) + "&hops=" + escape(query.hops);
|
||||
if ("headers" in query) {
|
||||
newURL += "&headers=" + escape(query.headers);
|
||||
}
|
||||
response.setStatusLine(null, 307, "redirect");
|
||||
response.setHeader("Location", newURL);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Send response body
|
||||
if (!isPreflight && request.method != "HEAD") {
|
||||
response.setHeader("Content-Type", "application/xml", false);
|
||||
response.write("<res>hello pass</res>\n");
|
||||
}
|
||||
if (isPreflight && "preflightBody" in query) {
|
||||
response.setHeader("Content-Type", "text/plain", false);
|
||||
response.write(query.preflightBody);
|
||||
}
|
||||
}
|
||||
|
||||
function sendHttp500(response, text) {
|
||||
response.setStatusLine(null, 500, text);
|
||||
}
|
||||
11
dom/security/test/cors/mochitest.ini
Normal file
11
dom/security/test/cors/mochitest.ini
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
[DEFAULT]
|
||||
support-files =
|
||||
file_CrossSiteXHR_cache_server.sjs
|
||||
file_CrossSiteXHR_inner.html
|
||||
file_CrossSiteXHR_inner.jar
|
||||
file_CrossSiteXHR_inner_data.sjs
|
||||
file_CrossSiteXHR_server.sjs
|
||||
|
||||
[test_CrossSiteXHR.html]
|
||||
[test_CrossSiteXHR_cache.html]
|
||||
[test_CrossSiteXHR_origin.html]
|
||||
1461
dom/security/test/cors/test_CrossSiteXHR.html
Normal file
1461
dom/security/test/cors/test_CrossSiteXHR.html
Normal file
File diff suppressed because it is too large
Load diff
587
dom/security/test/cors/test_CrossSiteXHR_cache.html
Normal file
587
dom/security/test/cors/test_CrossSiteXHR_cache.html
Normal file
|
|
@ -0,0 +1,587 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=utf-8">
|
||||
<title>Test for Cross Site XMLHttpRequest</title>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body onload="gen.next()">
|
||||
<p id="display">
|
||||
<iframe id=loader></iframe>
|
||||
</p>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script class="testbody" type="application/javascript;version=1.7">
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
SimpleTest.requestFlakyTimeout("This test needs to generate artificial pauses, hence it uses timeouts. There is no way around it, unfortunately. :(");
|
||||
|
||||
window.addEventListener("message", function(e) {
|
||||
gen.send(e.data);
|
||||
}, false);
|
||||
|
||||
gen = runTest();
|
||||
|
||||
function runTest() {
|
||||
var loader = document.getElementById('loader');
|
||||
var loaderWindow = loader.contentWindow;
|
||||
loader.onload = function () { gen.next() };
|
||||
|
||||
loader.src = "http://example.org/tests/dom/security/test/cors/file_CrossSiteXHR_inner.html";
|
||||
origin = "http://example.org";
|
||||
yield undefined;
|
||||
|
||||
tests = [{ pass: 0,
|
||||
method: "GET",
|
||||
headers: { "x-my-header": "myValue" },
|
||||
},
|
||||
{ pass: 1,
|
||||
method: "GET",
|
||||
headers: { "x-my-header": "myValue" },
|
||||
allowHeaders: "x-my-header",
|
||||
cacheTime: 3600
|
||||
},
|
||||
{ pass: 1,
|
||||
method: "GET",
|
||||
headers: { "x-my-header": "myValue" },
|
||||
},
|
||||
{ pass: 1,
|
||||
method: "GET",
|
||||
headers: { "x-my-header": "myValue" },
|
||||
},
|
||||
{ pass: 0,
|
||||
method: "GET",
|
||||
headers: { "x-my-header": "myValue",
|
||||
"y-my-header": "second" },
|
||||
},
|
||||
{ pass: 1,
|
||||
method: "GET",
|
||||
headers: { "y-my-header": "hello" },
|
||||
allowHeaders: "y-my-header",
|
||||
},
|
||||
{ pass: 0,
|
||||
method: "GET",
|
||||
headers: { "y-my-header": "hello" },
|
||||
},
|
||||
{ pass: 1,
|
||||
method: "GET",
|
||||
headers: { "y-my-header": "hello" },
|
||||
allowHeaders: "y-my-header,x-my-header",
|
||||
cacheTime: 3600,
|
||||
},
|
||||
{ pass: 1,
|
||||
method: "GET",
|
||||
headers: { "x-my-header": "myValue",
|
||||
"y-my-header": "second" },
|
||||
},
|
||||
{ newTest: "*******" },
|
||||
{ pass: 0,
|
||||
method: "GET",
|
||||
headers: { "x-my-header": "myValue" },
|
||||
},
|
||||
{ pass: 1,
|
||||
method: "GET",
|
||||
headers: { "x-my-header": "myValue" },
|
||||
allowHeaders: "x-my-header",
|
||||
cacheTime: 2
|
||||
},
|
||||
{ pause: 2.1 },
|
||||
{ pass: 0,
|
||||
method: "GET",
|
||||
headers: { "x-my-header": "myValue" },
|
||||
},
|
||||
{ newTest: "*******" },
|
||||
{ pass: 1,
|
||||
method: "GET",
|
||||
headers: { "x-my-header": "myValue" },
|
||||
allowHeaders: "x-my-header, y-my-header",
|
||||
cacheTime: 3600
|
||||
},
|
||||
{ pass: 1,
|
||||
method: "GET",
|
||||
headers: { "x-my-header": "myValue" },
|
||||
},
|
||||
{ pass: 1,
|
||||
method: "GET",
|
||||
headers: { "y-my-header": "myValue" },
|
||||
},
|
||||
{ pass: 0,
|
||||
method: "GET",
|
||||
headers: { "z-my-header": "myValue" },
|
||||
},
|
||||
{ newTest: "*******" },
|
||||
{ pass: 1,
|
||||
method: "GET",
|
||||
headers: { "x-my-header": "myValue" },
|
||||
allowHeaders: "x-my-header",
|
||||
cacheTime: "\t 3600 \t ",
|
||||
},
|
||||
{ pass: 1,
|
||||
method: "GET",
|
||||
headers: { "x-my-header": "myValue" },
|
||||
},
|
||||
{ newTest: "*******" },
|
||||
{ pass: 1,
|
||||
method: "GET",
|
||||
headers: { "x-my-header": "myValue" },
|
||||
allowHeaders: "x-my-header",
|
||||
cacheTime: "3600 3",
|
||||
},
|
||||
{ pass: 0,
|
||||
method: "GET",
|
||||
headers: { "x-my-header": "myValue" },
|
||||
},
|
||||
{ newTest: "*******" },
|
||||
{ pass: 1,
|
||||
method: "GET",
|
||||
headers: { "x-my-header": "myValue" },
|
||||
allowHeaders: "x-my-header",
|
||||
cacheTime: "asdf",
|
||||
},
|
||||
{ pass: 0,
|
||||
method: "GET",
|
||||
headers: { "x-my-header": "myValue" },
|
||||
},
|
||||
{ newTest: "*******" },
|
||||
{ pass: 1,
|
||||
method: "GET",
|
||||
headers: { "first-header": "myValue" },
|
||||
allowHeaders: "first-header",
|
||||
cacheTime: 2,
|
||||
},
|
||||
{ pass: 1,
|
||||
method: "GET",
|
||||
headers: { "second-header": "myValue" },
|
||||
allowHeaders: "second-header",
|
||||
cacheTime: 3600,
|
||||
},
|
||||
{ pass: 1,
|
||||
method: "GET",
|
||||
headers: { "third-header": "myValue" },
|
||||
allowHeaders: "third-header",
|
||||
cacheTime: 2,
|
||||
},
|
||||
{ pause: 2.1 },
|
||||
{ pass: 1,
|
||||
method: "GET",
|
||||
headers: { "second-header": "myValue" },
|
||||
},
|
||||
{ pass: 0,
|
||||
method: "GET",
|
||||
headers: { "first-header": "myValue" },
|
||||
},
|
||||
{ newTest: "*******" },
|
||||
{ pass: 1,
|
||||
method: "GET",
|
||||
headers: { "first-header": "myValue" },
|
||||
allowHeaders: "first-header",
|
||||
cacheTime: 2,
|
||||
},
|
||||
{ pass: 1,
|
||||
method: "GET",
|
||||
headers: { "second-header": "myValue" },
|
||||
allowHeaders: "second-header",
|
||||
cacheTime: 3600,
|
||||
},
|
||||
{ pass: 1,
|
||||
method: "GET",
|
||||
headers: { "third-header": "myValue" },
|
||||
allowHeaders: "third-header",
|
||||
cacheTime: 2,
|
||||
},
|
||||
{ pause: 2.1 },
|
||||
{ pass: 1,
|
||||
method: "GET",
|
||||
headers: { "second-header": "myValue" },
|
||||
},
|
||||
{ pass: 0,
|
||||
method: "GET",
|
||||
headers: { "third-header": "myValue" },
|
||||
},
|
||||
{ newTest: "*******" },
|
||||
{ pass: 0,
|
||||
method: "DELETE",
|
||||
},
|
||||
{ pass: 1,
|
||||
method: "DELETE",
|
||||
allowMethods: "DELETE",
|
||||
cacheTime: 3600
|
||||
},
|
||||
{ pass: 1,
|
||||
method: "DELETE",
|
||||
},
|
||||
{ pass: 1,
|
||||
method: "DELETE",
|
||||
},
|
||||
{ pass: 0,
|
||||
method: "PATCH",
|
||||
},
|
||||
{ pass: 1,
|
||||
method: "PATCH",
|
||||
allowMethods: "PATCH",
|
||||
},
|
||||
{ pass: 0,
|
||||
method: "PATCH",
|
||||
},
|
||||
{ pass: 1,
|
||||
method: "PATCH",
|
||||
allowMethods: "PATCH",
|
||||
cacheTime: 3600,
|
||||
},
|
||||
{ pass: 1,
|
||||
method: "PATCH",
|
||||
},
|
||||
{ pass: 0,
|
||||
method: "DELETE",
|
||||
},
|
||||
{ pass: 0,
|
||||
method: "PUT",
|
||||
},
|
||||
{ newTest: "*******" },
|
||||
{ pass: 0,
|
||||
method: "DELETE",
|
||||
},
|
||||
{ pass: 1,
|
||||
method: "DELETE",
|
||||
allowMethods: "DELETE",
|
||||
cacheTime: 2
|
||||
},
|
||||
{ pause: 2.1 },
|
||||
{ pass: 0,
|
||||
method: "DELETE",
|
||||
},
|
||||
{ newTest: "*******" },
|
||||
{ pass: 1,
|
||||
method: "DELETE",
|
||||
allowMethods: "DELETE, PUT",
|
||||
cacheTime: 3600
|
||||
},
|
||||
{ pass: 1,
|
||||
method: "DELETE",
|
||||
},
|
||||
{ pass: 1,
|
||||
method: "PUT",
|
||||
},
|
||||
{ pass: 0,
|
||||
method: "PATCH",
|
||||
},
|
||||
{ newTest: "*******" },
|
||||
{ pass: 1,
|
||||
method: "FIRST",
|
||||
allowMethods: "FIRST",
|
||||
cacheTime: 2,
|
||||
},
|
||||
{ pass: 1,
|
||||
method: "SECOND",
|
||||
allowMethods: "SECOND",
|
||||
cacheTime: 3600,
|
||||
},
|
||||
{ pass: 1,
|
||||
method: "THIRD",
|
||||
allowMethods: "THIRD",
|
||||
cacheTime: 2,
|
||||
},
|
||||
{ pause: 2.1 },
|
||||
{ pass: 1,
|
||||
method: "SECOND",
|
||||
},
|
||||
{ pass: 0,
|
||||
method: "FIRST",
|
||||
},
|
||||
{ newTest: "*******" },
|
||||
{ pass: 1,
|
||||
method: "FIRST",
|
||||
allowMethods: "FIRST",
|
||||
cacheTime: 2,
|
||||
},
|
||||
{ pass: 1,
|
||||
method: "SECOND",
|
||||
allowMethods: "SECOND",
|
||||
cacheTime: 3600,
|
||||
},
|
||||
{ pass: 1,
|
||||
method: "THIRD",
|
||||
allowMethods: "THIRD",
|
||||
cacheTime: 2,
|
||||
},
|
||||
{ pause: 2.1 },
|
||||
{ pass: 1,
|
||||
method: "SECOND",
|
||||
},
|
||||
{ pass: 0,
|
||||
method: "THIRD",
|
||||
},
|
||||
{ newTest: "*******" },
|
||||
{ pass: 1,
|
||||
method: "GET",
|
||||
headers: { "x-my-header": "x-value" },
|
||||
allowHeaders: "x-my-header",
|
||||
cacheTime: 3600,
|
||||
},
|
||||
{ pass: 1,
|
||||
method: "GET",
|
||||
headers: { "x-my-header": "x-value" }
|
||||
},
|
||||
{ pass: 0,
|
||||
method: "GET",
|
||||
headers: { "y-my-header": "y-value" }
|
||||
},
|
||||
{ pass: 0,
|
||||
method: "GET",
|
||||
headers: { "x-my-header": "x-value" }
|
||||
},
|
||||
{ newTest: "*******" },
|
||||
{ pass: 1,
|
||||
method: "GET",
|
||||
headers: { "x-my-header": "x-value" },
|
||||
allowHeaders: "x-my-header",
|
||||
cacheTime: 3600,
|
||||
},
|
||||
{ pass: 1,
|
||||
method: "GET",
|
||||
headers: { "x-my-header": "x-value" },
|
||||
},
|
||||
{ pass: 0,
|
||||
method: "PUT",
|
||||
},
|
||||
{ pass: 0,
|
||||
method: "GET",
|
||||
headers: { "x-my-header": "x-value" },
|
||||
},
|
||||
{ newTest: "*******" },
|
||||
{ pass: 1,
|
||||
method: "GET",
|
||||
headers: { "x-my-header": "x-value" },
|
||||
allowHeaders: "x-my-header",
|
||||
cacheTime: 3600,
|
||||
},
|
||||
{ pass: 1,
|
||||
method: "GET",
|
||||
headers: { "x-my-header": "x-value" },
|
||||
},
|
||||
{ pass: 0,
|
||||
method: "GET",
|
||||
noOrigin: 1,
|
||||
},
|
||||
{ pass: 0,
|
||||
method: "GET",
|
||||
headers: { "x-my-header": "x-value" },
|
||||
},
|
||||
{ newTest: "*******" },
|
||||
{ pass: 1,
|
||||
method: "DELETE",
|
||||
allowMethods: "DELETE",
|
||||
cacheTime: 3600,
|
||||
},
|
||||
{ pass: 1,
|
||||
method: "DELETE"
|
||||
},
|
||||
{ pass: 0,
|
||||
method: "PUT"
|
||||
},
|
||||
{ pass: 0,
|
||||
method: "DELETE"
|
||||
},
|
||||
{ newTest: "*******" },
|
||||
{ pass: 1,
|
||||
method: "DELETE",
|
||||
allowMethods: "DELETE",
|
||||
cacheTime: 3600,
|
||||
},
|
||||
{ pass: 1,
|
||||
method: "DELETE"
|
||||
},
|
||||
{ pass: 0,
|
||||
method: "DELETE",
|
||||
headers: { "my-header": "value" },
|
||||
},
|
||||
{ pass: 0,
|
||||
method: "DELETE"
|
||||
},
|
||||
{ newTest: "*******" },
|
||||
{ pass: 1,
|
||||
method: "DELETE",
|
||||
allowMethods: "DELETE",
|
||||
cacheTime: 3600,
|
||||
},
|
||||
{ pass: 1,
|
||||
method: "DELETE"
|
||||
},
|
||||
{ pass: 0,
|
||||
method: "GET",
|
||||
noOrigin: 1,
|
||||
},
|
||||
{ pass: 0,
|
||||
method: "DELETE"
|
||||
},
|
||||
{ newTest: "*******" },
|
||||
{ pass: 1,
|
||||
method: "GET",
|
||||
withCred: true,
|
||||
headers: { "x-my-header": "myValue" },
|
||||
allowHeaders: "x-my-header",
|
||||
cacheTime: 3600
|
||||
},
|
||||
{ pass: 1,
|
||||
method: "GET",
|
||||
withCred: true,
|
||||
headers: { "x-my-header": "myValue" },
|
||||
},
|
||||
{ pass: 0,
|
||||
method: "GET",
|
||||
headers: { "x-my-header": "myValue" },
|
||||
},
|
||||
{ newTest: "*******" },
|
||||
{ pass: 1,
|
||||
method: "GET",
|
||||
withCred: true,
|
||||
headers: { "x-my-header": "myValue" },
|
||||
allowHeaders: "x-my-header",
|
||||
cacheTime: 3600
|
||||
},
|
||||
{ pass: 1,
|
||||
method: "GET",
|
||||
headers: { "y-my-header": "myValue" },
|
||||
allowHeaders: "y-my-header",
|
||||
cacheTime: 2
|
||||
},
|
||||
{ pass: 1,
|
||||
method: "GET",
|
||||
headers: { "y-my-header": "myValue" },
|
||||
},
|
||||
{ pass: 1,
|
||||
method: "GET",
|
||||
withCred: true,
|
||||
headers: { "x-my-header": "myValue" },
|
||||
},
|
||||
{ pause: 2.1 },
|
||||
{ pass: 1,
|
||||
method: "GET",
|
||||
withCred: true,
|
||||
headers: { "x-my-header": "myValue" },
|
||||
},
|
||||
{ pass: 0,
|
||||
method: "GET",
|
||||
headers: { "x-my-header": "myValue" },
|
||||
},
|
||||
{ pass: 0,
|
||||
method: "GET",
|
||||
headers: { "y-my-header": "myValue" },
|
||||
},
|
||||
{ pass: 0,
|
||||
method: "GET",
|
||||
withCred: true,
|
||||
headers: { "y-my-header": "myValue" },
|
||||
},
|
||||
{ newTest: "*******" },
|
||||
{ pass: 1,
|
||||
method: "DELETE",
|
||||
allowMethods: "DELETE",
|
||||
cacheTime: 3600
|
||||
},
|
||||
{ pass: 0,
|
||||
method: "GET",
|
||||
headers: { "DELETE": "myvalue" },
|
||||
},
|
||||
{ newTest: "*******" },
|
||||
{ pass: 1,
|
||||
method: "GET",
|
||||
headers: { "x-my-header": "myValue" },
|
||||
allowHeaders: "x-my-header",
|
||||
cacheTime: 3600
|
||||
},
|
||||
{ pass: 0,
|
||||
method: "3600",
|
||||
headers: { "x-my-header": "myvalue" },
|
||||
},
|
||||
];
|
||||
|
||||
for (let i = 0; i < 110; i++) {
|
||||
tests.push({ newTest: "*******" },
|
||||
{ pass: 1,
|
||||
method: "DELETE",
|
||||
allowMethods: "DELETE",
|
||||
cacheTime: 3600,
|
||||
});
|
||||
}
|
||||
|
||||
baseURL = "http://mochi.test:8888/tests/dom/security/test/cors/" +
|
||||
"file_CrossSiteXHR_cache_server.sjs?";
|
||||
setStateURL = baseURL + "setState=";
|
||||
|
||||
var unique = Date.now();
|
||||
for (test of tests) {
|
||||
if (test.newTest) {
|
||||
unique++;
|
||||
continue;
|
||||
}
|
||||
if (test.pause) {
|
||||
setTimeout(function() { gen.next() }, test.pause * 1000);
|
||||
yield undefined;
|
||||
continue;
|
||||
}
|
||||
|
||||
req = {
|
||||
url: baseURL + "c=" + unique,
|
||||
method: test.method,
|
||||
headers: test.headers,
|
||||
withCred: test.withCred,
|
||||
};
|
||||
|
||||
sec = { allowOrigin: test.noOrigin ? "" : origin,
|
||||
allowHeaders: test.allowHeaders,
|
||||
allowMethods: test.allowMethods,
|
||||
cacheTime: test.cacheTime,
|
||||
withCred: test.withCred };
|
||||
xhr = new XMLHttpRequest();
|
||||
xhr.open("POST", setStateURL + escape(sec.toSource()), true);
|
||||
xhr.onloadend = function() { gen.next(); }
|
||||
xhr.send();
|
||||
yield undefined;
|
||||
|
||||
loaderWindow.postMessage(req.toSource(), origin);
|
||||
|
||||
res = eval(yield);
|
||||
|
||||
testName = test.toSource() + " (index " + tests.indexOf(test) + ")";
|
||||
|
||||
if (test.pass) {
|
||||
is(res.didFail, false,
|
||||
"shouldn't have failed in test for " + testName);
|
||||
is(res.status, 200, "wrong status in test for " + testName);
|
||||
is(res.responseXML, "<res>hello pass</res>",
|
||||
"wrong responseXML in test for " + testName);
|
||||
is(res.responseText, "<res>hello pass</res>\n",
|
||||
"wrong responseText in test for " + testName);
|
||||
is(res.events.join(","),
|
||||
"opening,rs1,sending,loadstart,rs2,rs3,rs4,load,loadend",
|
||||
"wrong events in test for " + testName);
|
||||
}
|
||||
else {
|
||||
is(res.didFail, true,
|
||||
"should have failed in test for " + testName);
|
||||
is(res.status, 0, "wrong status in test for " + testName);
|
||||
is(res.responseXML, null,
|
||||
"wrong responseXML in test for " + testName);
|
||||
is(res.responseText, "",
|
||||
"wrong responseText in test for " + testName);
|
||||
is(res.events.join(","),
|
||||
"opening,rs1,sending,loadstart,rs2,rs4,error,loadend",
|
||||
"wrong events in test for " + testName);
|
||||
is(res.progressEvents, 0,
|
||||
"wrong events in test for " + testName);
|
||||
}
|
||||
}
|
||||
|
||||
SimpleTest.finish();
|
||||
|
||||
yield undefined;
|
||||
}
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
||||
174
dom/security/test/cors/test_CrossSiteXHR_origin.html
Normal file
174
dom/security/test/cors/test_CrossSiteXHR_origin.html
Normal file
|
|
@ -0,0 +1,174 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=utf-8">
|
||||
<title>Test for Cross Site XMLHttpRequest</title>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<p id="display">
|
||||
<iframe id=loader></iframe>
|
||||
</p>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script class="testbody" type="application/javascript;version=1.8">
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
SimpleTest.requestLongerTimeout(2);
|
||||
|
||||
var origins =
|
||||
[{ server: 'http://example.org' },
|
||||
{ server: 'http://example.org:80',
|
||||
origin: 'http://example.org'
|
||||
},
|
||||
{ server: 'http://sub1.test1.example.org' },
|
||||
{ server: 'http://test2.example.org:8000' },
|
||||
{ server: 'http://sub1.\xe4lt.example.org:8000',
|
||||
origin: 'http://sub1.xn--lt-uia.example.org:8000'
|
||||
},
|
||||
{ server: 'http://sub2.\xe4lt.example.org',
|
||||
origin: 'http://sub2.xn--lt-uia.example.org'
|
||||
},
|
||||
{ server: 'http://ex\xe4mple.test',
|
||||
origin: 'http://xn--exmple-cua.test'
|
||||
},
|
||||
{ server: 'http://xn--exmple-cua.test' },
|
||||
{ server: 'http://\u03c0\u03b1\u03c1\u03ac\u03b4\u03b5\u03b9\u03b3\u03bc\u03b1.\u03b4\u03bf\u03ba\u03b9\u03bc\u03ae',
|
||||
origin: 'http://xn--hxajbheg2az3al.xn--jxalpdlp'
|
||||
},
|
||||
{ origin: 'http://example.org',
|
||||
file: 'jar:http://example.org/tests/dom/security/test/cors/file_CrossSiteXHR_inner.jar!/file_CrossSiteXHR_inner.html'
|
||||
},
|
||||
{ origin: 'null',
|
||||
file: 'http://example.org/tests/dom/security/test/cors/file_CrossSiteXHR_inner_data.sjs'
|
||||
},
|
||||
];
|
||||
|
||||
//['https://example.com:443'],
|
||||
//['https://sub1.test1.example.com:443'],
|
||||
|
||||
window.addEventListener("message", function(e) {
|
||||
gen.send(e.data);
|
||||
}, false);
|
||||
|
||||
gen = runTest();
|
||||
|
||||
function runTest() {
|
||||
var loader = document.getElementById('loader');
|
||||
var loaderWindow = loader.contentWindow;
|
||||
loader.onload = function () { gen.next() };
|
||||
|
||||
// Test preflight-less requests
|
||||
basePath = "/tests/dom/security/test/cors/file_CrossSiteXHR_server.sjs?"
|
||||
baseURL = "http://mochi.test:8888" + basePath;
|
||||
|
||||
for (originEntry of origins) {
|
||||
origin = originEntry.origin || originEntry.server;
|
||||
|
||||
loader.src = originEntry.file ||
|
||||
(originEntry.server + "/tests/dom/security/test/cors/file_CrossSiteXHR_inner.html");
|
||||
yield undefined;
|
||||
|
||||
var isNullOrigin = origin == "null";
|
||||
|
||||
port = /:\d+/;
|
||||
passTests = [
|
||||
origin,
|
||||
"*",
|
||||
" \t " + origin + "\t \t",
|
||||
"\t \t* \t ",
|
||||
];
|
||||
failTests = [
|
||||
"",
|
||||
" ",
|
||||
port.test(origin) ? origin.replace(port, "")
|
||||
: origin + ":1234",
|
||||
port.test(origin) ? origin.replace(port, ":")
|
||||
: origin + ":",
|
||||
origin + ".",
|
||||
origin + "/",
|
||||
origin + "#",
|
||||
origin + "?",
|
||||
origin + "\\",
|
||||
origin + "%",
|
||||
origin + "@",
|
||||
origin + "/hello",
|
||||
"foo:bar@" + origin,
|
||||
"* " + origin,
|
||||
origin + " " + origin,
|
||||
"allow <" + origin + ">",
|
||||
"<" + origin + ">",
|
||||
"<*>",
|
||||
origin.substr(0, 5) == "https" ? origin.replace("https", "http")
|
||||
: origin.replace("http", "https"),
|
||||
origin.replace("://", "://www."),
|
||||
origin.replace("://", ":// "),
|
||||
origin.replace(/\/[^.]+\./, "/"),
|
||||
];
|
||||
|
||||
if (isNullOrigin) {
|
||||
passTests = ["*", "\t \t* \t ", "null"];
|
||||
failTests = failTests.filter(function(v) { return v != origin });
|
||||
}
|
||||
|
||||
for (allowOrigin of passTests) {
|
||||
req = {
|
||||
url: baseURL +
|
||||
"allowOrigin=" + escape(allowOrigin) +
|
||||
"&origin=" + escape(origin),
|
||||
method: "GET",
|
||||
};
|
||||
loaderWindow.postMessage(req.toSource(), isNullOrigin ? "*" : origin);
|
||||
|
||||
res = eval(yield);
|
||||
is(res.didFail, false, "shouldn't have failed for " + allowOrigin);
|
||||
is(res.status, 200, "wrong status for " + allowOrigin);
|
||||
is(res.statusText, "OK", "wrong status text for " + allowOrigin);
|
||||
is(res.responseXML,
|
||||
"<res>hello pass</res>",
|
||||
"wrong responseXML in test for " + allowOrigin);
|
||||
is(res.responseText, "<res>hello pass</res>\n",
|
||||
"wrong responseText in test for " + allowOrigin);
|
||||
is(res.events.join(","),
|
||||
"opening,rs1,sending,loadstart,rs2,rs3,rs4,load,loadend",
|
||||
"wrong responseText in test for " + allowOrigin);
|
||||
}
|
||||
|
||||
for (allowOrigin of failTests) {
|
||||
req = {
|
||||
url: baseURL + "allowOrigin=" + escape(allowOrigin),
|
||||
method: "GET",
|
||||
};
|
||||
loaderWindow.postMessage(req.toSource(), isNullOrigin ? "*" : origin);
|
||||
|
||||
res = eval(yield);
|
||||
is(res.didFail, true, "should have failed for " + allowOrigin);
|
||||
is(res.responseText, "", "should have no text for " + allowOrigin);
|
||||
is(res.status, 0, "should have no status for " + allowOrigin);
|
||||
is(res.statusText, "", "wrong status text for " + allowOrigin);
|
||||
is(res.responseXML, null, "should have no XML for " + allowOrigin);
|
||||
is(res.events.join(","),
|
||||
"opening,rs1,sending,loadstart,rs2,rs4,error,loadend",
|
||||
"wrong events in test for " + allowOrigin);
|
||||
is(res.progressEvents, 0,
|
||||
"wrong events in test for " + allowOrigin);
|
||||
}
|
||||
}
|
||||
|
||||
SimpleTest.finish();
|
||||
|
||||
yield undefined;
|
||||
}
|
||||
|
||||
addLoadEvent(function() {
|
||||
SpecialPowers.pushPrefEnv({"set": [["network.jar.block-remote-files", false]]}, function() {
|
||||
gen.next();
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
||||
13
dom/security/test/csp/browser.ini
Normal file
13
dom/security/test/csp/browser.ini
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
[DEFAULT]
|
||||
support-files =
|
||||
!/dom/security/test/csp/file_testserver.sjs
|
||||
!/dom/security/test/csp/file_web_manifest.html
|
||||
!/dom/security/test/csp/file_web_manifest.json
|
||||
!/dom/security/test/csp/file_web_manifest.json^headers^
|
||||
!/dom/security/test/csp/file_web_manifest_https.html
|
||||
!/dom/security/test/csp/file_web_manifest_https.json
|
||||
!/dom/security/test/csp/file_web_manifest_mixed_content.html
|
||||
!/dom/security/test/csp/file_web_manifest_remote.html
|
||||
[browser_test_web_manifest.js]
|
||||
[browser_test_web_manifest_mixed_content.js]
|
||||
[browser_manifest-src-override-default-src.js]
|
||||
|
|
@ -0,0 +1,108 @@
|
|||
/*
|
||||
* Description of the tests:
|
||||
* Tests check that default-src can be overridden by manifest-src.
|
||||
*/
|
||||
/*globals Cu, is, ok*/
|
||||
"use strict";
|
||||
const {
|
||||
ManifestObtainer
|
||||
} = Cu.import("resource://gre/modules/ManifestObtainer.jsm", {});
|
||||
const path = "/tests/dom/security/test/csp/";
|
||||
const testFile = `${path}file_web_manifest.html`;
|
||||
const mixedContentFile = `${path}file_web_manifest_mixed_content.html`;
|
||||
const server = `${path}file_testserver.sjs`;
|
||||
const defaultURL = new URL(`http://example.org${server}`);
|
||||
const mixedURL = new URL(`http://mochi.test:8888${server}`);
|
||||
const tests = [
|
||||
// Check interaction with default-src and another origin,
|
||||
// CSP allows fetching from example.org, so manifest should load.
|
||||
{
|
||||
expected: `CSP manifest-src overrides default-src of elsewhere.com`,
|
||||
get tabURL() {
|
||||
const url = new URL(defaultURL);
|
||||
url.searchParams.append("file", testFile);
|
||||
url.searchParams.append("cors", "*");
|
||||
url.searchParams.append("csp", "default-src http://elsewhere.com; manifest-src http://example.org");
|
||||
return url.href;
|
||||
},
|
||||
run(manifest) {
|
||||
is(manifest.name, "loaded", this.expected);
|
||||
}
|
||||
},
|
||||
// Check interaction with default-src none,
|
||||
// CSP allows fetching manifest from example.org, so manifest should load.
|
||||
{
|
||||
expected: `CSP manifest-src overrides default-src`,
|
||||
get tabURL() {
|
||||
const url = new URL(mixedURL);
|
||||
url.searchParams.append("file", mixedContentFile);
|
||||
url.searchParams.append("cors", "http://test:80");
|
||||
url.searchParams.append("csp", "default-src 'self'; manifest-src http://test:80");
|
||||
return url.href;
|
||||
},
|
||||
run(manifest) {
|
||||
is(manifest.name, "loaded", this.expected);
|
||||
}
|
||||
},
|
||||
];
|
||||
|
||||
//jscs:disable
|
||||
add_task(function* () {
|
||||
//jscs:enable
|
||||
const testPromises = tests.map((test) => {
|
||||
const tabOptions = {
|
||||
gBrowser,
|
||||
url: test.tabURL,
|
||||
skipAnimation: true,
|
||||
};
|
||||
return BrowserTestUtils.withNewTab(tabOptions, (browser) => testObtainingManifest(browser, test));
|
||||
});
|
||||
yield Promise.all(testPromises);
|
||||
});
|
||||
|
||||
function* testObtainingManifest(aBrowser, aTest) {
|
||||
const expectsBlocked = aTest.expected.includes("block");
|
||||
const observer = (expectsBlocked) ? createNetObserver(aTest) : null;
|
||||
// Expect an exception (from promise rejection) if there a content policy
|
||||
// that is violated.
|
||||
try {
|
||||
const manifest = yield ManifestObtainer.browserObtainManifest(aBrowser);
|
||||
aTest.run(manifest);
|
||||
} catch (e) {
|
||||
const wasBlocked = e.message.includes("NetworkError when attempting to fetch resource");
|
||||
ok(wasBlocked,`Expected promise rejection obtaining ${aTest.tabURL}: ${e.message}`);
|
||||
if (observer) {
|
||||
yield observer.untilFinished;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Helper object used to observe policy violations. It waits 1 seconds
|
||||
// for a response, and then times out causing its associated test to fail.
|
||||
function createNetObserver(test) {
|
||||
let finishedTest;
|
||||
let success = false;
|
||||
const finished = new Promise((resolver) => {
|
||||
finishedTest = resolver;
|
||||
});
|
||||
const timeoutId = setTimeout(() => {
|
||||
if (!success) {
|
||||
test.run("This test timed out.");
|
||||
finishedTest();
|
||||
}
|
||||
}, 1000);
|
||||
var observer = {
|
||||
get untilFinished(){
|
||||
return finished;
|
||||
},
|
||||
observe(subject, topic) {
|
||||
SpecialPowers.removeObserver(observer, "csp-on-violate-policy");
|
||||
test.run(topic);
|
||||
finishedTest();
|
||||
clearTimeout(timeoutId);
|
||||
success = true;
|
||||
},
|
||||
};
|
||||
SpecialPowers.addObserver(observer, "csp-on-violate-policy", false);
|
||||
return observer;
|
||||
}
|
||||
224
dom/security/test/csp/browser_test_web_manifest.js
Normal file
224
dom/security/test/csp/browser_test_web_manifest.js
Normal file
|
|
@ -0,0 +1,224 @@
|
|||
/*
|
||||
* Description of the tests:
|
||||
* These tests check for conformance to the CSP spec as they relate to Web Manifests.
|
||||
*
|
||||
* In particular, the tests check that default-src and manifest-src directives are
|
||||
* are respected by the ManifestObtainer.
|
||||
*/
|
||||
/*globals Cu, is, ok*/
|
||||
"use strict";
|
||||
const {
|
||||
ManifestObtainer
|
||||
} = Cu.import("resource://gre/modules/ManifestObtainer.jsm", {});
|
||||
const path = "/tests/dom/security/test/csp/";
|
||||
const testFile = `${path}file_web_manifest.html`;
|
||||
const remoteFile = `${path}file_web_manifest_remote.html`;
|
||||
const httpsManifest = `${path}file_web_manifest_https.html`;
|
||||
const server = `${path}file_testserver.sjs`;
|
||||
const defaultURL = new URL(`http://example.org${server}`);
|
||||
const secureURL = new URL(`https://example.com:443${server}`);
|
||||
const tests = [
|
||||
// CSP block everything, so trying to load a manifest
|
||||
// will result in a policy violation.
|
||||
{
|
||||
expected: "default-src 'none' blocks fetching manifest.",
|
||||
get tabURL() {
|
||||
const url = new URL(defaultURL);
|
||||
url.searchParams.append("file", testFile);
|
||||
url.searchParams.append("csp", "default-src 'none'");
|
||||
return url.href;
|
||||
},
|
||||
run(topic) {
|
||||
is(topic, "csp-on-violate-policy", this.expected);
|
||||
}
|
||||
},
|
||||
// CSP allows fetching only from mochi.test:8888,
|
||||
// so trying to load a manifest from same origin
|
||||
// triggers a CSP violation.
|
||||
{
|
||||
expected: "default-src mochi.test:8888 blocks manifest fetching.",
|
||||
get tabURL() {
|
||||
const url = new URL(defaultURL);
|
||||
url.searchParams.append("file", testFile);
|
||||
url.searchParams.append("csp", "default-src mochi.test:8888");
|
||||
return url.href;
|
||||
},
|
||||
run(topic) {
|
||||
is(topic, "csp-on-violate-policy", this.expected);
|
||||
}
|
||||
},
|
||||
// CSP restricts fetching to 'self', so allowing the manifest
|
||||
// to load. The name of the manifest is then checked.
|
||||
{
|
||||
expected: "CSP default-src 'self' allows fetch of manifest.",
|
||||
get tabURL() {
|
||||
const url = new URL(defaultURL);
|
||||
url.searchParams.append("file", testFile);
|
||||
url.searchParams.append("csp", "default-src 'self'");
|
||||
return url.href;
|
||||
},
|
||||
run(manifest) {
|
||||
is(manifest.name, "loaded", this.expected);
|
||||
}
|
||||
},
|
||||
// CSP only allows fetching from mochi.test:8888 and remoteFile
|
||||
// requests a manifest from that origin, so manifest should load.
|
||||
{
|
||||
expected: "CSP default-src mochi.test:8888 allows fetching manifest.",
|
||||
get tabURL() {
|
||||
const url = new URL(defaultURL);
|
||||
url.searchParams.append("file", remoteFile);
|
||||
url.searchParams.append("csp", "default-src http://mochi.test:8888");
|
||||
return url.href;
|
||||
},
|
||||
run(manifest) {
|
||||
is(manifest.name, "loaded", this.expected);
|
||||
}
|
||||
},
|
||||
// default-src blocks everything, so any attempt to
|
||||
// fetch a manifest from another origin will trigger a
|
||||
// policy violation.
|
||||
{
|
||||
expected: "default-src 'none' blocks mochi.test:8888",
|
||||
get tabURL() {
|
||||
const url = new URL(defaultURL);
|
||||
url.searchParams.append("file", remoteFile);
|
||||
url.searchParams.append("csp", "default-src 'none'");
|
||||
return url.href;
|
||||
},
|
||||
run(topic) {
|
||||
is(topic, "csp-on-violate-policy", this.expected);
|
||||
}
|
||||
},
|
||||
// CSP allows fetching from self, so manifest should load.
|
||||
{
|
||||
expected: "CSP manifest-src allows self",
|
||||
get tabURL() {
|
||||
const url = new URL(defaultURL);
|
||||
url.searchParams.append("file", testFile);
|
||||
url.searchParams.append("csp", "manifest-src 'self'");
|
||||
return url.href;
|
||||
},
|
||||
run(manifest) {
|
||||
is(manifest.name, "loaded", this.expected);
|
||||
}
|
||||
},
|
||||
// CSP allows fetching from example.org, so manifest should load.
|
||||
{
|
||||
expected: "CSP manifest-src allows http://example.org",
|
||||
get tabURL() {
|
||||
const url = new URL(defaultURL);
|
||||
url.searchParams.append("file", testFile);
|
||||
url.searchParams.append("csp", "manifest-src http://example.org");
|
||||
return url.href;
|
||||
},
|
||||
run(manifest) {
|
||||
is(manifest.name, "loaded", this.expected);
|
||||
}
|
||||
}, {
|
||||
expected: "CSP manifest-src allows mochi.test:8888",
|
||||
get tabURL() {
|
||||
const url = new URL(defaultURL);
|
||||
url.searchParams.append("file", remoteFile);
|
||||
url.searchParams.append("cors", "*");
|
||||
url.searchParams.append("csp", "default-src *; manifest-src http://mochi.test:8888");
|
||||
return url.href;
|
||||
},
|
||||
run(manifest) {
|
||||
is(manifest.name, "loaded", this.expected);
|
||||
}
|
||||
},
|
||||
// CSP restricts fetching to mochi.test:8888, but the test
|
||||
// file is at example.org. Hence, a policy violation is
|
||||
// triggered.
|
||||
{
|
||||
expected: "CSP blocks manifest fetching from example.org.",
|
||||
get tabURL() {
|
||||
const url = new URL(defaultURL);
|
||||
url.searchParams.append("file", testFile);
|
||||
url.searchParams.append("csp", "manifest-src mochi.test:8888");
|
||||
return url.href;
|
||||
},
|
||||
run(topic) {
|
||||
is(topic, "csp-on-violate-policy", this.expected);
|
||||
}
|
||||
},
|
||||
// CSP is set to only allow manifest to be loaded from same origin,
|
||||
// but the remote file attempts to load from a different origin. Thus
|
||||
// this causes a CSP violation.
|
||||
{
|
||||
expected: "CSP manifest-src 'self' blocks cross-origin fetch.",
|
||||
get tabURL() {
|
||||
const url = new URL(defaultURL);
|
||||
url.searchParams.append("file", remoteFile);
|
||||
url.searchParams.append("csp", "manifest-src 'self'");
|
||||
return url.href;
|
||||
},
|
||||
run(topic) {
|
||||
is(topic, "csp-on-violate-policy", this.expected);
|
||||
}
|
||||
},
|
||||
// CSP allows fetching over TLS from example.org, so manifest should load.
|
||||
{
|
||||
expected: "CSP manifest-src allows example.com over TLS",
|
||||
get tabURL() {
|
||||
// secureURL loads https://example.com:443
|
||||
// and gets manifest from https://example.org:443
|
||||
const url = new URL(secureURL);
|
||||
url.searchParams.append("file", httpsManifest);
|
||||
url.searchParams.append("cors", "*");
|
||||
url.searchParams.append("csp", "manifest-src https://example.com:443");
|
||||
return url.href;
|
||||
},
|
||||
run(manifest) {
|
||||
is(manifest.name, "loaded", this.expected);
|
||||
}
|
||||
},
|
||||
];
|
||||
|
||||
//jscs:disable
|
||||
add_task(function* () {
|
||||
//jscs:enable
|
||||
const testPromises = tests.map((test) => {
|
||||
const tabOptions = {
|
||||
gBrowser,
|
||||
url: test.tabURL,
|
||||
skipAnimation: true,
|
||||
};
|
||||
return BrowserTestUtils.withNewTab(tabOptions, (browser) => testObtainingManifest(browser, test));
|
||||
});
|
||||
yield Promise.all(testPromises);
|
||||
});
|
||||
|
||||
function* testObtainingManifest(aBrowser, aTest) {
|
||||
const waitForObserver = waitForNetObserver(aTest);
|
||||
// Expect an exception (from promise rejection) if there a content policy
|
||||
// that is violated.
|
||||
try {
|
||||
const manifest = yield ManifestObtainer.browserObtainManifest(aBrowser);
|
||||
aTest.run(manifest);
|
||||
} catch (e) {
|
||||
const wasBlocked = e.message.includes("NetworkError when attempting to fetch resource");
|
||||
ok(wasBlocked, `Expected promise rejection obtaining ${aTest.tabURL}: ${e.message}`);
|
||||
} finally {
|
||||
yield waitForObserver;
|
||||
}
|
||||
}
|
||||
|
||||
// Helper object used to observe policy violations when blocking is expected.
|
||||
function waitForNetObserver(aTest) {
|
||||
return new Promise((resolve) => {
|
||||
// We don't need to wait for violation, so just resolve
|
||||
if (!aTest.expected.includes("block")){
|
||||
return resolve();
|
||||
}
|
||||
const observer = {
|
||||
observe(subject, topic) {
|
||||
SpecialPowers.removeObserver(observer, "csp-on-violate-policy");
|
||||
aTest.run(topic);
|
||||
resolve();
|
||||
},
|
||||
};
|
||||
SpecialPowers.addObserver(observer, "csp-on-violate-policy", false);
|
||||
});
|
||||
}
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* Description of the test:
|
||||
* Check that mixed content blocker works prevents fetches of
|
||||
* mixed content manifests.
|
||||
*/
|
||||
/*globals Cu, ok*/
|
||||
"use strict";
|
||||
const {
|
||||
ManifestObtainer
|
||||
} = Cu.import("resource://gre/modules/ManifestObtainer.jsm", {});
|
||||
const path = "/tests/dom/security/test/csp/";
|
||||
const mixedContent = `${path}file_web_manifest_mixed_content.html`;
|
||||
const server = `${path}file_testserver.sjs`;
|
||||
const secureURL = new URL(`https://example.com${server}`);
|
||||
const tests = [
|
||||
// Trying to load mixed content in file_web_manifest_mixed_content.html
|
||||
// needs to result in an error.
|
||||
{
|
||||
expected: "Mixed Content Blocker prevents fetching manifest.",
|
||||
get tabURL() {
|
||||
const url = new URL(secureURL);
|
||||
url.searchParams.append("file", mixedContent);
|
||||
return url.href;
|
||||
},
|
||||
run(error) {
|
||||
// Check reason for error.
|
||||
const check = /NetworkError when attempting to fetch resource/.test(error.message);
|
||||
ok(check, this.expected);
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
//jscs:disable
|
||||
add_task(function* () {
|
||||
//jscs:enable
|
||||
const testPromises = tests.map((test) => {
|
||||
const tabOptions = {
|
||||
gBrowser,
|
||||
url: test.tabURL,
|
||||
skipAnimation: true,
|
||||
};
|
||||
return BrowserTestUtils.withNewTab(tabOptions, (browser) => testObtainingManifest(browser, test));
|
||||
});
|
||||
yield Promise.all(testPromises);
|
||||
});
|
||||
|
||||
function* testObtainingManifest(aBrowser, aTest) {
|
||||
try {
|
||||
yield ManifestObtainer.browserObtainManifest(aBrowser);
|
||||
} catch (e) {
|
||||
aTest.run(e);
|
||||
}
|
||||
}
|
||||
20
dom/security/test/csp/file_CSP.css
Normal file
20
dom/security/test/csp/file_CSP.css
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* Moved this CSS from an inline stylesheet to an external file when we added
|
||||
* inline-style blocking in bug 763879.
|
||||
* This test may hang if the load for this .css file is blocked due to a
|
||||
* malfunction of CSP, but should pass if the style_good test passes.
|
||||
*/
|
||||
|
||||
/* CSS font embedding tests */
|
||||
@font-face {
|
||||
font-family: "arbitrary_good";
|
||||
src: url('file_CSP.sjs?testid=font_good&type=application/octet-stream');
|
||||
}
|
||||
@font-face {
|
||||
font-family: "arbitrary_bad";
|
||||
src: url('http://example.org/tests/dom/security/test/csp/file_CSP.sjs?testid=font_bad&type=application/octet-stream');
|
||||
}
|
||||
|
||||
.div_arbitrary_good { font-family: "arbitrary_good"; }
|
||||
.div_arbitrary_bad { font-family: "arbitrary_bad"; }
|
||||
|
||||
26
dom/security/test/csp/file_CSP.sjs
Normal file
26
dom/security/test/csp/file_CSP.sjs
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
// SJS file for CSP mochitests
|
||||
|
||||
function handleRequest(request, response)
|
||||
{
|
||||
var query = {};
|
||||
request.queryString.split('&').forEach(function (val) {
|
||||
var [name, value] = val.split('=');
|
||||
query[name] = unescape(value);
|
||||
});
|
||||
|
||||
var isPreflight = request.method == "OPTIONS";
|
||||
|
||||
|
||||
//avoid confusing cache behaviors
|
||||
response.setHeader("Cache-Control", "no-cache", false);
|
||||
|
||||
if ("type" in query) {
|
||||
response.setHeader("Content-Type", unescape(query['type']), false);
|
||||
} else {
|
||||
response.setHeader("Content-Type", "text/html", false);
|
||||
}
|
||||
|
||||
if ("content" in query) {
|
||||
response.write(unescape(query['content']));
|
||||
}
|
||||
}
|
||||
14
dom/security/test/csp/file_allow_https_schemes.html
Normal file
14
dom/security/test/csp/file_allow_https_schemes.html
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Bug 826805 - CSP: Allow http and https for scheme-less sources</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="testdiv">blocked</div>
|
||||
<!--
|
||||
We resue file_path_matching.js which just updates the contents of 'testdiv' to contain allowed.
|
||||
Note, that we are loading the file_path_matchting.js using a scheme of 'https'.
|
||||
-->
|
||||
<script src="https://example.com/tests/dom/security/test/csp/file_path_matching.js#foo"></script>
|
||||
</body>
|
||||
</html>
|
||||
61
dom/security/test/csp/file_base_uri_server.sjs
Normal file
61
dom/security/test/csp/file_base_uri_server.sjs
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
// Custom *.sjs file specifically for the needs of
|
||||
// https://bugzilla.mozilla.org/show_bug.cgi?id=1263286
|
||||
|
||||
"use strict";
|
||||
Components.utils.importGlobalProperties(["URLSearchParams"]);
|
||||
|
||||
const PRE_BASE = `
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Bug 1045897 - Test CSP base-uri directive</title>`;
|
||||
|
||||
const REGULAR_POST_BASE =`
|
||||
</head>
|
||||
<body onload='window.parent.postMessage({result: document.baseURI}, "*");'>
|
||||
<!-- just making use of the 'base' tag for this test -->
|
||||
</body>
|
||||
</html>`;
|
||||
|
||||
const SCRIPT_POST_BASE = `
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
document.getElementById("base1").removeAttribute("href");
|
||||
window.parent.postMessage({result: document.baseURI}, "*");
|
||||
</script>
|
||||
</body>
|
||||
</html>`;
|
||||
|
||||
function handleRequest(request, response) {
|
||||
const query = new URLSearchParams(request.queryString);
|
||||
|
||||
// avoid confusing cache behaviors
|
||||
response.setHeader("Cache-Control", "no-cache", false);
|
||||
|
||||
// Deliver the CSP policy encoded in the URL
|
||||
response.setHeader("Content-Security-Policy", query.get("csp"), false);
|
||||
|
||||
// Send HTML to test allowed/blocked behaviors
|
||||
response.setHeader("Content-Type", "text/html", false);
|
||||
response.write(PRE_BASE);
|
||||
var base1 =
|
||||
"<base id=\"base1\" href=\"" + query.get("base1") + "\">";
|
||||
var base2 =
|
||||
"<base id=\"base2\" href=\"" + query.get("base2") + "\">";
|
||||
response.write(base1 + base2);
|
||||
|
||||
if (query.get("action") === "enforce-csp") {
|
||||
response.write(REGULAR_POST_BASE);
|
||||
return;
|
||||
}
|
||||
|
||||
if (query.get("action") === "remove-base1") {
|
||||
response.write(SCRIPT_POST_BASE);
|
||||
return;
|
||||
}
|
||||
|
||||
// we should never get here, but just in case
|
||||
// return something unexpected
|
||||
response.write("do'h");
|
||||
}
|
||||
49
dom/security/test/csp/file_blob_data_schemes.html
Normal file
49
dom/security/test/csp/file_blob_data_schemes.html
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Bug 1086999 - Wildcard should not match blob:, data:</title>
|
||||
</head>
|
||||
<body>
|
||||
<script type="text/javascript">
|
||||
|
||||
var base64data =
|
||||
"iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12" +
|
||||
"P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==";
|
||||
|
||||
|
||||
// construct an image element using *data:*
|
||||
var data_src = "data:image/png;base64," + base64data;
|
||||
var data_img = document.createElement('img');
|
||||
data_img.onload = function() {
|
||||
window.parent.postMessage({scheme: "data", result: "allowed"}, "*");
|
||||
}
|
||||
data_img.onerror = function() {
|
||||
window.parent.postMessage({scheme: "data", result: "blocked"}, "*");
|
||||
}
|
||||
data_img.src = data_src;
|
||||
document.body.appendChild(data_img);
|
||||
|
||||
|
||||
// construct an image element using *blob:*
|
||||
var byteCharacters = atob(base64data);
|
||||
var byteNumbers = new Array(byteCharacters.length);
|
||||
for (var i = 0; i < byteCharacters.length; i++) {
|
||||
byteNumbers[i] = byteCharacters.charCodeAt(i);
|
||||
}
|
||||
var byteArray = new Uint8Array(byteNumbers);
|
||||
var blob = new Blob([byteArray], {type: "image/png"});
|
||||
var imageUrl = URL.createObjectURL( blob );
|
||||
|
||||
var blob_img = document.createElement('img');
|
||||
blob_img.onload = function() {
|
||||
window.parent.postMessage({scheme: "blob", result: "allowed"}, "*");
|
||||
}
|
||||
blob_img.onerror = function() {
|
||||
window.parent.postMessage({scheme: "blob", result: "blocked"}, "*");
|
||||
}
|
||||
blob_img.src = imageUrl;
|
||||
document.body.appendChild(blob_img);
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
76
dom/security/test/csp/file_block_all_mcb.sjs
Normal file
76
dom/security/test/csp/file_block_all_mcb.sjs
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
// custom *.sjs for Bug 1122236
|
||||
// CSP: 'block-all-mixed-content'
|
||||
|
||||
const HEAD =
|
||||
"<!DOCTYPE HTML>" +
|
||||
"<html><head><meta charset=\"utf-8\">" +
|
||||
"<title>Bug 1122236 - CSP: Implement block-all-mixed-content</title>" +
|
||||
"</head>";
|
||||
|
||||
const CSP_ALLOW =
|
||||
"<meta http-equiv=\"Content-Security-Policy\" content=\"img-src *\">";
|
||||
|
||||
const CSP_BLOCK =
|
||||
"<meta http-equiv=\"Content-Security-Policy\" content=\"block-all-mixed-content\">";
|
||||
|
||||
const BODY =
|
||||
"<body>" +
|
||||
"<img id=\"testimage\" src=\"http://mochi.test:8888/tests/image/test/mochitest/blue.png\"></img>" +
|
||||
"<script type=\"application/javascript\">" +
|
||||
" var myImg = document.getElementById(\"testimage\");" +
|
||||
" myImg.onload = function(e) {" +
|
||||
" window.parent.postMessage({result: \"img-loaded\"}, \"*\");" +
|
||||
" };" +
|
||||
" myImg.onerror = function(e) {" +
|
||||
" window.parent.postMessage({result: \"img-blocked\"}, \"*\");" +
|
||||
" };" +
|
||||
"</script>" +
|
||||
"</body>" +
|
||||
"</html>";
|
||||
|
||||
// We have to use this special code fragment, in particular '?nocache' to trigger an
|
||||
// actual network load rather than loading the image from the cache.
|
||||
const BODY_CSPRO =
|
||||
"<body>" +
|
||||
"<img id=\"testimage\" src=\"http://mochi.test:8888/tests/image/test/mochitest/blue.png?nocache\"></img>" +
|
||||
"<script type=\"application/javascript\">" +
|
||||
" var myImg = document.getElementById(\"testimage\");" +
|
||||
" myImg.onload = function(e) {" +
|
||||
" window.parent.postMessage({result: \"img-loaded\"}, \"*\");" +
|
||||
" };" +
|
||||
" myImg.onerror = function(e) {" +
|
||||
" window.parent.postMessage({result: \"img-blocked\"}, \"*\");" +
|
||||
" };" +
|
||||
"</script>" +
|
||||
"</body>" +
|
||||
"</html>";
|
||||
|
||||
function handleRequest(request, response)
|
||||
{
|
||||
// avoid confusing cache behaviors
|
||||
response.setHeader("Cache-Control", "no-cache", false);
|
||||
|
||||
var queryString = request.queryString;
|
||||
|
||||
if (queryString === "csp-block") {
|
||||
response.write(HEAD + CSP_BLOCK + BODY);
|
||||
return;
|
||||
}
|
||||
if (queryString === "csp-allow") {
|
||||
response.write(HEAD + CSP_ALLOW + BODY);
|
||||
return;
|
||||
}
|
||||
if (queryString === "no-csp") {
|
||||
response.write(HEAD + BODY);
|
||||
return;
|
||||
}
|
||||
if (queryString === "cspro-block") {
|
||||
// CSP RO is not supported in meta tag, let's use the header
|
||||
response.setHeader("Content-Security-Policy-Report-Only", "block-all-mixed-content", false);
|
||||
response.write(HEAD + BODY_CSPRO);
|
||||
return;
|
||||
}
|
||||
// we should never get here but just in case return something unexpected
|
||||
response.write("do'h");
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="Content-Security-Policy" content="block-all-mixed-content">
|
||||
<title>Bug 1122236 - CSP: Implement block-all-mixed-content</title>
|
||||
</head>
|
||||
<body>
|
||||
<b>user clicks and navigates from https://b.com to http://c.com</b>
|
||||
|
||||
<a id="navlink" href="http://example.com/tests/dom/security/test/csp/file_block_all_mixed_content_frame_navigation2.html">foo</a>
|
||||
|
||||
<script class="testbody" type="text/javascript">
|
||||
// click the link to start the frame navigation
|
||||
document.getElementById("navlink").click();
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Bug 1122236 - CSP: Implement block-all-mixed-content</title>
|
||||
</head>
|
||||
<body>
|
||||
<b>http://c.com loaded, let's tell the parent</b>
|
||||
|
||||
<script class="testbody" type="text/javascript">
|
||||
window.parent.postMessage({result: "frame-navigated"}, "*");
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
7
dom/security/test/csp/file_bug1229639.html
Normal file
7
dom/security/test/csp/file_bug1229639.html
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
<html>
|
||||
<head> <meta charset="utf-8"> </head>
|
||||
<body>
|
||||
<!-- this should be allowed -->
|
||||
<script src="http://mochi.test:8888/tests/dom/security/test/csp/%24.js"> </script>
|
||||
</body>
|
||||
</html>
|
||||
1
dom/security/test/csp/file_bug1229639.html^headers^
Normal file
1
dom/security/test/csp/file_bug1229639.html^headers^
Normal file
|
|
@ -0,0 +1 @@
|
|||
Content-Security-Policy: "default-src 'self'; script-src http://mochi.test:8888/tests/dom/security/test/csp/%24.js
|
||||
13
dom/security/test/csp/file_bug1312272.html
Normal file
13
dom/security/test/csp/file_bug1312272.html
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
<!DOCTYPE HTML>
|
||||
<!-- Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ -->
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>marquee inline script tests for Bug 1312272</title>
|
||||
</head>
|
||||
<body>
|
||||
<marquee id="m" onstart="parent.postMessage('csp-violation-marquee-onstart', '*')">bug 1312272</marquee>
|
||||
<script src="file_bug1312272.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
1
dom/security/test/csp/file_bug1312272.html^headers^
Normal file
1
dom/security/test/csp/file_bug1312272.html^headers^
Normal file
|
|
@ -0,0 +1 @@
|
|||
Content-Security-Policy: default-src *; script-src * 'unsafe-eval'
|
||||
8
dom/security/test/csp/file_bug1312272.js
Normal file
8
dom/security/test/csp/file_bug1312272.js
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
var m = document.getElementById("m");
|
||||
m.addEventListener("click", function() {
|
||||
// this will trigger after onstart, obviously.
|
||||
parent.postMessage('finish', '*');
|
||||
});
|
||||
console.log("finish-handler setup");
|
||||
m.click();
|
||||
console.log("clicked");
|
||||
27
dom/security/test/csp/file_bug663567.xsl
Normal file
27
dom/security/test/csp/file_bug663567.xsl
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<!-- Edited by XMLSpy® -->
|
||||
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
|
||||
|
||||
<xsl:template match="/">
|
||||
<html>
|
||||
<body>
|
||||
<h2 id="xsltheader">this xml file should be formatted using an xsl file(lower iframe should contain xml dump)!</h2>
|
||||
<table border="1">
|
||||
<tr bgcolor="#990099">
|
||||
<th>Title</th>
|
||||
<th>Artist</th>
|
||||
<th>Price</th>
|
||||
</tr>
|
||||
<xsl:for-each select="catalog/cd">
|
||||
<tr>
|
||||
<td><xsl:value-of select="title"/></td>
|
||||
<td><xsl:value-of select="artist"/></td>
|
||||
<td><xsl:value-of select="price"/></td>
|
||||
</tr>
|
||||
</xsl:for-each>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
</xsl:template>
|
||||
</xsl:stylesheet>
|
||||
|
||||
28
dom/security/test/csp/file_bug663567_allows.xml
Normal file
28
dom/security/test/csp/file_bug663567_allows.xml
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<?xml-stylesheet type="text/xsl" href="file_bug663567.xsl"?>
|
||||
<catalog>
|
||||
<cd>
|
||||
<title>Empire Burlesque</title>
|
||||
<artist>Bob Dylan</artist>
|
||||
<country>USA</country>
|
||||
<company>Columbia</company>
|
||||
<price>10.90</price>
|
||||
<year>1985</year>
|
||||
</cd>
|
||||
<cd>
|
||||
<title>Hide your heart</title>
|
||||
<artist>Bonnie Tyler</artist>
|
||||
<country>UK</country>
|
||||
<company>CBS Records</company>
|
||||
<price>9.90</price>
|
||||
<year>1988</year>
|
||||
</cd>
|
||||
<cd>
|
||||
<title>Greatest Hits</title>
|
||||
<artist>Dolly Parton</artist>
|
||||
<country>USA</country>
|
||||
<company>RCA</company>
|
||||
<price>9.90</price>
|
||||
<year>1982</year>
|
||||
</cd>
|
||||
</catalog>
|
||||
1
dom/security/test/csp/file_bug663567_allows.xml^headers^
Normal file
1
dom/security/test/csp/file_bug663567_allows.xml^headers^
Normal file
|
|
@ -0,0 +1 @@
|
|||
Content-Security-Policy: default-src 'self'
|
||||
28
dom/security/test/csp/file_bug663567_blocks.xml
Normal file
28
dom/security/test/csp/file_bug663567_blocks.xml
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<?xml-stylesheet type="text/xsl" href="file_bug663567.xsl"?>
|
||||
<catalog>
|
||||
<cd>
|
||||
<title>Empire Burlesque</title>
|
||||
<artist>Bob Dylan</artist>
|
||||
<country>USA</country>
|
||||
<company>Columbia</company>
|
||||
<price>10.90</price>
|
||||
<year>1985</year>
|
||||
</cd>
|
||||
<cd>
|
||||
<title>Hide your heart</title>
|
||||
<artist>Bonnie Tyler</artist>
|
||||
<country>UK</country>
|
||||
<company>CBS Records</company>
|
||||
<price>9.90</price>
|
||||
<year>1988</year>
|
||||
</cd>
|
||||
<cd>
|
||||
<title>Greatest Hits</title>
|
||||
<artist>Dolly Parton</artist>
|
||||
<country>USA</country>
|
||||
<company>RCA</company>
|
||||
<price>9.90</price>
|
||||
<year>1982</year>
|
||||
</cd>
|
||||
</catalog>
|
||||
1
dom/security/test/csp/file_bug663567_blocks.xml^headers^
Normal file
1
dom/security/test/csp/file_bug663567_blocks.xml^headers^
Normal file
|
|
@ -0,0 +1 @@
|
|||
Content-Security-Policy: default-src *.example.com
|
||||
12
dom/security/test/csp/file_bug802872.html
Normal file
12
dom/security/test/csp/file_bug802872.html
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Bug 802872</title>
|
||||
<!-- Including SimpleTest.js so we can use AddLoadEvent !-->
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<script src='file_bug802872.js'></script>
|
||||
</body>
|
||||
</html>
|
||||
1
dom/security/test/csp/file_bug802872.html^headers^
Normal file
1
dom/security/test/csp/file_bug802872.html^headers^
Normal file
|
|
@ -0,0 +1 @@
|
|||
Content-Security-Policy: default-src 'self'
|
||||
43
dom/security/test/csp/file_bug802872.js
Normal file
43
dom/security/test/csp/file_bug802872.js
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* The policy for this test is:
|
||||
* Content-Security-Policy: default-src 'self'
|
||||
*/
|
||||
|
||||
function createAllowedEvent() {
|
||||
/*
|
||||
* Creates a new EventSource using 'http://mochi.test:8888'. Since all mochitests run on
|
||||
* 'http://mochi.test', a default-src of 'self' allows this request.
|
||||
*/
|
||||
var src_event = new EventSource("http://mochi.test:8888/tests/dom/security/test/csp/file_bug802872.sjs");
|
||||
|
||||
src_event.onmessage = function(e) {
|
||||
src_event.close();
|
||||
parent.dispatchEvent(new Event('allowedEventSrcCallbackOK'));
|
||||
}
|
||||
|
||||
src_event.onerror = function(e) {
|
||||
src_event.close();
|
||||
parent.dispatchEvent(new Event('allowedEventSrcCallbackFailed'));
|
||||
}
|
||||
}
|
||||
|
||||
function createBlockedEvent() {
|
||||
/*
|
||||
* creates a new EventSource using 'http://example.com'. This domain is not whitelisted by the
|
||||
* CSP of this page, therefore the CSP blocks this request.
|
||||
*/
|
||||
var src_event = new EventSource("http://example.com/tests/dom/security/test/csp/file_bug802872.sjs");
|
||||
|
||||
src_event.onmessage = function(e) {
|
||||
src_event.close();
|
||||
parent.dispatchEvent(new Event('blockedEventSrcCallbackOK'));
|
||||
}
|
||||
|
||||
src_event.onerror = function(e) {
|
||||
src_event.close();
|
||||
parent.dispatchEvent(new Event('blockedEventSrcCallbackFailed'));
|
||||
}
|
||||
}
|
||||
|
||||
addLoadEvent(createAllowedEvent);
|
||||
addLoadEvent(createBlockedEvent);
|
||||
7
dom/security/test/csp/file_bug802872.sjs
Normal file
7
dom/security/test/csp/file_bug802872.sjs
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
function handleRequest(request, response)
|
||||
{
|
||||
response.setHeader("Cache-Control", "no-cache", false);
|
||||
response.setHeader("Content-Type", "text/event-stream", false);
|
||||
response.write("data: eventsource response from server!");
|
||||
response.write("\n\n");
|
||||
}
|
||||
12
dom/security/test/csp/file_bug836922_npolicies.html
Normal file
12
dom/security/test/csp/file_bug836922_npolicies.html
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
<html>
|
||||
<head>
|
||||
<link rel='stylesheet' type='text/css'
|
||||
href='/tests/dom/security/test/csp/file_CSP.sjs?testid=css_self&type=text/css' />
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<img src="/tests/dom/security/test/csp/file_CSP.sjs?testid=img_self&type=img/png"> </img>
|
||||
<script src='/tests/dom/security/test/csp/file_CSP.sjs?testid=script_self&type=text/javascript'></script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
content-security-policy: default-src 'self'; img-src 'none'; report-uri http://mochi.test:8888/tests/dom/security/test/csp/file_bug836922_npolicies_violation.sjs
|
||||
content-security-policy-report-only: default-src *; img-src 'self'; script-src 'none'; report-uri http://mochi.test:8888/tests/dom/security/test/csp/file_bug836922_npolicies_ro_violation.sjs
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
// SJS file that receives violation reports and then responds with nothing.
|
||||
|
||||
const CC = Components.Constructor;
|
||||
const BinaryInputStream = CC("@mozilla.org/binaryinputstream;1",
|
||||
"nsIBinaryInputStream",
|
||||
"setInputStream");
|
||||
|
||||
const STATE_KEY = "bug836922_ro_violations";
|
||||
|
||||
function handleRequest(request, response)
|
||||
{
|
||||
var query = {};
|
||||
request.queryString.split('&').forEach(function (val) {
|
||||
var [name, value] = val.split('=');
|
||||
query[name] = unescape(value);
|
||||
});
|
||||
|
||||
if ('results' in query) {
|
||||
// if asked for the received data, send it.
|
||||
response.setHeader("Content-Type", "text/javascript", false);
|
||||
if (getState(STATE_KEY)) {
|
||||
response.write(getState(STATE_KEY));
|
||||
} else {
|
||||
// no state has been recorded.
|
||||
response.write(JSON.stringify({}));
|
||||
}
|
||||
} else if ('reset' in query) {
|
||||
//clear state
|
||||
setState(STATE_KEY, JSON.stringify(null));
|
||||
} else {
|
||||
// ... otherwise, just respond "ok".
|
||||
response.write("null");
|
||||
|
||||
var bodystream = new BinaryInputStream(request.bodyInputStream);
|
||||
var avail;
|
||||
var bytes = [];
|
||||
while ((avail = bodystream.available()) > 0)
|
||||
Array.prototype.push.apply(bytes, bodystream.readByteArray(avail));
|
||||
|
||||
var data = String.fromCharCode.apply(null, bytes);
|
||||
|
||||
// figure out which test was violating a policy
|
||||
var testpat = new RegExp("testid=([a-z0-9_]+)");
|
||||
var testid = testpat.exec(data)[1];
|
||||
|
||||
// store the violation in the persistent state
|
||||
var s = JSON.parse(getState(STATE_KEY) || "{}");
|
||||
s[testid] ? s[testid]++ : s[testid] = 1;
|
||||
setState(STATE_KEY, JSON.stringify(s));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
59
dom/security/test/csp/file_bug836922_npolicies_violation.sjs
Normal file
59
dom/security/test/csp/file_bug836922_npolicies_violation.sjs
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
// SJS file that receives violation reports and then responds with nothing.
|
||||
|
||||
const CC = Components.Constructor;
|
||||
const BinaryInputStream = CC("@mozilla.org/binaryinputstream;1",
|
||||
"nsIBinaryInputStream",
|
||||
"setInputStream");
|
||||
|
||||
const STATE = "bug836922_violations";
|
||||
|
||||
function handleRequest(request, response)
|
||||
{
|
||||
var query = {};
|
||||
request.queryString.split('&').forEach(function (val) {
|
||||
var [name, value] = val.split('=');
|
||||
query[name] = unescape(value);
|
||||
});
|
||||
|
||||
|
||||
if ('results' in query) {
|
||||
// if asked for the received data, send it.
|
||||
response.setHeader("Content-Type", "text/javascript", false);
|
||||
if (getState(STATE)) {
|
||||
response.write(getState(STATE));
|
||||
} else {
|
||||
// no state has been recorded.
|
||||
response.write(JSON.stringify({}));
|
||||
}
|
||||
} else if ('reset' in query) {
|
||||
//clear state
|
||||
setState(STATE, JSON.stringify(null));
|
||||
} else {
|
||||
// ... otherwise, just respond "ok".
|
||||
response.write("null");
|
||||
|
||||
var bodystream = new BinaryInputStream(request.bodyInputStream);
|
||||
var avail;
|
||||
var bytes = [];
|
||||
while ((avail = bodystream.available()) > 0)
|
||||
Array.prototype.push.apply(bytes, bodystream.readByteArray(avail));
|
||||
|
||||
var data = String.fromCharCode.apply(null, bytes);
|
||||
|
||||
// figure out which test was violating a policy
|
||||
var testpat = new RegExp("testid=([a-z0-9_]+)");
|
||||
var testid = testpat.exec(data)[1];
|
||||
|
||||
// store the violation in the persistent state
|
||||
var s = getState(STATE);
|
||||
if (!s) s = "{}";
|
||||
s = JSON.parse(s);
|
||||
if (!s) s = {};
|
||||
|
||||
if (!s[testid]) s[testid] = 0;
|
||||
s[testid]++;
|
||||
setState(STATE, JSON.stringify(s));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
38
dom/security/test/csp/file_bug885433_allows.html
Normal file
38
dom/security/test/csp/file_bug885433_allows.html
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
<!doctype html>
|
||||
<!--
|
||||
The Content-Security-Policy header for this file is:
|
||||
|
||||
Content-Security-Policy: img-src 'self';
|
||||
|
||||
It does not include any of the default-src, script-src, or style-src
|
||||
directives. It should allow the use of unsafe-inline and unsafe-eval on
|
||||
scripts, and unsafe-inline on styles, because no directives related to scripts
|
||||
or styles are specified.
|
||||
-->
|
||||
<html>
|
||||
<body>
|
||||
<ol>
|
||||
<li id="unsafe-inline-script-allowed">Inline script allowed (this text should be green)</li>
|
||||
<li id="unsafe-eval-script-allowed">Eval script allowed (this text should be green)</li>
|
||||
<li id="unsafe-inline-style-allowed">Inline style allowed (this text should be green)</li>
|
||||
</ol>
|
||||
|
||||
<script>
|
||||
// Use inline script to set a style attribute
|
||||
document.getElementById("unsafe-inline-script-allowed").style.color = "green";
|
||||
|
||||
// Use eval to set a style attribute
|
||||
// try/catch is used because CSP causes eval to throw an exception when it
|
||||
// is blocked, which would derail the rest of the tests in this file.
|
||||
try {
|
||||
eval('document.getElementById("unsafe-eval-script-allowed").style.color = "green";');
|
||||
} catch (e) {}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
li#unsafe-inline-style-allowed {
|
||||
color: green;
|
||||
}
|
||||
</style>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1 @@
|
|||
Content-Security-Policy: img-src 'self';
|
||||
37
dom/security/test/csp/file_bug885433_blocks.html
Normal file
37
dom/security/test/csp/file_bug885433_blocks.html
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
<!doctype html>
|
||||
<!--
|
||||
The Content-Security-Policy header for this file is:
|
||||
|
||||
Content-Security-Policy: default-src 'self';
|
||||
|
||||
The Content-Security-Policy header for this file includes the default-src
|
||||
directive, which triggers the default behavior of blocking unsafe-inline and
|
||||
unsafe-eval on scripts, and unsafe-inline on styles.
|
||||
-->
|
||||
<html>
|
||||
<body>
|
||||
<ol>
|
||||
<li id="unsafe-inline-script-blocked">Inline script blocked (this text should be black)</li>
|
||||
<li id="unsafe-eval-script-blocked">Eval script blocked (this text should be black)</li>
|
||||
<li id="unsafe-inline-style-blocked">Inline style blocked (this text should be black)</li>
|
||||
</ol>
|
||||
|
||||
<script>
|
||||
// Use inline script to set a style attribute
|
||||
document.getElementById("unsafe-inline-script-blocked").style.color = "green";
|
||||
|
||||
// Use eval to set a style attribute
|
||||
// try/catch is used because CSP causes eval to throw an exception when it
|
||||
// is blocked, which would derail the rest of the tests in this file.
|
||||
try {
|
||||
eval('document.getElementById("unsafe-eval-script-blocked").style.color = "green";');
|
||||
} catch (e) {}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
li#unsafe-inline-style-blocked {
|
||||
color: green;
|
||||
}
|
||||
</style>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1 @@
|
|||
Content-Security-Policy: default-src 'self';
|
||||
15
dom/security/test/csp/file_bug886164.html
Normal file
15
dom/security/test/csp/file_bug886164.html
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
<html>
|
||||
<head> <meta charset="utf-8"> </head>
|
||||
<body>
|
||||
<!-- sandbox="allow-same-origin" -->
|
||||
<!-- Content-Security-Policy: default-src 'self' -->
|
||||
|
||||
<!-- these should be stopped by CSP -->
|
||||
<img src="http://example.org/tests/dom/security/test/csp/file_CSP.sjs?testid=img_bad&type=img/png"> </img>
|
||||
|
||||
<!-- these should load ok -->
|
||||
<img src="/tests/dom/security/test/csp/file_CSP.sjs?testid=img_good&type=img/png" />
|
||||
<script src='/tests/dom/security/test/csp/file_CSP.sjs?testid=scripta_bad&type=text/javascript'></script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
1
dom/security/test/csp/file_bug886164.html^headers^
Normal file
1
dom/security/test/csp/file_bug886164.html^headers^
Normal file
|
|
@ -0,0 +1 @@
|
|||
Content-Security-Policy: default-src 'self'
|
||||
14
dom/security/test/csp/file_bug886164_2.html
Normal file
14
dom/security/test/csp/file_bug886164_2.html
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
<html>
|
||||
<head> <meta charset="utf-8"> </head>
|
||||
<body>
|
||||
<!-- sandbox -->
|
||||
<!-- Content-Security-Policy: default-src 'self' -->
|
||||
|
||||
<!-- these should be stopped by CSP -->
|
||||
<img src="http://example.org/tests/dom/security/test/csp/file_CSP.sjs?testid=img2_bad&type=img/png"> </img>
|
||||
|
||||
<!-- these should load ok -->
|
||||
<img src="/tests/dom/security/test/csp/file_CSP.sjs?testid=img2a_good&type=img/png" />
|
||||
|
||||
</body>
|
||||
</html>
|
||||
1
dom/security/test/csp/file_bug886164_2.html^headers^
Normal file
1
dom/security/test/csp/file_bug886164_2.html^headers^
Normal file
|
|
@ -0,0 +1 @@
|
|||
Content-Security-Policy: default-src 'self'
|
||||
12
dom/security/test/csp/file_bug886164_3.html
Normal file
12
dom/security/test/csp/file_bug886164_3.html
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
<html>
|
||||
<head> <meta charset="utf-8"> </head>
|
||||
<body>
|
||||
<!-- sandbox -->
|
||||
<!-- Content-Security-Policy: default-src 'none' -->
|
||||
|
||||
<!-- these should be stopped by CSP -->
|
||||
<img src="http://example.org/tests/dom/security/test/csp/file_CSP.sjs?testid=img3_bad&type=img/png"> </img>
|
||||
<img src="/tests/dom/security/test/csp/file_CSP.sjs?testid=img3a_bad&type=img/png" />
|
||||
|
||||
</body>
|
||||
</html>
|
||||
1
dom/security/test/csp/file_bug886164_3.html^headers^
Normal file
1
dom/security/test/csp/file_bug886164_3.html^headers^
Normal file
|
|
@ -0,0 +1 @@
|
|||
Content-Security-Policy: default-src 'none'
|
||||
12
dom/security/test/csp/file_bug886164_4.html
Normal file
12
dom/security/test/csp/file_bug886164_4.html
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
<html>
|
||||
<head> <meta charset="utf-8"> </head>
|
||||
<body>
|
||||
<!-- sandbox -->
|
||||
<!-- Content-Security-Policy: default-src 'none' -->
|
||||
|
||||
<!-- these should be stopped by CSP -->
|
||||
<img src="http://example.org/tests/dom/security/test/csp/file_CSP.sjs?testid=img4_bad&type=img/png"> </img>
|
||||
<img src="/tests/dom/security/test/csp/file_CSP.sjs?testid=img4a_bad&type=img/png" />
|
||||
|
||||
</body>
|
||||
</html>
|
||||
1
dom/security/test/csp/file_bug886164_4.html^headers^
Normal file
1
dom/security/test/csp/file_bug886164_4.html^headers^
Normal file
|
|
@ -0,0 +1 @@
|
|||
Content-Security-Policy: default-src 'none'
|
||||
26
dom/security/test/csp/file_bug886164_5.html
Normal file
26
dom/security/test/csp/file_bug886164_5.html
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head> <meta charset="utf-8"> </head>
|
||||
<script type="text/javascript">
|
||||
function ok(result, desc) {
|
||||
window.parent.postMessage({ok: result, desc: desc}, "*");
|
||||
}
|
||||
|
||||
function doStuff() {
|
||||
ok(true, "documents sandboxed with allow-scripts should be able to run inline scripts");
|
||||
}
|
||||
</script>
|
||||
<script src='file_iframe_sandbox_pass.js'></script>
|
||||
<body onLoad='ok(true, "documents sandboxed with allow-scripts should be able to run script from event listeners");doStuff();'>
|
||||
I am sandboxed but with only inline "allow-scripts"
|
||||
|
||||
<!-- sandbox="allow-scripts" -->
|
||||
<!-- Content-Security-Policy: default-src 'none' 'unsafe-inline'-->
|
||||
|
||||
<!-- these should be stopped by CSP -->
|
||||
<img src="/tests/dom/security/test/csp/file_CSP.sjs?testid=img5_bad&type=img/png" />
|
||||
<img src="http://example.org/tests/dom/security/test/csp/file_CSP.sjs?testid=img5a_bad&type=img/png"> </img>
|
||||
<script src='/tests/dom/security/test/csp/file_CSP.sjs?testid=script5_bad&type=text/javascript'></script>
|
||||
<script src='http://example.org/tests/dom/security/test/csp/file_CSP.sjs?testid=script5a_bad&type=text/javascript'></script>
|
||||
</body>
|
||||
</html>
|
||||
1
dom/security/test/csp/file_bug886164_5.html^headers^
Normal file
1
dom/security/test/csp/file_bug886164_5.html^headers^
Normal file
|
|
@ -0,0 +1 @@
|
|||
Content-Security-Policy: default-src 'none' 'unsafe-inline';
|
||||
35
dom/security/test/csp/file_bug886164_6.html
Normal file
35
dom/security/test/csp/file_bug886164_6.html
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
|
||||
</head>
|
||||
<script type="text/javascript">
|
||||
function ok(result, desc) {
|
||||
window.parent.postMessage({ok: result, desc: desc}, "*");
|
||||
}
|
||||
|
||||
function doStuff() {
|
||||
ok(true, "documents sandboxed with allow-scripts should be able to run inline scripts");
|
||||
|
||||
document.getElementById('a_form').submit();
|
||||
|
||||
// trigger the javascript: url test
|
||||
sendMouseEvent({type:'click'}, 'a_link');
|
||||
}
|
||||
</script>
|
||||
<script src='file_iframe_sandbox_pass.js'></script>
|
||||
<body onLoad='ok(true, "documents sandboxed with allow-scripts should be able to run script from event listeners");doStuff();'>
|
||||
I am sandboxed but with "allow-scripts"
|
||||
<img src="http://example.org/tests/dom/security/test/csp/file_CSP.sjs?testid=img6_bad&type=img/png"> </img>
|
||||
<script src='http://example.org/tests/dom/security/test/csp/file_CSP.sjs?testid=script6_bad&type=text/javascript'></script>
|
||||
|
||||
<form method="get" action="file_iframe_sandbox_form_fail.html" id="a_form">
|
||||
First name: <input type="text" name="firstname">
|
||||
Last name: <input type="text" name="lastname">
|
||||
<input type="submit" onclick="doSubmit()" id="a_button">
|
||||
</form>
|
||||
|
||||
<a href = 'javascript:ok(true, "documents sandboxed with allow-scripts should be able to run script from javascript: URLs");' id='a_link'>click me</a>
|
||||
</body>
|
||||
</html>
|
||||
1
dom/security/test/csp/file_bug886164_6.html^headers^
Normal file
1
dom/security/test/csp/file_bug886164_6.html^headers^
Normal file
|
|
@ -0,0 +1 @@
|
|||
Content-Security-Policy: default-src 'self' 'unsafe-inline';
|
||||
28
dom/security/test/csp/file_bug888172.html
Normal file
28
dom/security/test/csp/file_bug888172.html
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
<!doctype html>
|
||||
<html>
|
||||
<body>
|
||||
<ol>
|
||||
<li id="unsafe-inline-script">Inline script (green if allowed, black if blocked)</li>
|
||||
<li id="unsafe-eval-script">Eval script (green if allowed, black if blocked)</li>
|
||||
<li id="unsafe-inline-style">Inline style (green if allowed, black if blocked)</li>
|
||||
</ol>
|
||||
|
||||
<script>
|
||||
// Use inline script to set a style attribute
|
||||
document.getElementById("unsafe-inline-script").style.color = "green";
|
||||
|
||||
// Use eval to set a style attribute
|
||||
// try/catch is used because CSP causes eval to throw an exception when it
|
||||
// is blocked, which would derail the rest of the tests in this file.
|
||||
try {
|
||||
eval('document.getElementById("unsafe-eval-script").style.color = "green";');
|
||||
} catch (e) {}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
li#unsafe-inline-style {
|
||||
color: green;
|
||||
}
|
||||
</style>
|
||||
</body>
|
||||
</html>
|
||||
43
dom/security/test/csp/file_bug888172.sjs
Normal file
43
dom/security/test/csp/file_bug888172.sjs
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
// SJS file for CSP mochitests
|
||||
|
||||
Components.utils.import("resource://gre/modules/NetUtil.jsm");
|
||||
|
||||
function loadHTMLFromFile(path) {
|
||||
// Load the HTML to return in the response from file.
|
||||
// Since it's relative to the cwd of the test runner, we start there and
|
||||
// append to get to the actual path of the file.
|
||||
var testHTMLFile =
|
||||
Components.classes["@mozilla.org/file/directory_service;1"].
|
||||
getService(Components.interfaces.nsIProperties).
|
||||
get("CurWorkD", Components.interfaces.nsILocalFile);
|
||||
var dirs = path.split("/");
|
||||
for (var i = 0; i < dirs.length; i++) {
|
||||
testHTMLFile.append(dirs[i]);
|
||||
}
|
||||
var testHTMLFileStream =
|
||||
Components.classes["@mozilla.org/network/file-input-stream;1"].
|
||||
createInstance(Components.interfaces.nsIFileInputStream);
|
||||
testHTMLFileStream.init(testHTMLFile, -1, 0, 0);
|
||||
var testHTML = NetUtil.readInputStreamToString(testHTMLFileStream, testHTMLFileStream.available());
|
||||
return testHTML;
|
||||
}
|
||||
|
||||
function handleRequest(request, response)
|
||||
{
|
||||
var query = {};
|
||||
request.queryString.split('&').forEach(function (val) {
|
||||
var [name, value] = val.split('=');
|
||||
query[name] = unescape(value);
|
||||
});
|
||||
|
||||
// avoid confusing cache behaviors
|
||||
response.setHeader("Cache-Control", "no-cache", false);
|
||||
|
||||
// Deliver the CSP policy encoded in the URI
|
||||
if (query['csp'])
|
||||
response.setHeader("Content-Security-Policy", unescape(query['csp']), false);
|
||||
|
||||
// Send HTML to test allowed/blocked behaviors
|
||||
response.setHeader("Content-Type", "text/html", false);
|
||||
response.write(loadHTMLFromFile("tests/dom/security/test/csp/file_bug888172.html"));
|
||||
}
|
||||
20
dom/security/test/csp/file_bug909029_none.html
Normal file
20
dom/security/test/csp/file_bug909029_none.html
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<!-- file_CSP.sjs mocks a resource load -->
|
||||
<link rel='stylesheet' type='text/css'
|
||||
href='file_CSP.sjs?testid=noneExternalStylesBlocked&type=text/css' />
|
||||
</head>
|
||||
<body>
|
||||
<p id="inline-style">This should be green</p>
|
||||
<p id="inline-script">This should be black</p>
|
||||
<style>
|
||||
p#inline-style { color:rgb(0, 128, 0); }
|
||||
</style>
|
||||
<script>
|
||||
// Use inline script to set a style attribute
|
||||
document.getElementById("inline-script").style.color = "rgb(0, 128, 0)";
|
||||
</script>
|
||||
<img src="file_CSP.sjs?testid=noneExternalImgLoaded&type=img/png" />
|
||||
</body>
|
||||
</html>
|
||||
1
dom/security/test/csp/file_bug909029_none.html^headers^
Normal file
1
dom/security/test/csp/file_bug909029_none.html^headers^
Normal file
|
|
@ -0,0 +1 @@
|
|||
Content-Security-Policy: default-src * ; style-src 'none' 'unsafe-inline';
|
||||
19
dom/security/test/csp/file_bug909029_star.html
Normal file
19
dom/security/test/csp/file_bug909029_star.html
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<link rel='stylesheet' type='text/css'
|
||||
href='file_CSP.sjs?testid=starExternalStylesLoaded&type=text/css' />
|
||||
</head>
|
||||
<body>
|
||||
<p id="inline-style">This should be green</p>
|
||||
<p id="inline-script">This should be black</p>
|
||||
<style>
|
||||
p#inline-style { color:rgb(0, 128, 0); }
|
||||
</style>
|
||||
<script>
|
||||
// Use inline script to set a style attribute
|
||||
document.getElementById("inline-script").style.color = "rgb(0, 128, 0)";
|
||||
</script>
|
||||
<img src="file_CSP.sjs?testid=starExternalImgLoaded&type=img/png" />
|
||||
</body>
|
||||
</html>
|
||||
1
dom/security/test/csp/file_bug909029_star.html^headers^
Normal file
1
dom/security/test/csp/file_bug909029_star.html^headers^
Normal file
|
|
@ -0,0 +1 @@
|
|||
Content-Security-Policy: default-src *; style-src * 'unsafe-inline';
|
||||
52
dom/security/test/csp/file_bug910139.sjs
Normal file
52
dom/security/test/csp/file_bug910139.sjs
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
// Server side js file for bug 910139, see file test_bug910139.html for details.
|
||||
|
||||
Components.utils.import("resource://gre/modules/NetUtil.jsm");
|
||||
|
||||
function loadResponseFromFile(path) {
|
||||
var testHTMLFile =
|
||||
Components.classes["@mozilla.org/file/directory_service;1"].
|
||||
getService(Components.interfaces.nsIProperties).
|
||||
get("CurWorkD", Components.interfaces.nsILocalFile);
|
||||
var dirs = path.split("/");
|
||||
for (var i = 0; i < dirs.length; i++) {
|
||||
testHTMLFile.append(dirs[i]);
|
||||
}
|
||||
var testHTMLFileStream =
|
||||
Components.classes["@mozilla.org/network/file-input-stream;1"].
|
||||
createInstance(Components.interfaces.nsIFileInputStream);
|
||||
testHTMLFileStream.init(testHTMLFile, -1, 0, 0);
|
||||
var testHTML = NetUtil.readInputStreamToString(testHTMLFileStream, testHTMLFileStream.available());
|
||||
return testHTML;
|
||||
}
|
||||
|
||||
var policies = [
|
||||
"default-src 'self'; script-src 'self'", // CSP for checkAllowed
|
||||
"default-src 'self'; script-src *.example.com" // CSP for checkBlocked
|
||||
]
|
||||
|
||||
function getPolicy() {
|
||||
var index;
|
||||
// setState only accepts strings as arguments
|
||||
if (!getState("counter")) {
|
||||
index = 0;
|
||||
setState("counter", index.toString());
|
||||
}
|
||||
else {
|
||||
index = parseInt(getState("counter"));
|
||||
++index;
|
||||
setState("counter", index.toString());
|
||||
}
|
||||
return policies[index];
|
||||
}
|
||||
|
||||
function handleRequest(request, response)
|
||||
{
|
||||
// avoid confusing cache behaviors
|
||||
response.setHeader("Cache-Control", "no-cache", false);
|
||||
|
||||
// set the required CSP
|
||||
response.setHeader("Content-Security-Policy", getPolicy(), false);
|
||||
|
||||
// return the requested XML file.
|
||||
response.write(loadResponseFromFile("tests/dom/security/test/csp/file_bug910139.xml"));
|
||||
}
|
||||
28
dom/security/test/csp/file_bug910139.xml
Normal file
28
dom/security/test/csp/file_bug910139.xml
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<?xml-stylesheet type="text/xsl" href="file_bug910139.xsl"?>
|
||||
<catalog>
|
||||
<cd>
|
||||
<title>Empire Burlesque</title>
|
||||
<artist>Bob Dylan</artist>
|
||||
<country>USA</country>
|
||||
<company>Columbia</company>
|
||||
<price>10.90</price>
|
||||
<year>1985</year>
|
||||
</cd>
|
||||
<cd>
|
||||
<title>Hide your heart</title>
|
||||
<artist>Bonnie Tyler</artist>
|
||||
<country>UK</country>
|
||||
<company>CBS Records</company>
|
||||
<price>9.90</price>
|
||||
<year>1988</year>
|
||||
</cd>
|
||||
<cd>
|
||||
<title>Greatest Hits</title>
|
||||
<artist>Dolly Parton</artist>
|
||||
<country>USA</country>
|
||||
<company>RCA</company>
|
||||
<price>9.90</price>
|
||||
<year>1982</year>
|
||||
</cd>
|
||||
</catalog>
|
||||
27
dom/security/test/csp/file_bug910139.xsl
Normal file
27
dom/security/test/csp/file_bug910139.xsl
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<!-- Edited by XMLSpy® -->
|
||||
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
|
||||
|
||||
<xsl:template match="/">
|
||||
<html>
|
||||
<body>
|
||||
<h2 id="xsltheader">this xml file should be formatted using an xsl file(lower iframe should contain xml dump)!</h2>
|
||||
<table border="1">
|
||||
<tr bgcolor="#990099">
|
||||
<th>Title</th>
|
||||
<th>Artist</th>
|
||||
<th>Price</th>
|
||||
</tr>
|
||||
<xsl:for-each select="catalog/cd">
|
||||
<tr>
|
||||
<td><xsl:value-of select="title"/></td>
|
||||
<td><xsl:value-of select="artist"/></td>
|
||||
<td><xsl:value-of select="price"/></td>
|
||||
</tr>
|
||||
</xsl:for-each>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
</xsl:template>
|
||||
</xsl:stylesheet>
|
||||
|
||||
27
dom/security/test/csp/file_bug941404.html
Normal file
27
dom/security/test/csp/file_bug941404.html
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
<html>
|
||||
<head> <meta charset="utf-8"> </head>
|
||||
<body>
|
||||
|
||||
<!-- this should be allowed (no CSP)-->
|
||||
<img src="http://example.org/tests/dom/security/test/csp/file_CSP.sjs?testid=img_good&type=img/png"> </img>
|
||||
|
||||
|
||||
<script type="text/javascript">
|
||||
var req = new XMLHttpRequest();
|
||||
req.onload = function() {
|
||||
//this should be allowed (no CSP)
|
||||
try {
|
||||
var img = document.createElement("img");
|
||||
img.src="http://example.org/tests/dom/security/test/csp/file_CSP.sjs?testid=img2_good&type=img/png";
|
||||
document.body.appendChild(img);
|
||||
} catch(e) {
|
||||
console.log("yo: "+e);
|
||||
}
|
||||
};
|
||||
req.open("get", "file_bug941404_xhr.html", true);
|
||||
req.responseType = "document";
|
||||
req.send();
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
5
dom/security/test/csp/file_bug941404_xhr.html
Normal file
5
dom/security/test/csp/file_bug941404_xhr.html
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
<html>
|
||||
<head> <meta charset="utf-8"> </head>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
||||
1
dom/security/test/csp/file_bug941404_xhr.html^headers^
Normal file
1
dom/security/test/csp/file_bug941404_xhr.html^headers^
Normal file
|
|
@ -0,0 +1 @@
|
|||
Content-Security-Policy: default-src 'none' 'unsafe-inline' 'unsafe-eval'
|
||||
61
dom/security/test/csp/file_child-src_iframe.html
Normal file
61
dom/security/test/csp/file_child-src_iframe.html
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Bug 1045891</title>
|
||||
</head>
|
||||
<body>
|
||||
<iframe id="testframe"> </iframe>
|
||||
<script type="text/javascript">
|
||||
page_id = window.location.hash.substring(1);
|
||||
|
||||
function executeTest(ev) {
|
||||
testframe = document.getElementById('testframe');
|
||||
testframe.contentWindow.postMessage({id:page_id, message:"execute"}, 'http://mochi.test:8888');
|
||||
}
|
||||
|
||||
function reportError(ev) {
|
||||
window.parent.postMessage({id:page_id, message:"blocked"}, 'http://mochi.test:8888');
|
||||
cleanup();
|
||||
}
|
||||
|
||||
function recvMessage(ev) {
|
||||
if (ev.data.id == page_id) {
|
||||
window.parent.postMessage({id:ev.data.id, message:ev.data.message}, 'http://mochi.test:8888');
|
||||
cleanup();
|
||||
}
|
||||
}
|
||||
|
||||
function cleanup() {
|
||||
testframe = document.getElementById('testframe');
|
||||
window.removeEventListener('message', recvMessage);
|
||||
testframe.removeEventListener('load', executeTest);
|
||||
testframe.removeEventListener('error', reportError);
|
||||
}
|
||||
|
||||
|
||||
window.addEventListener('message', recvMessage, false);
|
||||
|
||||
try {
|
||||
// Please note that file_testserver.sjs?foo does not return a response.
|
||||
// For testing purposes this is not necessary because we only want to check
|
||||
// whether CSP allows or blocks the load.
|
||||
src = "file_testserver.sjs";
|
||||
src += "?file=" + escape("tests/dom/security/test/csp/file_child-src_inner_frame.html");
|
||||
src += "#" + escape(page_id);
|
||||
testframe = document.getElementById('testframe');
|
||||
|
||||
testframe.addEventListener('load', executeTest, false);
|
||||
testframe.addEventListener('error', reportError, false);
|
||||
|
||||
testframe.src = src;
|
||||
}
|
||||
catch (e) {
|
||||
if (e.message.match(/Failed to load script/)) {
|
||||
window.parent.postMessage({id:page_id, message:"blocked"}, 'http://mochi.test:8888');
|
||||
} else {
|
||||
window.parent.postMessage({id:page_id, message:"exception"}, 'http://mochi.test:8888');
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
21
dom/security/test/csp/file_child-src_inner_frame.html
Normal file
21
dom/security/test/csp/file_child-src_inner_frame.html
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Bug 1045891</title>
|
||||
</head>
|
||||
<body>
|
||||
<iframe id="innermosttestframe"> </iframe>
|
||||
<script type="text/javascript">
|
||||
page_id = window.location.hash.substring(1);
|
||||
|
||||
function recvMessage(ev) {
|
||||
if (ev.data.id == page_id) {
|
||||
window.parent.postMessage({id:ev.data.id, message:'allowed'}, 'http://mochi.test:8888');
|
||||
window.removeEventListener('message', recvMessage);
|
||||
}
|
||||
}
|
||||
|
||||
window.addEventListener('message', recvMessage, false);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
30
dom/security/test/csp/file_child-src_service_worker.html
Normal file
30
dom/security/test/csp/file_child-src_service_worker.html
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Bug 1045891</title>
|
||||
</head>
|
||||
<body>
|
||||
<script type="text/javascript">
|
||||
page_id = window.location.hash.substring(1);
|
||||
try {
|
||||
if ('serviceWorker' in navigator) {
|
||||
navigator.serviceWorker.register(
|
||||
'file_child-src_service_worker.js',
|
||||
{ scope: './' + page_id + '/' }
|
||||
).then(function(reg)
|
||||
{
|
||||
// registration worked
|
||||
reg.unregister().then(function() {
|
||||
window.parent.postMessage({id:page_id, message:"allowed"}, 'http://mochi.test:8888');
|
||||
});
|
||||
}).catch(function(error) {
|
||||
// registration failed
|
||||
window.parent.postMessage({id:page_id, message:"blocked"}, 'http://mochi.test:8888');
|
||||
});
|
||||
};
|
||||
} catch(ex) {
|
||||
window.parent.postMessage({id:page_id, message:"exception"}, 'http://mochi.test:8888');
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
3
dom/security/test/csp/file_child-src_service_worker.js
Normal file
3
dom/security/test/csp/file_child-src_service_worker.js
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
this.addEventListener('install', function(event) {
|
||||
close();
|
||||
});
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Bug 1045891</title>
|
||||
</head>
|
||||
<body>
|
||||
<script type="text/javascript">
|
||||
page_id = window.location.hash.substring(1);
|
||||
var redir = 'none';
|
||||
|
||||
page_id.split('_').forEach(function (val) {
|
||||
var [name, value] = val.split('-');
|
||||
if (name == 'redir') {
|
||||
redir = unescape(value);
|
||||
}
|
||||
});
|
||||
|
||||
try {
|
||||
worker = new SharedWorker('file_redirect_worker.sjs?path='
|
||||
+ escape("/tests/dom/security/test/csp/file_child-src_shared_worker.js")
|
||||
+ "&redir=" + redir
|
||||
+ "&page_id=" + page_id,
|
||||
page_id);
|
||||
worker.port.start();
|
||||
|
||||
worker.onerror = function(evt) {
|
||||
evt.preventDefault();
|
||||
window.parent.postMessage({id:page_id, message:"blocked"},
|
||||
'http://mochi.test:8888');
|
||||
}
|
||||
|
||||
worker.port.onmessage = function(ev) {
|
||||
window.parent.postMessage({id:page_id, message:"allowed"}, 'http://mochi.test:8888');
|
||||
};
|
||||
|
||||
worker.onerror = function() {
|
||||
window.parent.postMessage({id:page_id, message:"blocked"}, 'http://mochi.test:8888');
|
||||
};
|
||||
|
||||
worker.port.postMessage('foo');
|
||||
}
|
||||
catch (e) {
|
||||
window.parent.postMessage({id:page_id, message:"blocked"}, 'http://mochi.test:8888');
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
34
dom/security/test/csp/file_child-src_shared_worker.html
Normal file
34
dom/security/test/csp/file_child-src_shared_worker.html
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Bug 1045891</title>
|
||||
</head>
|
||||
<body>
|
||||
<script type="text/javascript">
|
||||
page_id = window.location.hash.substring(1);
|
||||
try {
|
||||
worker = new SharedWorker(
|
||||
'file_testserver.sjs?file='+
|
||||
escape("tests/dom/security/test/csp/file_child-src_shared_worker.js"),
|
||||
page_id);
|
||||
worker.port.start();
|
||||
|
||||
worker.onerror = function(evt) {
|
||||
evt.preventDefault();
|
||||
window.parent.postMessage({id:page_id, message:"blocked"},
|
||||
'http://mochi.test:8888');
|
||||
}
|
||||
|
||||
worker.port.onmessage = function(ev) {
|
||||
window.parent.postMessage({id:page_id, message:"allowed"},
|
||||
'http://mochi.test:8888');
|
||||
};
|
||||
worker.port.postMessage('foo');
|
||||
}
|
||||
catch (e) {
|
||||
window.parent.postMessage({id:page_id, message:"blocked"},
|
||||
'http://mochi.test:8888');
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
8
dom/security/test/csp/file_child-src_shared_worker.js
Normal file
8
dom/security/test/csp/file_child-src_shared_worker.js
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
onconnect = function(e) {
|
||||
var port = e.ports[0];
|
||||
port.addEventListener('message', function(e) {
|
||||
port.postMessage('success');
|
||||
});
|
||||
|
||||
port.start();
|
||||
}
|
||||
37
dom/security/test/csp/file_child-src_shared_worker_data.html
Normal file
37
dom/security/test/csp/file_child-src_shared_worker_data.html
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Bug 1045891</title>
|
||||
</head>
|
||||
<body>
|
||||
<script type="text/javascript">
|
||||
var page_id = window.location.hash.substring(1);
|
||||
var shared_worker = "onconnect = function(e) { " +
|
||||
"var port = e.ports[0];" +
|
||||
"port.addEventListener('message'," +
|
||||
"function(e) { port.postMessage('success'); });" +
|
||||
"port.start(); }";
|
||||
|
||||
try {
|
||||
var worker = new SharedWorker('data:application/javascript;charset=UTF-8,'+
|
||||
escape(shared_worker), page_id);
|
||||
worker.port.start();
|
||||
|
||||
worker.onerror = function(evt) {
|
||||
evt.preventDefault();
|
||||
window.parent.postMessage({id:page_id, message:"blocked"}, 'http://mochi.test:8888');
|
||||
}
|
||||
|
||||
worker.port.onmessage = function(ev) {
|
||||
window.parent.postMessage({id:page_id, message:"allowed"}, 'http://mochi.test:8888');
|
||||
};
|
||||
|
||||
worker.port.postMessage('foo');
|
||||
}
|
||||
catch (e) {
|
||||
window.parent.postMessage({id:page_id, message:"blocked"}, 'http://mochi.test:8888');
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
50
dom/security/test/csp/file_child-src_worker-redirect.html
Normal file
50
dom/security/test/csp/file_child-src_worker-redirect.html
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Bug 1045891</title>
|
||||
</head>
|
||||
<body>
|
||||
<script type="text/javascript">
|
||||
var page_id = window.location.hash.substring(1);
|
||||
var redir = 'none';
|
||||
|
||||
page_id.split('_').forEach(function (val) {
|
||||
var [name, value] = val.split('-');
|
||||
if (name == 'redir') {
|
||||
redir = unescape(value);
|
||||
}
|
||||
});
|
||||
|
||||
try {
|
||||
worker = new Worker('file_redirect_worker.sjs?path='
|
||||
+ escape("/tests/dom/security/test/csp/file_child-src_worker.js")
|
||||
+ "&redir=" + redir
|
||||
+ "&page_id=" + page_id
|
||||
);
|
||||
|
||||
worker.onerror = function(error) {
|
||||
var msg = error.message;
|
||||
if (msg.match(/^NetworkError/) || msg.match(/Failed to load worker script/)) {
|
||||
// this means CSP blocked it
|
||||
msg = "blocked";
|
||||
}
|
||||
window.parent.postMessage({id:page_id, message:msg}, 'http://mochi.test:8888');
|
||||
error.preventDefault();
|
||||
};
|
||||
|
||||
worker.onmessage = function(ev) {
|
||||
window.parent.postMessage({id:page_id, message:"allowed"}, 'http://mochi.test:8888');
|
||||
|
||||
};
|
||||
worker.postMessage('foo');
|
||||
}
|
||||
catch (e) {
|
||||
if (e.message.match(/Failed to load script/)) {
|
||||
window.parent.postMessage({id:page_id, message:"blocked"}, 'http://mochi.test:8888');
|
||||
} else {
|
||||
window.parent.postMessage({id:page_id, message:"exception"}, 'http://mochi.test:8888');
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
32
dom/security/test/csp/file_child-src_worker.html
Normal file
32
dom/security/test/csp/file_child-src_worker.html
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Bug 1045891</title>
|
||||
</head>
|
||||
<body>
|
||||
<script type="text/javascript">
|
||||
page_id = window.location.hash.substring(1);
|
||||
try {
|
||||
worker = new Worker('file_testserver.sjs?file='+escape("tests/dom/security/test/csp/file_child-src_worker.js"));
|
||||
|
||||
worker.onerror = function(e) {
|
||||
window.parent.postMessage({id:page_id, message:"blocked"}, 'http://mochi.test:8888');
|
||||
e.preventDefault();
|
||||
}
|
||||
|
||||
worker.onmessage = function(ev) {
|
||||
window.parent.postMessage({id:page_id, message:"allowed"}, 'http://mochi.test:8888');
|
||||
}
|
||||
|
||||
worker.postMessage('foo');
|
||||
}
|
||||
catch (e) {
|
||||
if (e.message.match(/Failed to load script/)) {
|
||||
window.parent.postMessage({id:page_id, message:"blocked"}, 'http://mochi.test:8888');
|
||||
} else {
|
||||
window.parent.postMessage({id:page_id, message:"exception"}, 'http://mochi.test:8888');
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
4
dom/security/test/csp/file_child-src_worker.js
Normal file
4
dom/security/test/csp/file_child-src_worker.js
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
onmessage = function(e) {
|
||||
postMessage('worker');
|
||||
};
|
||||
|
||||
33
dom/security/test/csp/file_child-src_worker_data.html
Normal file
33
dom/security/test/csp/file_child-src_worker_data.html
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Bug 1045891</title>
|
||||
</head>
|
||||
<body>
|
||||
<script type="text/javascript">
|
||||
page_id = window.location.hash.substring(1);
|
||||
try {
|
||||
worker = new Worker('data:application/javascript;charset=UTF-8,'+escape('onmessage = function(e) { postMessage("worker"); };'));
|
||||
|
||||
worker.onerror = function(e) {
|
||||
window.parent.postMessage({id:page_id, message:"blocked"}, 'http://mochi.test:8888');
|
||||
e.preventDefault();
|
||||
}
|
||||
|
||||
worker.onmessage = function(ev) {
|
||||
window.parent.postMessage({id:page_id, message:"allowed"}, 'http://mochi.test:8888');
|
||||
}
|
||||
|
||||
worker.postMessage('foo');
|
||||
}
|
||||
catch (e) {
|
||||
if (e.message.match(/Failed to load script/)) {
|
||||
window.parent.postMessage({id:page_id, message:"blocked"}, 'http://mochi.test:8888');
|
||||
} else {
|
||||
console.log(e);
|
||||
window.parent.postMessage({id:page_id, message:"exception"}, 'http://mochi.test:8888');
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
39
dom/security/test/csp/file_child_worker.js
Normal file
39
dom/security/test/csp/file_child_worker.js
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
function doXHR(uri) {
|
||||
try {
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open("GET", uri);
|
||||
xhr.send();
|
||||
} catch(ex) {}
|
||||
}
|
||||
|
||||
var sameBase = "http://mochi.test:8888/tests/dom/security/test/csp/file_CSP.sjs?testid=";
|
||||
var crossBase = "http://example.com/tests/dom/security/test/csp/file_CSP.sjs?testid=";
|
||||
|
||||
onmessage = (e) => {
|
||||
for (base of [sameBase, crossBase]) {
|
||||
var prefix;
|
||||
var suffix;
|
||||
if (e.data.inherited == "parent") {
|
||||
//Worker inherits CSP from parent worker
|
||||
prefix = base + "worker_child_inherited_parent_";
|
||||
suffix = base == sameBase ? "_good" : "_bad";
|
||||
} else if (e.data.inherited == "document") {
|
||||
//Worker inherits CSP from owner document -> parent worker -> subworker
|
||||
prefix = base + "worker_child_inherited_document_";
|
||||
suffix = base == sameBase ? "_good" : "_bad";
|
||||
} else {
|
||||
// Worker delivers CSP from HTTP header
|
||||
prefix = base + "worker_child_";
|
||||
suffix = base == sameBase ? "_same_bad" : "_cross_bad";
|
||||
}
|
||||
|
||||
doXHR(prefix + "xhr" + suffix);
|
||||
// Fetch is likely failed in subworker
|
||||
// See Bug 1273070 - Failed to fetch in subworker
|
||||
// Enable fetch test after the bug is fixed
|
||||
// fetch(prefix + "xhr" + suffix);
|
||||
try {
|
||||
importScripts(prefix + "script" + suffix);
|
||||
} catch(ex) {}
|
||||
}
|
||||
}
|
||||
1
dom/security/test/csp/file_child_worker.js^headers^
Normal file
1
dom/security/test/csp/file_child_worker.js^headers^
Normal file
|
|
@ -0,0 +1 @@
|
|||
Content-Security-Policy: default-src 'none'
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue