mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-24 19:37:15 +00:00
Merge mozilla-central to b2g-inbound
This commit is contained in:
commit
3ae80963ac
@ -3,7 +3,6 @@
|
||||
# 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/.
|
||||
|
||||
ifndef .PYMAKE
|
||||
ifeq (,$(MAKE_VERSION))
|
||||
$(error GNU Make is required)
|
||||
endif
|
||||
@ -11,7 +10,6 @@ make_min_ver := 3.81
|
||||
ifneq ($(make_min_ver),$(firstword $(sort $(make_min_ver) $(MAKE_VERSION))))
|
||||
$(error GNU Make $(make_min_ver) or higher is required)
|
||||
endif
|
||||
endif
|
||||
|
||||
export TOPLEVEL_BUILD := 1
|
||||
|
||||
|
@ -388,9 +388,6 @@ pref("content.ime.strict_policy", true);
|
||||
// $ adb shell start
|
||||
pref("browser.dom.window.dump.enabled", false);
|
||||
|
||||
// Turn on the CSP 1.0 parser for Content Security Policy headers
|
||||
pref("security.csp.speccompliant", true);
|
||||
|
||||
// Default Content Security Policy to apply to privileged and certified apps
|
||||
pref("security.apps.privileged.CSP.default", "default-src *; script-src 'self'; object-src 'none'; style-src 'self' 'unsafe-inline'");
|
||||
// If you change this CSP, make sure to update the fast path in nsCSPService.cpp
|
||||
|
@ -4,13 +4,6 @@
|
||||
|
||||
GAIA_PATH := gaia/profile
|
||||
|
||||
ifdef .PYMAKE
|
||||
# For use of GNU make in pymake builds.
|
||||
GAIA_MAKE=$(GMAKE)
|
||||
else
|
||||
GAIA_MAKE=$(MAKE)
|
||||
endif
|
||||
|
||||
# This is needed to avoid making run-b2g depend on mozglue
|
||||
WRAP_LDFLAGS :=
|
||||
|
||||
@ -19,6 +12,6 @@ GENERATED_DIRS += $(DIST)/bin/$(GAIA_PATH)
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
libs::
|
||||
+$(GAIA_MAKE) -j1 -C $(GAIADIR) clean
|
||||
+$(GAIA_MAKE) -j1 -C $(GAIADIR) profile
|
||||
+$(MAKE) -j1 -C $(GAIADIR) clean
|
||||
+$(MAKE) -j1 -C $(GAIADIR) profile
|
||||
(cd $(GAIADIR)/profile && tar $(TAR_CREATE_FLAGS) - .) | (cd $(abspath $(DIST))/bin/$(GAIA_PATH) && tar -xf -)
|
||||
|
@ -1524,9 +1524,6 @@ pref("social.sidebar.unload_timeout_ms", 10000);
|
||||
|
||||
pref("dom.identity.enabled", false);
|
||||
|
||||
// Turn on the CSP 1.0 parser for Content Security Policy headers
|
||||
pref("security.csp.speccompliant", true);
|
||||
|
||||
// Block insecure active content on https pages
|
||||
pref("security.mixed_content.block_active_content", true);
|
||||
|
||||
|
@ -90,6 +90,7 @@ SocialUI = {
|
||||
if (!this._initialized) {
|
||||
return;
|
||||
}
|
||||
SocialSidebar.saveWindowState();
|
||||
|
||||
Services.obs.removeObserver(this, "social:ambient-notification-changed");
|
||||
Services.obs.removeObserver(this, "social:profile-changed");
|
||||
@ -710,6 +711,11 @@ SocialSidebar = {
|
||||
},
|
||||
|
||||
restoreWindowState: function() {
|
||||
// Window state is used to allow different sidebar providers in each window.
|
||||
// We also store the provider used in a pref as the default sidebar to
|
||||
// maintain that state for users who do not restore window state. The
|
||||
// existence of social.sidebar.provider means the sidebar is open with that
|
||||
// provider.
|
||||
this._initialized = true;
|
||||
if (!this.canShow)
|
||||
return;
|
||||
@ -737,13 +743,22 @@ SocialSidebar = {
|
||||
let data = SessionStore.getWindowValue(window, "socialSidebar");
|
||||
// if this window doesn't have it's own state, use the state from the opener
|
||||
if (!data && window.opener && !window.opener.closed) {
|
||||
data = SessionStore.getWindowValue(window.opener, "socialSidebar");
|
||||
try {
|
||||
data = SessionStore.getWindowValue(window.opener, "socialSidebar");
|
||||
} catch(e) {
|
||||
// Window is not tracked, which happens on osx if the window is opened
|
||||
// from the hidden window. That happens when you close the last window
|
||||
// without quiting firefox, then open a new window.
|
||||
}
|
||||
}
|
||||
if (data) {
|
||||
data = JSON.parse(data);
|
||||
document.getElementById("social-sidebar-browser").setAttribute("origin", data.origin);
|
||||
if (!data.hidden)
|
||||
this.show(data.origin);
|
||||
} else if (Services.prefs.prefHasUserValue("social.sidebar.provider")) {
|
||||
// no window state, use the global state if it is available
|
||||
this.show(Services.prefs.getCharPref("social.sidebar.provider"));
|
||||
}
|
||||
},
|
||||
|
||||
@ -754,7 +769,18 @@ SocialSidebar = {
|
||||
"hidden": broadcaster.hidden,
|
||||
"origin": sidebarOrigin
|
||||
};
|
||||
SessionStore.setWindowValue(window, "socialSidebar", JSON.stringify(data));
|
||||
|
||||
// Save a global state for users who do not restore state.
|
||||
if (broadcaster.hidden)
|
||||
Services.prefs.clearUserPref("social.sidebar.provider");
|
||||
else
|
||||
Services.prefs.setCharPref("social.sidebar.provider", sidebarOrigin);
|
||||
|
||||
try {
|
||||
SessionStore.setWindowValue(window, "socialSidebar", JSON.stringify(data));
|
||||
} catch(e) {
|
||||
// window not tracked during uninit
|
||||
}
|
||||
},
|
||||
|
||||
setSidebarVisibilityState: function(aEnabled) {
|
||||
|
@ -34,22 +34,22 @@ addMessageListener("Browser:HideSessionRestoreButton", function (message) {
|
||||
}
|
||||
});
|
||||
|
||||
addEventListener("DOMFormHasPassword", function(event) {
|
||||
InsecurePasswordUtils.checkForInsecurePasswords(event.target);
|
||||
LoginManagerContent.onFormPassword(event);
|
||||
});
|
||||
addEventListener("DOMAutoComplete", function(event) {
|
||||
LoginManagerContent.onUsernameInput(event);
|
||||
});
|
||||
addEventListener("blur", function(event) {
|
||||
LoginManagerContent.onUsernameInput(event);
|
||||
});
|
||||
|
||||
if (Services.appinfo.processType == Services.appinfo.PROCESS_TYPE_CONTENT) {
|
||||
addEventListener("contextmenu", function (event) {
|
||||
sendAsyncMessage("contextmenu", {}, { event: event });
|
||||
}, false);
|
||||
} else {
|
||||
addEventListener("DOMFormHasPassword", function(event) {
|
||||
InsecurePasswordUtils.checkForInsecurePasswords(event.target);
|
||||
LoginManagerContent.onFormPassword(event);
|
||||
});
|
||||
addEventListener("DOMAutoComplete", function(event) {
|
||||
LoginManagerContent.onUsernameInput(event);
|
||||
});
|
||||
addEventListener("blur", function(event) {
|
||||
LoginManagerContent.onUsernameInput(event);
|
||||
});
|
||||
|
||||
addEventListener("mozUITour", function(event) {
|
||||
if (!Services.prefs.getBoolPref("browser.uitour.enabled"))
|
||||
return;
|
||||
|
@ -3,15 +3,13 @@
|
||||
|
||||
"use strict";
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
add_task(function* test_healthreport_search_recording() {
|
||||
try {
|
||||
let cm = Cc["@mozilla.org/categorymanager;1"].getService(Ci.nsICategoryManager);
|
||||
cm.getCategoryEntry("healthreport-js-provider-default", "SearchesProvider");
|
||||
} catch (ex) {
|
||||
// Health Report disabled, or no SearchesProvider.
|
||||
ok(true, "Firefox Health Report is not enabled.");
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -20,72 +18,63 @@ function test() {
|
||||
.wrappedJSObject
|
||||
.healthReporter;
|
||||
ok(reporter, "Health Reporter available.");
|
||||
reporter.onInit().then(function onInit() {
|
||||
let provider = reporter.getProvider("org.mozilla.searches");
|
||||
ok(provider, "Searches provider is available.");
|
||||
let m = provider.getMeasurement("counts", 3);
|
||||
yield reporter.onInit();
|
||||
let provider = reporter.getProvider("org.mozilla.searches");
|
||||
ok(provider, "Searches provider is available.");
|
||||
let m = provider.getMeasurement("counts", 3);
|
||||
|
||||
m.getValues().then(function onData(data) {
|
||||
let now = new Date();
|
||||
let oldCount = 0;
|
||||
let data = yield m.getValues();
|
||||
let now = new Date();
|
||||
let oldCount = 0;
|
||||
|
||||
// This will to be need changed if default search engine is not Google.
|
||||
let field = "google.urlbar";
|
||||
// This will to be need changed if default search engine is not Google.
|
||||
let field = "google.urlbar";
|
||||
|
||||
if (data.days.hasDay(now)) {
|
||||
let day = data.days.getDay(now);
|
||||
if (day.has(field)) {
|
||||
oldCount = day.get(field);
|
||||
}
|
||||
}
|
||||
if (data.days.hasDay(now)) {
|
||||
let day = data.days.getDay(now);
|
||||
if (day.has(field)) {
|
||||
oldCount = day.get(field);
|
||||
}
|
||||
}
|
||||
|
||||
let tab = gBrowser.addTab();
|
||||
gBrowser.selectedTab = tab;
|
||||
let tab = gBrowser.addTab();
|
||||
gBrowser.selectedTab = tab;
|
||||
|
||||
let searchStr = "firefox health report";
|
||||
let expectedURL = Services.search.currentEngine.
|
||||
getSubmission(searchStr, "", "keyword").uri.spec;
|
||||
let searchStr = "firefox health report";
|
||||
let expectedURL = Services.search.currentEngine.
|
||||
getSubmission(searchStr, "", "keyword").uri.spec;
|
||||
|
||||
// Expect the search URL to load but stop it as soon as it starts.
|
||||
let loadPromise = waitForDocLoadAndStopIt(expectedURL);
|
||||
// Expect the search URL to load but stop it as soon as it starts.
|
||||
let docLoadPromise = waitForDocLoadAndStopIt(expectedURL);
|
||||
|
||||
// Meanwhile, poll for the new measurement.
|
||||
let count = 0;
|
||||
let measurementDeferred = Promise.defer();
|
||||
function getNewMeasurement() {
|
||||
if (count++ >= 10) {
|
||||
ok(false, "Timed out waiting for new measurement");
|
||||
measurementDeferred.resolve();
|
||||
return;
|
||||
}
|
||||
m.getValues().then(function onData(data) {
|
||||
if (data.days.hasDay(now)) {
|
||||
let day = data.days.getDay(now);
|
||||
if (day.has(field)) {
|
||||
let newCount = day.get(field);
|
||||
if (newCount > oldCount) {
|
||||
is(newCount, oldCount + 1,
|
||||
"Exactly one search has been recorded.");
|
||||
measurementDeferred.resolve();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
executeSoon(getNewMeasurement);
|
||||
});
|
||||
}
|
||||
executeSoon(getNewMeasurement);
|
||||
// Trigger the search.
|
||||
gURLBar.value = searchStr;
|
||||
gURLBar.handleCommand();
|
||||
|
||||
// Trigger the search.
|
||||
gURLBar.value = searchStr;
|
||||
gURLBar.handleCommand();
|
||||
yield docLoadPromise;
|
||||
|
||||
// Wait for the page load and new measurement.
|
||||
Promise.all([loadPromise, measurementDeferred.promise]).then(() => {
|
||||
gBrowser.removeTab(tab);
|
||||
finish();
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
data = yield m.getValues();
|
||||
ok(data.days.hasDay(now), "We have a search measurement for today.");
|
||||
let day = data.days.getDay(now);
|
||||
ok(day.has(field), "Have a search count for the urlbar.");
|
||||
let newCount = day.get(field);
|
||||
is(newCount, oldCount + 1, "We recorded one new search.");
|
||||
|
||||
// We should record the default search engine if Telemetry is enabled.
|
||||
let oldTelemetry = Services.prefs.getBoolPref("toolkit.telemetry.enabled");
|
||||
Services.prefs.setBoolPref("toolkit.telemetry.enabled", true);
|
||||
|
||||
m = provider.getMeasurement("engines", 1);
|
||||
yield provider.collectDailyData();
|
||||
data = yield m.getValues();
|
||||
|
||||
ok(data.days.hasDay(now), "Have engines data when Telemetry is enabled.");
|
||||
day = data.days.getDay(now);
|
||||
ok(day.has("default"), "We have default engine data.");
|
||||
is(day.get("default"), "google", "The default engine is reported properly.");
|
||||
|
||||
// Restore.
|
||||
Services.prefs.setBoolPref("toolkit.telemetry.enabled", oldTelemetry);
|
||||
|
||||
gBrowser.removeTab(tab);
|
||||
});
|
||||
|
@ -30,17 +30,20 @@ function openWindowAndWaitForInit(parentWin, callback) {
|
||||
}, topic, false);
|
||||
}
|
||||
|
||||
function closeWindow(w, cb) {
|
||||
waitForNotification("domwindowclosed", cb);
|
||||
w.close();
|
||||
}
|
||||
|
||||
function closeOneWindow(cb) {
|
||||
let w = createdWindows.pop();
|
||||
if (!w) {
|
||||
if (!w || w.closed) {
|
||||
cb();
|
||||
return;
|
||||
}
|
||||
waitForCondition(function() w.closed,
|
||||
function() {
|
||||
info("window closed, " + createdWindows.length + " windows left");
|
||||
closeOneWindow(cb);
|
||||
}, "window did not close");
|
||||
closeWindow(w, function() {
|
||||
closeOneWindow(cb);
|
||||
});
|
||||
w.close();
|
||||
}
|
||||
|
||||
@ -126,6 +129,51 @@ let tests = {
|
||||
}, cbnext);
|
||||
},
|
||||
|
||||
testGlobalState: function(cbnext) {
|
||||
setManifestPref("social.manifest.test", manifest);
|
||||
ok(!SocialSidebar.opened, "sidebar is closed initially");
|
||||
ok(!Services.prefs.prefHasUserValue("social.sidebar.provider"), "global state unset");
|
||||
// mimick no session state in opener so we exercise the global state via pref
|
||||
SessionStore.deleteWindowValue(window, "socialSidebar");
|
||||
ok(!SessionStore.getWindowValue(window, "socialSidebar"), "window state unset");
|
||||
SocialService.addProvider(manifest, function() {
|
||||
openWindowAndWaitForInit(window, function(w1) {
|
||||
w1.SocialSidebar.show();
|
||||
waitForCondition(function() w1.SocialSidebar.opened,
|
||||
function() {
|
||||
ok(Services.prefs.prefHasUserValue("social.sidebar.provider"), "global state set");
|
||||
ok(!SocialSidebar.opened, "1. main sidebar is still closed");
|
||||
ok(w1.SocialSidebar.opened, "1. window sidebar is open");
|
||||
closeWindow(w1, function() {
|
||||
// this time, the global state should cause the sidebar to be opened
|
||||
// in the new window
|
||||
openWindowAndWaitForInit(window, function(w1) {
|
||||
ok(!SocialSidebar.opened, "2. main sidebar is still closed");
|
||||
ok(w1.SocialSidebar.opened, "2. window sidebar is open");
|
||||
w1.SocialSidebar.hide();
|
||||
ok(!w1.SocialSidebar.opened, "2. window sidebar is closed");
|
||||
ok(!Services.prefs.prefHasUserValue("social.sidebar.provider"), "2. global state unset");
|
||||
// global state should now be no sidebar gets opened on new window
|
||||
closeWindow(w1, function() {
|
||||
ok(!Services.prefs.prefHasUserValue("social.sidebar.provider"), "3. global state unset");
|
||||
ok(!SocialSidebar.opened, "3. main sidebar is still closed");
|
||||
openWindowAndWaitForInit(window, function(w1) {
|
||||
ok(!Services.prefs.prefHasUserValue("social.sidebar.provider"), "4. global state unset");
|
||||
ok(!SocialSidebar.opened, "4. main sidebar is still closed");
|
||||
ok(!w1.SocialSidebar.opened, "4. window sidebar is closed");
|
||||
SocialService.removeProvider(manifest.origin, function() {
|
||||
Services.prefs.clearUserPref("social.manifest.test");
|
||||
cbnext();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
// Check per window sidebar functionality, including migration from using
|
||||
// prefs to using session state, and state inheritance of windows (new windows
|
||||
// inherit state from the opener).
|
||||
|
@ -93,6 +93,9 @@ XPCOMUtils.defineLazyModuleGetter(this, "BrowserUITelemetry",
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "AsyncShutdown",
|
||||
"resource://gre/modules/AsyncShutdown.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "LoginManagerParent",
|
||||
"resource://gre/modules/LoginManagerParent.jsm");
|
||||
|
||||
#ifdef NIGHTLY_BUILD
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "SignInToWebsiteUX",
|
||||
"resource:///modules/SignInToWebsite.jsm");
|
||||
@ -507,6 +510,8 @@ BrowserGlue.prototype = {
|
||||
RemotePrompt.init();
|
||||
}
|
||||
|
||||
LoginManagerParent.init();
|
||||
|
||||
Services.obs.notifyObservers(null, "browser-ui-startup-complete", "");
|
||||
},
|
||||
|
||||
|
@ -53,8 +53,6 @@ support-files =
|
||||
test-bug-782653-css-errors-1.css
|
||||
test-bug-782653-css-errors-2.css
|
||||
test-bug-782653-css-errors.html
|
||||
test-bug-821877-csperrors.html
|
||||
test-bug-821877-csperrors.html^headers^
|
||||
test-bug-837351-security-errors.html
|
||||
test-bug-846918-hsts-invalid-headers.html
|
||||
test-bug-846918-hsts-invalid-headers.html^headers^
|
||||
@ -100,8 +98,6 @@ support-files =
|
||||
test-repeated-messages.html
|
||||
test-result-format-as-string.html
|
||||
test-webconsole-error-observer.html
|
||||
test_bug_770099_bad_policy_uri.html
|
||||
test_bug_770099_bad_policy_uri.html^headers^
|
||||
test_bug_770099_violation.html
|
||||
test_bug_770099_violation.html^headers^
|
||||
test-autocomplete-in-stackframe.html
|
||||
@ -230,13 +226,11 @@ run-if = os == "win"
|
||||
[browser_webconsole_bug_762593_insecure_passwords_web_console_warning.js]
|
||||
[browser_webconsole_bug_764572_output_open_url.js]
|
||||
[browser_webconsole_bug_766001_JS_Console_in_Debugger.js]
|
||||
[browser_webconsole_bug_770099_bad_policyuri.js]
|
||||
[browser_webconsole_bug_770099_violation.js]
|
||||
[browser_webconsole_bug_782653_CSS_links_in_Style_Editor.js]
|
||||
[browser_webconsole_bug_804845_ctrl_key_nav.js]
|
||||
run-if = os == "mac"
|
||||
[browser_webconsole_bug_817834_add_edited_input_to_history.js]
|
||||
[browser_webconsole_bug_821877_csp_errors.js]
|
||||
[browser_webconsole_bug_837351_securityerrors.js]
|
||||
[browser_webconsole_bug_846918_hsts_invalid-headers.js]
|
||||
[browser_webconsole_bug_915141_toggle_response_logging_with_keyboard.js]
|
||||
|
@ -15,8 +15,8 @@ The expected console messages in the constants CSP_VIOLATION_MSG and CSP_REPORT_
|
||||
*/
|
||||
|
||||
const TEST_VIOLATION = "http://example.com/browser/browser/devtools/webconsole/test/test_bug_1010953_cspro.html";
|
||||
const CSP_VIOLATION_MSG = 'Content Security Policy: The page\'s settings blocked the loading of a resource at http://some.example.com/test.png ("img-src http://example.com:80").';
|
||||
const CSP_REPORT_MSG = 'Content Security Policy: The page\'s settings observed the loading of a resource at http://some.example.com/test_bug_1010953_cspro.js ("script-src http://example.com:80"). A CSP report is being sent.';
|
||||
const CSP_VIOLATION_MSG = 'Content Security Policy: The page\'s settings blocked the loading of a resource at http://some.example.com/test.png ("img-src http://example.com").';
|
||||
const CSP_REPORT_MSG = 'Content Security Policy: The page\'s settings observed the loading of a resource at http://some.example.com/test_bug_1010953_cspro.js ("script-src http://example.com"). A CSP report is being sent.';
|
||||
|
||||
|
||||
let hud = undefined;
|
||||
|
@ -1,40 +0,0 @@
|
||||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
// Tests that the Web Console CSP messages are displayed
|
||||
|
||||
const TEST_BAD_POLICY_URI = "https://example.com/browser/browser/devtools/webconsole/test/test_bug_770099_bad_policy_uri.html";
|
||||
|
||||
let hud = undefined;
|
||||
|
||||
function test() {
|
||||
addTab("data:text/html;charset=utf8,Web Console CSP bad policy URI test");
|
||||
browser.addEventListener("load", function _onLoad() {
|
||||
browser.removeEventListener("load", _onLoad, true);
|
||||
openConsole(null, loadDocument);
|
||||
}, true);
|
||||
}
|
||||
|
||||
function loadDocument(theHud) {
|
||||
hud = theHud;
|
||||
hud.jsterm.clearOutput();
|
||||
browser.addEventListener("load", onLoad, true);
|
||||
content.location = TEST_BAD_POLICY_URI;
|
||||
}
|
||||
|
||||
function onLoad(aEvent) {
|
||||
browser.removeEventListener("load", onLoad, true);
|
||||
|
||||
waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [{
|
||||
text: "can't fetch policy",
|
||||
category: CATEGORY_SECURITY,
|
||||
severity: SEVERITY_ERROR,
|
||||
}],
|
||||
}).then(finishTest);
|
||||
}
|
@ -8,7 +8,7 @@
|
||||
// Tests that the Web Console CSP messages are displayed
|
||||
|
||||
const TEST_VIOLATION = "https://example.com/browser/browser/devtools/webconsole/test/test_bug_770099_violation.html";
|
||||
const CSP_VIOLATION_MSG = 'Content Security Policy: The page\'s settings blocked the loading of a resource at http://some.example.com/test.png ("default-src https://example.com:443").'
|
||||
const CSP_VIOLATION_MSG = 'Content Security Policy: The page\'s settings blocked the loading of a resource at http://some.example.com/test.png ("default-src https://example.com").'
|
||||
|
||||
let hud = undefined;
|
||||
|
||||
|
@ -1,28 +0,0 @@
|
||||
// Tests that CSP errors from nsDocument::InitCSP are logged to the Web Console
|
||||
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
const TEST_URI = "https://example.com/browser/browser/devtools/webconsole/test/test-bug-821877-csperrors.html";
|
||||
const CSP_DEPRECATED_HEADER_MSG = "The X-Content-Security-Policy and X-Content-Security-Report-Only headers will be deprecated in the future. Please use the Content-Security-Policy and Content-Security-Report-Only headers with CSP spec compliant syntax instead.";
|
||||
|
||||
function test()
|
||||
{
|
||||
addTab(TEST_URI);
|
||||
browser.addEventListener("load", function onLoad(aEvent) {
|
||||
browser.removeEventListener(aEvent.type, onLoad, true);
|
||||
openConsole(null, function testCSPErrorLogged (hud) {
|
||||
waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [
|
||||
{
|
||||
name: "Deprecated CSP header error displayed successfully",
|
||||
text: CSP_DEPRECATED_HEADER_MSG,
|
||||
category: CATEGORY_SECURITY,
|
||||
severity: SEVERITY_WARNING
|
||||
},
|
||||
],
|
||||
}).then(finishTest);
|
||||
});
|
||||
}, true);
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf8">
|
||||
<title>Bug 821877 - Log CSP Errors to Web Console</title>
|
||||
<!-- Any copyright is dedicated to the Public Domain.
|
||||
- http://creativecommons.org/publicdomain/zero/1.0/ -->
|
||||
</head>
|
||||
<body>
|
||||
<p>This page is served with a deprecated CSP header.</p>
|
||||
</body>
|
||||
</html>
|
@ -1 +0,0 @@
|
||||
X-Content-Security-Policy: default-src *; options inline-script
|
@ -1,12 +0,0 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Test for Bug 770099 - bad policy-uri</title>
|
||||
<!-- Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ -->
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=770099">Mozilla Bug 770099</a>
|
||||
</body>
|
||||
</html>
|
@ -1,2 +0,0 @@
|
||||
X-Content-Security-Policy: policy-uri http://example.com/some_policy
|
||||
Content-type: text/html; charset=utf-8
|
@ -1 +1 @@
|
||||
X-Content-Security-Policy: default-src 'self'
|
||||
Content-Security-Policy: default-src 'self'
|
||||
|
@ -597,6 +597,7 @@ Experiments.Experiments.prototype = {
|
||||
active: experiment.enabled,
|
||||
endDate: experiment.endDate.getTime(),
|
||||
detailURL: experiment._homepageURL,
|
||||
branch: experiment.branch,
|
||||
});
|
||||
}
|
||||
|
||||
@ -628,6 +629,54 @@ Experiments.Experiments.prototype = {
|
||||
return info;
|
||||
},
|
||||
|
||||
/**
|
||||
* Experiment "branch" support. If an experiment has multiple branches, it
|
||||
* can record the branch with the experiment system and it will
|
||||
* automatically be included in data reporting (FHR/telemetry payloads).
|
||||
*/
|
||||
|
||||
/**
|
||||
* Set the experiment branch for the specified experiment ID.
|
||||
* @returns Promise<>
|
||||
*/
|
||||
setExperimentBranch: Task.async(function*(id, branchstr) {
|
||||
yield this._loadTask;
|
||||
let e = this._experiments.get(id);
|
||||
if (!e) {
|
||||
throw new Error("Experiment not found");
|
||||
}
|
||||
e.branch = String(branchstr);
|
||||
this._dirty = true;
|
||||
Services.obs.notifyObservers(null, EXPERIMENTS_CHANGED_TOPIC, null);
|
||||
yield this._run();
|
||||
}),
|
||||
/**
|
||||
* Get the branch of the specified experiment. If the experiment is unknown,
|
||||
* throws an error.
|
||||
*
|
||||
* @param id The ID of the experiment. Pass null for the currently running
|
||||
* experiment.
|
||||
* @returns Promise<string|null>
|
||||
* @throws Error if the specified experiment ID is unknown, or if there is no
|
||||
* current experiment.
|
||||
*/
|
||||
getExperimentBranch: Task.async(function*(id=null) {
|
||||
yield this._loadTask;
|
||||
let e;
|
||||
if (id) {
|
||||
e = this._experiments.get(id);
|
||||
if (!e) {
|
||||
throw new Error("Experiment not found");
|
||||
}
|
||||
} else {
|
||||
e = this._getActiveExperiment();
|
||||
if (e === null) {
|
||||
throw new Error("No active experiment");
|
||||
}
|
||||
}
|
||||
return e.branch;
|
||||
}),
|
||||
|
||||
/**
|
||||
* Determine whether another date has the same UTC day as now().
|
||||
*/
|
||||
@ -1013,6 +1062,17 @@ Experiments.Experiments.prototype = {
|
||||
return e.id;
|
||||
},
|
||||
|
||||
getActiveExperimentBranch: function() {
|
||||
if (!this._experiments) {
|
||||
return null;
|
||||
}
|
||||
let e = this._getActiveExperiment();
|
||||
if (!e) {
|
||||
return null;
|
||||
}
|
||||
return e.branch;
|
||||
},
|
||||
|
||||
_getActiveExperiment: function () {
|
||||
let enabled = [experiment for ([,experiment] of this._experiments) if (experiment._enabled)];
|
||||
|
||||
@ -1258,6 +1318,8 @@ Experiments.ExperimentEntry = function (policy) {
|
||||
this._lastChangedDate = null;
|
||||
// Has this experiment failed to activate before?
|
||||
this._failedStart = false;
|
||||
// The experiment branch
|
||||
this._branch = null;
|
||||
|
||||
// We grab these from the addon after download.
|
||||
this._name = null;
|
||||
@ -1306,6 +1368,7 @@ Experiments.ExperimentEntry.prototype = {
|
||||
"_addonId",
|
||||
"_startDate",
|
||||
"_endDate",
|
||||
"_branch",
|
||||
]),
|
||||
|
||||
DATE_KEYS: new Set([
|
||||
@ -1313,6 +1376,10 @@ Experiments.ExperimentEntry.prototype = {
|
||||
"_endDate",
|
||||
]),
|
||||
|
||||
UPGRADE_KEYS: new Map([
|
||||
["_branch", null],
|
||||
]),
|
||||
|
||||
ADDON_CHANGE_NONE: 0,
|
||||
ADDON_CHANGE_INSTALL: 1,
|
||||
ADDON_CHANGE_UNINSTALL: 2,
|
||||
@ -1344,6 +1411,14 @@ Experiments.ExperimentEntry.prototype = {
|
||||
return this._manifestData.id;
|
||||
},
|
||||
|
||||
get branch() {
|
||||
return this._branch;
|
||||
},
|
||||
|
||||
set branch(v) {
|
||||
this._branch = v;
|
||||
},
|
||||
|
||||
get startDate() {
|
||||
return this._startDate;
|
||||
},
|
||||
@ -1376,6 +1451,12 @@ Experiments.ExperimentEntry.prototype = {
|
||||
* @return boolean Whether initialization succeeded.
|
||||
*/
|
||||
initFromCacheData: function (data) {
|
||||
for (let [key, dval] of this.UPGRADE_KEYS) {
|
||||
if (!(key in data)) {
|
||||
data.set(key, dval);
|
||||
}
|
||||
}
|
||||
|
||||
for (let key of this.SERIALIZE_KEYS) {
|
||||
if (!(key in data) && !this.DATE_KEYS.has(key)) {
|
||||
this._log.error("initFromCacheData() - missing required key " + key);
|
||||
@ -1970,6 +2051,9 @@ let stripDateToMidnight = function (d) {
|
||||
function ExperimentsLastActiveMeasurement1() {
|
||||
Metrics.Measurement.call(this);
|
||||
}
|
||||
function ExperimentsLastActiveMeasurement2() {
|
||||
Metrics.Measurement.call(this);
|
||||
}
|
||||
|
||||
const FIELD_DAILY_LAST_TEXT = {type: Metrics.Storage.FIELD_DAILY_LAST_TEXT};
|
||||
|
||||
@ -1983,6 +2067,17 @@ ExperimentsLastActiveMeasurement1.prototype = Object.freeze({
|
||||
lastActive: FIELD_DAILY_LAST_TEXT,
|
||||
}
|
||||
});
|
||||
ExperimentsLastActiveMeasurement2.prototype = Object.freeze({
|
||||
__proto__: Metrics.Measurement.prototype,
|
||||
|
||||
name: "info",
|
||||
version: 2,
|
||||
|
||||
fields: {
|
||||
lastActive: FIELD_DAILY_LAST_TEXT,
|
||||
lastActiveBranch: FIELD_DAILY_LAST_TEXT,
|
||||
}
|
||||
});
|
||||
|
||||
this.ExperimentsProvider = function () {
|
||||
Metrics.Provider.call(this);
|
||||
@ -1997,6 +2092,7 @@ ExperimentsProvider.prototype = Object.freeze({
|
||||
|
||||
measurementTypes: [
|
||||
ExperimentsLastActiveMeasurement1,
|
||||
ExperimentsLastActiveMeasurement2,
|
||||
],
|
||||
|
||||
_OBSERVERS: [
|
||||
@ -2040,8 +2136,8 @@ ExperimentsProvider.prototype = Object.freeze({
|
||||
this._experiments = Experiments.instance();
|
||||
}
|
||||
|
||||
let m = this.getMeasurement(ExperimentsLastActiveMeasurement1.prototype.name,
|
||||
ExperimentsLastActiveMeasurement1.prototype.version);
|
||||
let m = this.getMeasurement(ExperimentsLastActiveMeasurement2.prototype.name,
|
||||
ExperimentsLastActiveMeasurement2.prototype.version);
|
||||
|
||||
return this.enqueueStorageOperation(() => {
|
||||
return Task.spawn(function* recordTask() {
|
||||
@ -2055,6 +2151,11 @@ ExperimentsProvider.prototype = Object.freeze({
|
||||
this._log.info("Recording last active experiment: " + todayActive.id);
|
||||
yield m.setDailyLastText("lastActive", todayActive.id,
|
||||
this._experiments._policy.now());
|
||||
let branch = todayActive.branch;
|
||||
if (branch) {
|
||||
yield m.setDailyLastText("lastActiveBranch", branch,
|
||||
this._experiments._policy.now());
|
||||
}
|
||||
}.bind(this));
|
||||
});
|
||||
},
|
||||
|
@ -76,6 +76,7 @@ const FAKE_EXPERIMENTS_1 = [
|
||||
description: "experiment 1",
|
||||
active: true,
|
||||
detailUrl: "https://dummy/experiment1",
|
||||
branch: "foo",
|
||||
},
|
||||
];
|
||||
|
||||
@ -87,6 +88,7 @@ const FAKE_EXPERIMENTS_2 = [
|
||||
active: false,
|
||||
endDate: new Date(2014, 2, 11, 2, 4, 35, 42).getTime(),
|
||||
detailUrl: "https://dummy/experiment2",
|
||||
branch: null,
|
||||
},
|
||||
{
|
||||
id: "id1",
|
||||
@ -95,6 +97,7 @@ const FAKE_EXPERIMENTS_2 = [
|
||||
active: false,
|
||||
endDate: new Date(2014, 2, 10, 0, 0, 0, 0).getTime(),
|
||||
detailURL: "https://dummy/experiment1",
|
||||
branch: null,
|
||||
},
|
||||
];
|
||||
|
||||
|
@ -171,6 +171,14 @@ add_task(function* test_getExperiments() {
|
||||
let addons = yield getExperimentAddons();
|
||||
Assert.equal(addons.length, 0, "Precondition: No experiment add-ons are installed.");
|
||||
|
||||
try {
|
||||
let b = yield experiments.getExperimentBranch();
|
||||
Assert.ok(false, "getExperimentBranch should fail with no experiment");
|
||||
}
|
||||
catch (e) {
|
||||
Assert.ok(true, "getExperimentBranch correctly threw");
|
||||
}
|
||||
|
||||
// Trigger update, clock set for experiment 1 to start.
|
||||
|
||||
now = futureDate(startDate1, 5 * MS_IN_ONE_DAY);
|
||||
@ -196,6 +204,19 @@ add_task(function* test_getExperiments() {
|
||||
"Property " + k + " should match reference data.");
|
||||
}
|
||||
|
||||
let b = yield experiments.getExperimentBranch();
|
||||
Assert.strictEqual(b, null, "getExperimentBranch should return null by default");
|
||||
|
||||
b = yield experiments.getExperimentBranch(EXPERIMENT1_ID);
|
||||
Assert.strictEqual(b, null, "getExperimentsBranch should return null (with id)");
|
||||
|
||||
yield experiments.setExperimentBranch(EXPERIMENT1_ID, "foo");
|
||||
b = yield experiments.getExperimentBranch();
|
||||
Assert.strictEqual(b, "foo", "getExperimentsBranch should return the set value");
|
||||
|
||||
Assert.equal(observerFireCount, ++expectedObserverFireCount,
|
||||
"Experiments observer should have been called.");
|
||||
|
||||
Assert.equal(gTimerScheduleOffset, 10 * MS_IN_ONE_DAY,
|
||||
"Experiment re-evaluation should have been scheduled correctly.");
|
||||
|
||||
|
@ -190,6 +190,13 @@ add_task(function* test_cache() {
|
||||
checkExperimentListsEqual(experimentListData.slice(1), list);
|
||||
checkExperimentSerializations(experiments._experiments.values());
|
||||
|
||||
let branch = yield experiments.getExperimentBranch(EXPERIMENT1_ID);
|
||||
Assert.strictEqual(branch, null);
|
||||
|
||||
yield experiments.setExperimentBranch(EXPERIMENT1_ID, "testbranch");
|
||||
branch = yield experiments.getExperimentBranch(EXPERIMENT1_ID);
|
||||
Assert.strictEqual(branch, "testbranch");
|
||||
|
||||
// Re-init, clock set for experiment 1 to stop.
|
||||
|
||||
now = futureDate(now, 20 * MS_IN_ONE_DAY);
|
||||
@ -207,6 +214,9 @@ add_task(function* test_cache() {
|
||||
checkExperimentListsEqual(experimentListData.slice(1), list);
|
||||
checkExperimentSerializations(experiments._experiments.values());
|
||||
|
||||
branch = yield experiments.getExperimentBranch(EXPERIMENT1_ID);
|
||||
Assert.strictEqual(branch, "testbranch");
|
||||
|
||||
// Re-init, clock set for experiment 2 to start.
|
||||
|
||||
now = futureDate(startDates[1], 20 * MS_IN_ONE_DAY);
|
||||
|
@ -9,6 +9,8 @@ Cu.import("resource:///modules/experiments/Experiments.jsm");
|
||||
Cu.import("resource://testing-common/services/healthreport/utils.jsm");
|
||||
Cu.import("resource://testing-common/services-common/logging.js");
|
||||
|
||||
const kMeasurementVersion = 2;
|
||||
|
||||
function getStorageAndProvider(name) {
|
||||
return Task.spawn(function* get() {
|
||||
let storage = yield Metrics.Storage(name);
|
||||
@ -53,7 +55,7 @@ add_task(function* test_collect() {
|
||||
|
||||
// Initial state should not report anything.
|
||||
yield provider.collectDailyData();
|
||||
let m = provider.getMeasurement("info", 1);
|
||||
let m = provider.getMeasurement("info", kMeasurementVersion);
|
||||
let values = yield m.getValues();
|
||||
Assert.equal(values.days.size, 0, "Have no data if no experiments known.");
|
||||
|
||||
@ -69,6 +71,8 @@ add_task(function* test_collect() {
|
||||
let day = values.days.getDay(now);
|
||||
Assert.ok(day.has("lastActive"), "Has lastActive field.");
|
||||
Assert.equal(day.get("lastActive"), "id2", "Last active ID is sane.");
|
||||
Assert.strictEqual(day.get("lastActiveBranch"), undefined,
|
||||
"no branch should be set yet");
|
||||
|
||||
// Making an experiment active replaces the lastActive value.
|
||||
replaceExperiments(provider._experiments, FAKE_EXPERIMENTS_1);
|
||||
@ -76,6 +80,8 @@ add_task(function* test_collect() {
|
||||
values = yield m.getValues();
|
||||
day = values.days.getDay(now);
|
||||
Assert.equal(day.get("lastActive"), "id1", "Last active ID is the active experiment.");
|
||||
Assert.equal(day.get("lastActiveBranch"), "foo",
|
||||
"Experiment branch should be visible");
|
||||
|
||||
// And make sure the observer works.
|
||||
replaceExperiments(provider._experiments, FAKE_EXPERIMENTS_2);
|
||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -7,6 +7,9 @@
|
||||
Cu.import("resource://gre/modules/devtools/dbg-server.jsm")
|
||||
Cu.import("resource://gre/modules/WindowsPrefSync.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "LoginManagerParent",
|
||||
"resource://gre/modules/LoginManagerParent.jsm");
|
||||
|
||||
/**
|
||||
* Constants
|
||||
*/
|
||||
@ -167,6 +170,7 @@ var BrowserUI = {
|
||||
DialogUI.init();
|
||||
FormHelperUI.init();
|
||||
FindHelperUI.init();
|
||||
LoginManagerParent.init();
|
||||
#ifdef NIGHTLY_BUILD
|
||||
PdfJs.init();
|
||||
#endif
|
||||
|
@ -185,9 +185,7 @@ dnl A high level macro for selecting compiler options.
|
||||
AC_DEFUN([MOZ_COMPILER_OPTS],
|
||||
[
|
||||
if test "${MOZ_PSEUDO_DERECURSE-unset}" = unset; then
|
||||
dnl Don't enable on pymake, because of bug 918652. Bug 912979 is an annoyance
|
||||
dnl with pymake, too.
|
||||
MOZ_PSEUDO_DERECURSE=no-pymake
|
||||
MOZ_PSEUDO_DERECURSE=1
|
||||
fi
|
||||
|
||||
MOZ_DEBUGGING_OPTS
|
||||
@ -246,6 +244,13 @@ if test "$GNU_CC" -a -n "$MOZ_FORCE_GOLD"; then
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
if test "$GNU_CC"; then
|
||||
if $CC $LDFLAGS -Wl,--version 2>&1 | grep -q "GNU ld"; then
|
||||
LD_IS_BFD=1
|
||||
fi
|
||||
fi
|
||||
|
||||
AC_SUBST([LD_IS_BFD])
|
||||
|
||||
if test "$GNU_CC"; then
|
||||
if test -z "$DEVELOPER_OPTIONS"; then
|
||||
|
@ -88,22 +88,9 @@ GB is likely entering the point of diminishing returns.
|
||||
|
||||
This cause impacts both clobber and incremental builds.
|
||||
|
||||
You are building with pymake
|
||||
============================
|
||||
|
||||
Pymake is slower than GNU make. One reason is Python is generally slower
|
||||
than C. The build system maintainers are consistently looking at
|
||||
optimizing pymake. However, it is death by a thousand cuts.
|
||||
|
||||
This cause impacts both clobber and incremental builds.
|
||||
|
||||
You are building on Windows
|
||||
===========================
|
||||
|
||||
Builds on Windows are slow for a few reasons. First, Windows builds use
|
||||
pymake, not GNU make (because of compatibility issues with GNU make).
|
||||
But, there are other sources of slowness.
|
||||
|
||||
New processes on Windows are about a magnitude slower to spawn than on
|
||||
UNIX-y systems such as Linux. This is because Windows has optimized new
|
||||
threads while the \*NIX platforms typically optimize new processes.
|
||||
|
@ -46,8 +46,7 @@ except KeyError:
|
||||
try:
|
||||
proc = subprocess.Popen([binscope_path, "/target", binary_path,
|
||||
"/output", log_file_path, "/sympath", symbol_path,
|
||||
"/c", "ATLVersionCheck", "/c", "ATLVulnCheck", "/c", "FunctionPointersCheck",
|
||||
"/c", "SharedSectionCheck", "/c", "APTCACheck", "/c", "NXCheck",
|
||||
"/c", "ATLVersionCheck", "/c", "ATLVulnCheck", "/c", "SharedSectionCheck", "/c", "APTCACheck", "/c", "NXCheck",
|
||||
"/c", "GSCheck", "/c", "GSFunctionSafeBuffersCheck", "/c", "GSFriendlyInitCheck",
|
||||
"/c", "CompilerVersionCheck", "/c", "SafeSEHCheck", "/c", "SNCheck",
|
||||
"/c", "DBCheck"], stdout=subprocess.PIPE)
|
||||
|
@ -145,13 +145,6 @@ endif
|
||||
|
||||
ifndef MOZ_OBJDIR
|
||||
MOZ_OBJDIR = obj-$(CONFIG_GUESS)
|
||||
else
|
||||
# On Windows Pymake builds check MOZ_OBJDIR doesn't start with "/"
|
||||
ifneq (,$(findstring mingw,$(CONFIG_GUESS)))
|
||||
ifeq (1_a,$(.PYMAKE)_$(firstword a$(subst /, ,$(MOZ_OBJDIR))))
|
||||
$(error For Windows Pymake builds, MOZ_OBJDIR must be a Windows [and not MSYS] style path.)
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
ifdef MOZ_BUILD_PROJECTS
|
||||
|
@ -194,16 +194,6 @@ endif
|
||||
CONFIG_TOOLS = $(MOZ_BUILD_ROOT)/config
|
||||
AUTOCONF_TOOLS = $(topsrcdir)/build/autoconf
|
||||
|
||||
# Disable MOZ_PSEUDO_DERECURSE when it contains no-pymake and we're running
|
||||
# pymake. This can be removed when no-pymake is removed from the default in
|
||||
# build/autoconf/compiler-opts.m4.
|
||||
ifdef .PYMAKE
|
||||
comma = ,
|
||||
ifneq (,$(filter no-pymake,$(subst $(comma), ,$(MOZ_PSEUDO_DERECURSE))))
|
||||
MOZ_PSEUDO_DERECURSE :=
|
||||
endif
|
||||
endif
|
||||
|
||||
# Disable MOZ_PSEUDO_DERECURSE on PGO builds until it's fixed.
|
||||
ifneq (,$(MOZ_PROFILE_USE)$(MOZ_PROFILE_GENERATE))
|
||||
MOZ_PSEUDO_DERECURSE :=
|
||||
@ -238,10 +228,6 @@ MKDIR ?= mkdir
|
||||
SLEEP ?= sleep
|
||||
TOUCH ?= touch
|
||||
|
||||
ifdef .PYMAKE
|
||||
PYCOMMANDPATH += $(PYTHON_SITE_PACKAGES)
|
||||
endif
|
||||
|
||||
PYTHON_PATH = $(PYTHON) $(topsrcdir)/config/pythonpath.py
|
||||
|
||||
# determine debug-related options
|
||||
@ -720,9 +706,6 @@ endif # NSINSTALL_BIN
|
||||
|
||||
ifeq (,$(CROSS_COMPILE)$(filter-out WINNT, $(OS_ARCH)))
|
||||
INSTALL = $(NSINSTALL) -t
|
||||
ifdef .PYMAKE
|
||||
install_cmd = $(NSINSTALL_NATIVECMD) -t $(1)
|
||||
endif # .PYMAKE
|
||||
|
||||
else
|
||||
|
||||
@ -839,6 +822,7 @@ endif
|
||||
define CHECK_BINARY
|
||||
$(call CHECK_STDCXX,$(1))
|
||||
$(call CHECK_TEXTREL,$(1))
|
||||
$(call LOCAL_CHECKS,$(1))
|
||||
endef
|
||||
|
||||
# autoconf.mk sets OBJ_SUFFIX to an error to avoid use before including
|
||||
|
@ -27,8 +27,4 @@ core_winabspath = $(error core_winabspath is unsupported)
|
||||
#
|
||||
# libs::
|
||||
# $(call py_action,purge_manifests,_build_manifests/purge/foo.manifest)
|
||||
ifdef .PYMAKE
|
||||
py_action = %mozbuild.action.$(1) main $(2)
|
||||
else
|
||||
py_action = $(PYTHON) -m mozbuild.action.$(1) $(2)
|
||||
endif
|
||||
|
@ -35,23 +35,8 @@ endif
|
||||
USE_AUTOTARGETS_MK = 1
|
||||
include $(topsrcdir)/config/makefiles/makeutils.mk
|
||||
|
||||
# Only build with Pymake (not GNU make) on Windows.
|
||||
ifeq ($(HOST_OS_ARCH),WINNT)
|
||||
ifndef L10NBASEDIR
|
||||
ifndef .PYMAKE
|
||||
$(error Pymake is required to build on Windows. Run |./mach build| to \
|
||||
automatically use pymake or invoke pymake directly via \
|
||||
|python build/pymake/make.py|.)
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
ifdef REBUILD_CHECK
|
||||
ifdef .PYMAKE
|
||||
REPORT_BUILD = @%rebuild_check rebuild_check $@ $^
|
||||
else
|
||||
REPORT_BUILD = $(info $(shell $(PYTHON) $(MOZILLA_DIR)/config/rebuild_check.py $@ $^))
|
||||
endif
|
||||
else
|
||||
REPORT_BUILD = $(info $(notdir $@))
|
||||
endif
|
||||
@ -66,15 +51,11 @@ endif
|
||||
# ELOG prints out failed command when building silently (gmake -s). Pymake
|
||||
# prints out failed commands anyway, so ELOG just makes things worse by
|
||||
# forcing shell invocations.
|
||||
ifndef .PYMAKE
|
||||
ifneq (,$(findstring s, $(filter-out --%, $(MAKEFLAGS))))
|
||||
ELOG := $(EXEC) sh $(BUILD_TOOLS)/print-failed-commands.sh
|
||||
else
|
||||
ELOG :=
|
||||
endif # -s
|
||||
else
|
||||
ELOG :=
|
||||
endif # ifndef .PYMAKE
|
||||
|
||||
_VPATH_SRCS = $(abspath $<)
|
||||
|
||||
@ -238,7 +219,7 @@ endif
|
||||
COMPILE_CFLAGS += $(COMPILE_PDB_FLAG)
|
||||
COMPILE_CXXFLAGS += $(COMPILE_PDB_FLAG)
|
||||
|
||||
LINK_PDBFILE = $(basename $(@F)).pdb
|
||||
LINK_PDBFILE ?= $(basename $(@F)).pdb
|
||||
ifdef MOZ_DEBUG
|
||||
CODFILE=$(basename $(@F)).cod
|
||||
endif
|
||||
@ -1142,9 +1123,7 @@ else
|
||||
endif
|
||||
|
||||
# Cancel GNU make built-in implicit rules
|
||||
ifndef .PYMAKE
|
||||
MAKEFLAGS += -r
|
||||
endif
|
||||
|
||||
ifneq (,$(filter WINNT,$(OS_ARCH)))
|
||||
SEP := ;
|
||||
|
@ -22,7 +22,6 @@ tgts =\
|
||||
$(NULL)
|
||||
|
||||
export MAKE
|
||||
export .PYMAKE
|
||||
|
||||
##------------------_##
|
||||
##---] TARGETS [---##
|
||||
|
@ -193,7 +193,7 @@ CSPPolicyURIListener.prototype = {
|
||||
// send the policy we received back to the parent document's CSP
|
||||
// for parsing
|
||||
this._csp.appendPolicy(this._policy, this._docURI,
|
||||
this._reportOnly, this._csp._specCompliant);
|
||||
this._reportOnly, true);
|
||||
}
|
||||
else {
|
||||
// problem fetching policy so fail closed by appending a "block it all"
|
||||
@ -202,7 +202,7 @@ CSPPolicyURIListener.prototype = {
|
||||
this._csp.log(WARN_FLAG, CSPLocalizer.getFormatStr("errorFetchingPolicy",
|
||||
[status]));
|
||||
this._csp.appendPolicy("default-src 'none'", this._docURI,
|
||||
this._reportOnly, this._csp._specCompliant);
|
||||
this._reportOnly, true);
|
||||
}
|
||||
// resume the parent document request
|
||||
this._docRequest.resume();
|
||||
@ -213,49 +213,23 @@ CSPPolicyURIListener.prototype = {
|
||||
|
||||
/**
|
||||
* Class that represents a parsed policy structure.
|
||||
*
|
||||
* @param aSpecCompliant: true: this policy is a CSP 1.0 spec
|
||||
* compliant policy and should be parsed as such.
|
||||
* false or undefined: this is a policy using
|
||||
* our original implementation's CSP syntax.
|
||||
*/
|
||||
this.CSPRep = function CSPRep(aSpecCompliant) {
|
||||
this.CSPRep = function CSPRep() {
|
||||
// this gets set to true when the policy is done parsing, or when a
|
||||
// URI-borne policy has finished loading.
|
||||
this._isInitialized = false;
|
||||
|
||||
this._allowEval = false;
|
||||
this._allowInlineScripts = false;
|
||||
this._allowInlineStyles = false;
|
||||
this._reportOnlyMode = false;
|
||||
|
||||
// don't auto-populate _directives, so it is easier to find bugs
|
||||
this._directives = {};
|
||||
|
||||
// Is this a 1.0 spec compliant CSPRep ?
|
||||
// Default to false if not specified.
|
||||
this._specCompliant = (aSpecCompliant !== undefined) ? aSpecCompliant : false;
|
||||
|
||||
// Only CSP 1.0 spec compliant policies block inline styles by default.
|
||||
this._allowInlineStyles = !aSpecCompliant;
|
||||
}
|
||||
|
||||
// Source directives for our original CSP implementation.
|
||||
// These can be removed when the original implementation is deprecated.
|
||||
CSPRep.SRC_DIRECTIVES_OLD = {
|
||||
DEFAULT_SRC: "default-src",
|
||||
SCRIPT_SRC: "script-src",
|
||||
STYLE_SRC: "style-src",
|
||||
MEDIA_SRC: "media-src",
|
||||
IMG_SRC: "img-src",
|
||||
OBJECT_SRC: "object-src",
|
||||
FRAME_SRC: "frame-src",
|
||||
FRAME_ANCESTORS: "frame-ancestors",
|
||||
FONT_SRC: "font-src",
|
||||
XHR_SRC: "xhr-src"
|
||||
};
|
||||
|
||||
// Source directives for our CSP 1.0 spec compliant implementation.
|
||||
CSPRep.SRC_DIRECTIVES_NEW = {
|
||||
CSPRep.SRC_DIRECTIVES = {
|
||||
DEFAULT_SRC: "default-src",
|
||||
SCRIPT_SRC: "script-src",
|
||||
STYLE_SRC: "style-src",
|
||||
@ -273,268 +247,6 @@ CSPRep.URI_DIRECTIVES = {
|
||||
POLICY_URI: "policy-uri" /* single URI */
|
||||
};
|
||||
|
||||
// These directives no longer exist in CSP 1.0 and
|
||||
// later and will eventually be removed when we no longer
|
||||
// support our original implementation's syntax.
|
||||
CSPRep.OPTIONS_DIRECTIVE = "options";
|
||||
CSPRep.ALLOW_DIRECTIVE = "allow";
|
||||
|
||||
/**
|
||||
* Factory to create a new CSPRep, parsed from a string.
|
||||
*
|
||||
* @param aStr
|
||||
* string rep of a CSP
|
||||
* @param self (optional)
|
||||
* URI representing the "self" source
|
||||
* @param reportOnly (optional)
|
||||
* whether or not this CSP is report-only (defaults to false)
|
||||
* @param docRequest (optional)
|
||||
* request for the parent document which may need to be suspended
|
||||
* while the policy-uri is asynchronously fetched
|
||||
* @param csp (optional)
|
||||
* the CSP object to update once the policy has been fetched
|
||||
* @param enforceSelfChecks (optional)
|
||||
* if present, and "true", will check to be sure "self" has the
|
||||
* appropriate values to inherit when they are omitted from the source.
|
||||
* @returns
|
||||
* an instance of CSPRep
|
||||
*/
|
||||
CSPRep.fromString = function(aStr, self, reportOnly, docRequest, csp,
|
||||
enforceSelfChecks) {
|
||||
var SD = CSPRep.SRC_DIRECTIVES_OLD;
|
||||
var UD = CSPRep.URI_DIRECTIVES;
|
||||
var aCSPR = new CSPRep();
|
||||
aCSPR._originalText = aStr;
|
||||
aCSPR._innerWindowID = innerWindowFromRequest(docRequest);
|
||||
if (typeof reportOnly === 'undefined') reportOnly = false;
|
||||
aCSPR._reportOnlyMode = reportOnly;
|
||||
|
||||
var selfUri = null;
|
||||
if (self instanceof Ci.nsIURI) {
|
||||
selfUri = self.cloneIgnoringRef();
|
||||
// clean userpass out of the URI (not used for CSP origin checking, but
|
||||
// shows up in prePath).
|
||||
try {
|
||||
// GetUserPass throws for some protocols without userPass
|
||||
selfUri.userPass = '';
|
||||
} catch (ex) {}
|
||||
}
|
||||
|
||||
var dirs = aStr.split(";");
|
||||
|
||||
directive:
|
||||
for each(var dir in dirs) {
|
||||
dir = dir.trim();
|
||||
if (dir.length < 1) continue;
|
||||
|
||||
var dirname = dir.split(/\s+/)[0].toLowerCase();
|
||||
var dirvalue = dir.substring(dirname.length).trim();
|
||||
|
||||
if (aCSPR._directives.hasOwnProperty(dirname)) {
|
||||
// Check for (most) duplicate directives
|
||||
cspError(aCSPR, CSPLocalizer.getFormatStr("duplicateDirective",
|
||||
[dirname]));
|
||||
CSPdebug("Skipping duplicate directive: \"" + dir + "\"");
|
||||
continue directive;
|
||||
}
|
||||
|
||||
// OPTIONS DIRECTIVE ////////////////////////////////////////////////
|
||||
if (dirname === CSPRep.OPTIONS_DIRECTIVE) {
|
||||
if (aCSPR._allowInlineScripts || aCSPR._allowEval) {
|
||||
// Check for duplicate options directives
|
||||
cspError(aCSPR, CSPLocalizer.getFormatStr("duplicateDirective",
|
||||
[dirname]));
|
||||
CSPdebug("Skipping duplicate directive: \"" + dir + "\"");
|
||||
continue directive;
|
||||
}
|
||||
|
||||
// grab value tokens and interpret them
|
||||
var options = dirvalue.split(/\s+/);
|
||||
for each (var opt in options) {
|
||||
if (opt === "inline-script")
|
||||
aCSPR._allowInlineScripts = true;
|
||||
else if (opt === "eval-script")
|
||||
aCSPR._allowEval = true;
|
||||
else
|
||||
cspWarn(aCSPR, CSPLocalizer.getFormatStr("ignoringUnknownOption",
|
||||
[opt]));
|
||||
}
|
||||
continue directive;
|
||||
}
|
||||
|
||||
// ALLOW DIRECTIVE //////////////////////////////////////////////////
|
||||
// parse "allow" as equivalent to "default-src", at least until the spec
|
||||
// stabilizes, at which time we can stop parsing "allow"
|
||||
if (dirname === CSPRep.ALLOW_DIRECTIVE) {
|
||||
cspWarn(aCSPR, CSPLocalizer.getStr("allowDirectiveIsDeprecated"));
|
||||
if (aCSPR._directives.hasOwnProperty(SD.DEFAULT_SRC)) {
|
||||
// Check for duplicate default-src and allow directives
|
||||
cspError(aCSPR, CSPLocalizer.getFormatStr("duplicateDirective",
|
||||
[dirname]));
|
||||
CSPdebug("Skipping duplicate directive: \"" + dir + "\"");
|
||||
continue directive;
|
||||
}
|
||||
var dv = CSPSourceList.fromString(dirvalue, aCSPR, selfUri,
|
||||
enforceSelfChecks);
|
||||
if (dv) {
|
||||
aCSPR._directives[SD.DEFAULT_SRC] = dv;
|
||||
continue directive;
|
||||
}
|
||||
}
|
||||
|
||||
// SOURCE DIRECTIVES ////////////////////////////////////////////////
|
||||
for each(var sdi in SD) {
|
||||
if (dirname === sdi) {
|
||||
// process dirs, and enforce that 'self' is defined.
|
||||
var dv = CSPSourceList.fromString(dirvalue, aCSPR, selfUri,
|
||||
enforceSelfChecks);
|
||||
if (dv) {
|
||||
aCSPR._directives[sdi] = dv;
|
||||
continue directive;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// REPORT URI ///////////////////////////////////////////////////////
|
||||
if (dirname === UD.REPORT_URI) {
|
||||
// might be space-separated list of URIs
|
||||
var uriStrings = dirvalue.split(/\s+/);
|
||||
var okUriStrings = [];
|
||||
|
||||
for (let i in uriStrings) {
|
||||
var uri = null;
|
||||
try {
|
||||
// Relative URIs are okay, but to ensure we send the reports to the
|
||||
// right spot, the relative URIs are expanded here during parsing.
|
||||
// The resulting CSPRep instance will have only absolute URIs.
|
||||
uri = gIoService.newURI(uriStrings[i],null,selfUri);
|
||||
|
||||
// if there's no host, this will throw NS_ERROR_FAILURE, causing a
|
||||
// parse failure.
|
||||
uri.host;
|
||||
|
||||
// warn about, but do not prohibit non-http and non-https schemes for
|
||||
// reporting URIs. The spec allows unrestricted URIs resolved
|
||||
// relative to "self", but we should let devs know if the scheme is
|
||||
// abnormal and may fail a POST.
|
||||
if (!uri.schemeIs("http") && !uri.schemeIs("https")) {
|
||||
cspWarn(aCSPR, CSPLocalizer.getFormatStr("reportURInotHttpsOrHttp2",
|
||||
[uri.asciiSpec]));
|
||||
}
|
||||
} catch(e) {
|
||||
switch (e.result) {
|
||||
case Components.results.NS_ERROR_INSUFFICIENT_DOMAIN_LEVELS:
|
||||
case Components.results.NS_ERROR_HOST_IS_IP_ADDRESS:
|
||||
if (uri.host !== selfUri.host) {
|
||||
cspWarn(aCSPR,
|
||||
CSPLocalizer.getFormatStr("pageCannotSendReportsTo",
|
||||
[selfUri.host, uri.host]));
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
cspWarn(aCSPR, CSPLocalizer.getFormatStr("couldNotParseReportURI",
|
||||
[uriStrings[i]]));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
// all verification passed
|
||||
okUriStrings.push(uri.asciiSpec);
|
||||
}
|
||||
aCSPR._directives[UD.REPORT_URI] = okUriStrings.join(' ');
|
||||
continue directive;
|
||||
}
|
||||
|
||||
// POLICY URI //////////////////////////////////////////////////////////
|
||||
if (dirname === UD.POLICY_URI) {
|
||||
// POLICY_URI can only be alone
|
||||
if (aCSPR._directives.length > 0 || dirs.length > 1) {
|
||||
cspError(aCSPR, CSPLocalizer.getStr("policyURINotAlone"));
|
||||
return CSPRep.fromString("default-src 'none'", null, reportOnly);
|
||||
}
|
||||
// if we were called without a reference to the parent document request
|
||||
// we won't be able to suspend it while we fetch the policy -> fail closed
|
||||
if (!docRequest || !csp) {
|
||||
cspError(aCSPR, CSPLocalizer.getStr("noParentRequest"));
|
||||
return CSPRep.fromString("default-src 'none'", null, reportOnly);
|
||||
}
|
||||
|
||||
var uri = '';
|
||||
try {
|
||||
uri = gIoService.newURI(dirvalue, null, selfUri);
|
||||
} catch(e) {
|
||||
cspError(aCSPR, CSPLocalizer.getFormatStr("policyURIParseError",
|
||||
[dirvalue]));
|
||||
return CSPRep.fromString("default-src 'none'", null, reportOnly);
|
||||
}
|
||||
|
||||
// Verify that policy URI comes from the same origin
|
||||
if (selfUri) {
|
||||
if (selfUri.host !== uri.host) {
|
||||
cspError(aCSPR, CSPLocalizer.getFormatStr("nonMatchingHost",
|
||||
[uri.host]));
|
||||
return CSPRep.fromString("default-src 'none'", null, reportOnly);
|
||||
}
|
||||
if (selfUri.port !== uri.port) {
|
||||
cspError(aCSPR, CSPLocalizer.getFormatStr("nonMatchingPort",
|
||||
[uri.port.toString()]));
|
||||
return CSPRep.fromString("default-src 'none'", null, reportOnly);
|
||||
}
|
||||
if (selfUri.scheme !== uri.scheme) {
|
||||
cspError(aCSPR, CSPLocalizer.getFormatStr("nonMatchingScheme",
|
||||
[uri.scheme]));
|
||||
return CSPRep.fromString("default-src 'none'", null, reportOnly);
|
||||
}
|
||||
}
|
||||
|
||||
// suspend the parent document request while we fetch the policy-uri
|
||||
try {
|
||||
docRequest.suspend();
|
||||
var chan = gIoService.newChannel(uri.asciiSpec, null, null);
|
||||
// make request anonymous (no cookies, etc.) so the request for the
|
||||
// policy-uri can't be abused for CSRF
|
||||
chan.loadFlags |= Ci.nsIChannel.LOAD_ANONYMOUS;
|
||||
chan.loadGroup = docRequest.loadGroup;
|
||||
chan.asyncOpen(new CSPPolicyURIListener(uri, docRequest, csp, reportOnly), null);
|
||||
}
|
||||
catch (e) {
|
||||
// resume the document request and apply most restrictive policy
|
||||
docRequest.resume();
|
||||
cspError(aCSPR, CSPLocalizer.getFormatStr("errorFetchingPolicy",
|
||||
[e.toString()]));
|
||||
return CSPRep.fromString("default-src 'none'", null, reportOnly);
|
||||
}
|
||||
|
||||
// return a fully-open policy to be used until the contents of the
|
||||
// policy-uri come back.
|
||||
return CSPRep.fromString("default-src *", null, reportOnly);
|
||||
}
|
||||
|
||||
// UNIDENTIFIED DIRECTIVE /////////////////////////////////////////////
|
||||
cspWarn(aCSPR, CSPLocalizer.getFormatStr("couldNotProcessUnknownDirective",
|
||||
[dirname]));
|
||||
|
||||
} // end directive: loop
|
||||
|
||||
// the X-Content-Security-Policy syntax requires an allow or default-src
|
||||
// directive to be present.
|
||||
if (!aCSPR._directives[SD.DEFAULT_SRC]) {
|
||||
cspWarn(aCSPR, CSPLocalizer.getStr("allowOrDefaultSrcRequired"));
|
||||
return CSPRep.fromString("default-src 'none'", null, reportOnly);
|
||||
}
|
||||
|
||||
// If this is a Report-Only header and report-uri is not in the directive
|
||||
// list, tell developer either specify report-uri directive or use
|
||||
// a non-Report-Only CSP header.
|
||||
if (aCSPR._reportOnlyMode && !aCSPR._directives.hasOwnProperty(UD.REPORT_URI)) {
|
||||
cspWarn(aCSPR, CSPLocalizer.getFormatStr("reportURInotInReportOnlyHeader",
|
||||
[selfUri ? selfUri.prePath : "undefined"]))
|
||||
}
|
||||
|
||||
return aCSPR;
|
||||
};
|
||||
|
||||
/**
|
||||
* Factory to create a new CSPRep, parsed from a string, compliant
|
||||
* with the CSP 1.0 spec.
|
||||
@ -556,13 +268,11 @@ CSPRep.fromString = function(aStr, self, reportOnly, docRequest, csp,
|
||||
* @returns
|
||||
* an instance of CSPRep
|
||||
*/
|
||||
// When we deprecate our original CSP implementation, we rename this to
|
||||
// CSPRep.fromString and remove the existing CSPRep.fromString above.
|
||||
CSPRep.fromStringSpecCompliant = function(aStr, self, reportOnly, docRequest, csp,
|
||||
enforceSelfChecks) {
|
||||
var SD = CSPRep.SRC_DIRECTIVES_NEW;
|
||||
CSPRep.fromString = function(aStr, self, reportOnly, docRequest, csp,
|
||||
enforceSelfChecks) {
|
||||
var SD = CSPRep.SRC_DIRECTIVES;
|
||||
var UD = CSPRep.URI_DIRECTIVES;
|
||||
var aCSPR = new CSPRep(true);
|
||||
var aCSPR = new CSPRep();
|
||||
aCSPR._originalText = aStr;
|
||||
aCSPR._innerWindowID = innerWindowFromRequest(docRequest);
|
||||
if (typeof reportOnly === 'undefined') reportOnly = false;
|
||||
@ -587,7 +297,10 @@ CSPRep.fromStringSpecCompliant = function(aStr, self, reportOnly, docRequest, cs
|
||||
|
||||
var dirname = dir.split(/\s+/)[0].toLowerCase();
|
||||
var dirvalue = dir.substring(dirname.length).trim();
|
||||
dirs[dirname] = dirvalue;
|
||||
// skip duplicates
|
||||
if (!dirs.hasOwnProperty(dirname)) {
|
||||
dirs[dirname] = dirvalue;
|
||||
}
|
||||
}
|
||||
|
||||
// Spec compliant policies have different default behavior for inline
|
||||
@ -712,13 +425,13 @@ CSPRep.fromStringSpecCompliant = function(aStr, self, reportOnly, docRequest, cs
|
||||
// POLICY_URI can only be alone
|
||||
if (aCSPR._directives.length > 0 || dirs.length > 1) {
|
||||
cspError(aCSPR, CSPLocalizer.getStr("policyURINotAlone"));
|
||||
return CSPRep.fromStringSpecCompliant("default-src 'none'", null, reportOnly);
|
||||
return CSPRep.fromString("default-src 'none'", null, reportOnly);
|
||||
}
|
||||
// if we were called without a reference to the parent document request
|
||||
// we won't be able to suspend it while we fetch the policy -> fail closed
|
||||
if (!docRequest || !csp) {
|
||||
cspError(aCSPR, CSPLocalizer.getStr("noParentRequest"));
|
||||
return CSPRep.fromStringSpecCompliant("default-src 'none'", null, reportOnly);
|
||||
return CSPRep.fromString("default-src 'none'", null, reportOnly);
|
||||
}
|
||||
|
||||
var uri = '';
|
||||
@ -726,22 +439,22 @@ CSPRep.fromStringSpecCompliant = function(aStr, self, reportOnly, docRequest, cs
|
||||
uri = gIoService.newURI(dirvalue, null, selfUri);
|
||||
} catch(e) {
|
||||
cspError(aCSPR, CSPLocalizer.getFormatStr("policyURIParseError", [dirvalue]));
|
||||
return CSPRep.fromStringSpecCompliant("default-src 'none'", null, reportOnly);
|
||||
return CSPRep.fromString("default-src 'none'", null, reportOnly);
|
||||
}
|
||||
|
||||
// Verify that policy URI comes from the same origin
|
||||
if (selfUri) {
|
||||
if (selfUri.host !== uri.host){
|
||||
cspError(aCSPR, CSPLocalizer.getFormatStr("nonMatchingHost", [uri.host]));
|
||||
return CSPRep.fromStringSpecCompliant("default-src 'none'", null, reportOnly);
|
||||
return CSPRep.fromString("default-src 'none'", null, reportOnly);
|
||||
}
|
||||
if (selfUri.port !== uri.port){
|
||||
cspError(aCSPR, CSPLocalizer.getFormatStr("nonMatchingPort", [uri.port.toString()]));
|
||||
return CSPRep.fromStringSpecCompliant("default-src 'none'", null, reportOnly);
|
||||
return CSPRep.fromString("default-src 'none'", null, reportOnly);
|
||||
}
|
||||
if (selfUri.scheme !== uri.scheme){
|
||||
cspError(aCSPR, CSPLocalizer.getFormatStr("nonMatchingScheme", [uri.scheme]));
|
||||
return CSPRep.fromStringSpecCompliant("default-src 'none'", null, reportOnly);
|
||||
return CSPRep.fromString("default-src 'none'", null, reportOnly);
|
||||
}
|
||||
}
|
||||
|
||||
@ -759,12 +472,12 @@ CSPRep.fromStringSpecCompliant = function(aStr, self, reportOnly, docRequest, cs
|
||||
// resume the document request and apply most restrictive policy
|
||||
docRequest.resume();
|
||||
cspError(aCSPR, CSPLocalizer.getFormatStr("errorFetchingPolicy", [e.toString()]));
|
||||
return CSPRep.fromStringSpecCompliant("default-src 'none'", null, reportOnly);
|
||||
return CSPRep.fromString("default-src 'none'", null, reportOnly);
|
||||
}
|
||||
|
||||
// return a fully-open policy to be used until the contents of the
|
||||
// policy-uri come back
|
||||
return CSPRep.fromStringSpecCompliant("default-src *", null, reportOnly);
|
||||
return CSPRep.fromString("default-src *", null, reportOnly);
|
||||
}
|
||||
|
||||
// UNIDENTIFIED DIRECTIVE /////////////////////////////////////////////
|
||||
@ -819,10 +532,6 @@ CSPRep.prototype = {
|
||||
function csp_toString() {
|
||||
var dirs = [];
|
||||
|
||||
if (!this._specCompliant && (this._allowEval || this._allowInlineScripts)) {
|
||||
dirs.push("options" + (this._allowEval ? " eval-script" : "")
|
||||
+ (this._allowInlineScripts ? " inline-script" : ""));
|
||||
}
|
||||
for (var i in this._directives) {
|
||||
if (this._directives[i]) {
|
||||
dirs.push(i + " " + this._directives[i].toString());
|
||||
@ -867,7 +576,7 @@ CSPRep.prototype = {
|
||||
return true;
|
||||
|
||||
// make sure the right directive set is used
|
||||
let DIRS = this._specCompliant ? CSPRep.SRC_DIRECTIVES_NEW : CSPRep.SRC_DIRECTIVES_OLD;
|
||||
let DIRS = CSPRep.SRC_DIRECTIVES;
|
||||
|
||||
let directiveInPolicy = false;
|
||||
for (var i in DIRS) {
|
||||
@ -904,8 +613,8 @@ CSPRep.prototype = {
|
||||
}
|
||||
|
||||
// no relevant directives present -- this means for CSP 1.0 that the load
|
||||
// should be permitted (and for the old CSP, to block it).
|
||||
return this._specCompliant;
|
||||
// should be permitted.
|
||||
return true;
|
||||
},
|
||||
|
||||
/**
|
||||
@ -1541,7 +1250,11 @@ CSPSource.prototype = {
|
||||
s = s + this.scheme + "://";
|
||||
if (this._host)
|
||||
s = s + this._host;
|
||||
if (this.port)
|
||||
|
||||
// CSP 1.0 4.11 says the report should use URI-reference from RFC 3986,
|
||||
// 3.2.3 and indicates that the default port should be omitted.
|
||||
// Non-default ports are included.
|
||||
if (this.port && gIoService.getProtocolHandler(this.scheme).defaultPort != this.port)
|
||||
s = s + ":" + this.port;
|
||||
return s;
|
||||
},
|
||||
|
@ -24,11 +24,6 @@ const Cu = Components.utils;
|
||||
|
||||
const CSP_VIOLATION_TOPIC = "csp-on-violate-policy";
|
||||
|
||||
// Needed to support CSP 1.0 spec and our original CSP implementation - should
|
||||
// be removed when our original implementation is deprecated.
|
||||
const CSP_TYPE_XMLHTTPREQUEST_SPEC_COMPLIANT = "csp_type_xmlhttprequest_spec_compliant";
|
||||
const CSP_TYPE_WEBSOCKET_SPEC_COMPLIANT = "csp_type_websocket_spec_compliant";
|
||||
|
||||
const WARN_FLAG = Ci.nsIScriptError.warningFlag;
|
||||
const ERROR_FLAG = Ci.nsIScriptError.ERROR_FLAG;
|
||||
|
||||
@ -71,14 +66,13 @@ function ContentSecurityPolicy() {
|
||||
{
|
||||
let cp = Ci.nsIContentPolicy;
|
||||
let csp = ContentSecurityPolicy;
|
||||
let cspr_sd_old = CSPRep.SRC_DIRECTIVES_OLD;
|
||||
let cspr_sd_new = CSPRep.SRC_DIRECTIVES_NEW;
|
||||
let cspr_sd = CSPRep.SRC_DIRECTIVES;
|
||||
|
||||
csp._MAPPINGS=[];
|
||||
|
||||
/* default, catch-all case */
|
||||
// This is the same in old and new CSP so use the new mapping.
|
||||
csp._MAPPINGS[cp.TYPE_OTHER] = cspr_sd_new.DEFAULT_SRC;
|
||||
csp._MAPPINGS[cp.TYPE_OTHER] = cspr_sd.DEFAULT_SRC;
|
||||
|
||||
/* self */
|
||||
csp._MAPPINGS[cp.TYPE_DOCUMENT] = null;
|
||||
@ -87,44 +81,26 @@ function ContentSecurityPolicy() {
|
||||
csp._MAPPINGS[cp.TYPE_REFRESH] = null;
|
||||
|
||||
/* categorized content types */
|
||||
// These are the same in old and new CSP's so just use the new mappings.
|
||||
csp._MAPPINGS[cp.TYPE_SCRIPT] = cspr_sd_new.SCRIPT_SRC;
|
||||
csp._MAPPINGS[cp.TYPE_IMAGE] = cspr_sd_new.IMG_SRC;
|
||||
csp._MAPPINGS[cp.TYPE_STYLESHEET] = cspr_sd_new.STYLE_SRC;
|
||||
csp._MAPPINGS[cp.TYPE_OBJECT] = cspr_sd_new.OBJECT_SRC;
|
||||
csp._MAPPINGS[cp.TYPE_OBJECT_SUBREQUEST] = cspr_sd_new.OBJECT_SRC;
|
||||
csp._MAPPINGS[cp.TYPE_SUBDOCUMENT] = cspr_sd_new.FRAME_SRC;
|
||||
csp._MAPPINGS[cp.TYPE_MEDIA] = cspr_sd_new.MEDIA_SRC;
|
||||
csp._MAPPINGS[cp.TYPE_FONT] = cspr_sd_new.FONT_SRC;
|
||||
csp._MAPPINGS[cp.TYPE_XSLT] = cspr_sd_new.SCRIPT_SRC;
|
||||
csp._MAPPINGS[cp.TYPE_BEACON] = cspr_sd_new.CONNECT_SRC;
|
||||
|
||||
/* Our original CSP implementation's mappings for XHR and websocket
|
||||
* These should be changed to be = cspr_sd.CONNECT_SRC when we remove
|
||||
* the original implementation - NOTE: order in this array is important !!!
|
||||
*/
|
||||
csp._MAPPINGS[cp.TYPE_XMLHTTPREQUEST] = cspr_sd_old.XHR_SRC;
|
||||
csp._MAPPINGS[cp.TYPE_WEBSOCKET] = cspr_sd_old.XHR_SRC;
|
||||
csp._MAPPINGS[cp.TYPE_SCRIPT] = cspr_sd.SCRIPT_SRC;
|
||||
csp._MAPPINGS[cp.TYPE_IMAGE] = cspr_sd.IMG_SRC;
|
||||
csp._MAPPINGS[cp.TYPE_STYLESHEET] = cspr_sd.STYLE_SRC;
|
||||
csp._MAPPINGS[cp.TYPE_OBJECT] = cspr_sd.OBJECT_SRC;
|
||||
csp._MAPPINGS[cp.TYPE_OBJECT_SUBREQUEST] = cspr_sd.OBJECT_SRC;
|
||||
csp._MAPPINGS[cp.TYPE_SUBDOCUMENT] = cspr_sd.FRAME_SRC;
|
||||
csp._MAPPINGS[cp.TYPE_MEDIA] = cspr_sd.MEDIA_SRC;
|
||||
csp._MAPPINGS[cp.TYPE_FONT] = cspr_sd.FONT_SRC;
|
||||
csp._MAPPINGS[cp.TYPE_XSLT] = cspr_sd.SCRIPT_SRC;
|
||||
csp._MAPPINGS[cp.TYPE_BEACON] = cspr_sd.CONNECT_SRC;
|
||||
csp._MAPPINGS[cp.TYPE_XMLHTTPREQUEST] = cspr_sd.CONNECT_SRC;
|
||||
csp._MAPPINGS[cp.TYPE_WEBSOCKET] = cspr_sd.CONNECT_SRC;
|
||||
|
||||
/* CSP cannot block CSP reports */
|
||||
csp._MAPPINGS[cp.TYPE_CSP_REPORT] = null;
|
||||
|
||||
/* These must go through the catch-all */
|
||||
csp._MAPPINGS[cp.TYPE_XBL] = cspr_sd_new.DEFAULT_SRC;
|
||||
csp._MAPPINGS[cp.TYPE_PING] = cspr_sd_new.DEFAULT_SRC;
|
||||
csp._MAPPINGS[cp.TYPE_DTD] = cspr_sd_new.DEFAULT_SRC;
|
||||
|
||||
/* CSP 1.0 spec compliant mappings for XHR and websocket */
|
||||
// The directive name for XHR, websocket, and EventSource is different
|
||||
// in the 1.0 spec than in our original implementation, these mappings
|
||||
// address this. These won't be needed when we deprecate our original
|
||||
// implementation.
|
||||
csp._MAPPINGS[CSP_TYPE_XMLHTTPREQUEST_SPEC_COMPLIANT] = cspr_sd_new.CONNECT_SRC;
|
||||
csp._MAPPINGS[CSP_TYPE_WEBSOCKET_SPEC_COMPLIANT] = cspr_sd_new.CONNECT_SRC;
|
||||
// TODO : EventSource will be here and also will use connect-src
|
||||
// after we fix Bug 802872 - CSP should restrict EventSource using the connect-src
|
||||
// directive. For background see Bug 667490 - EventSource should use the same
|
||||
// nsIContentPolicy type as XHR (which is fixed)
|
||||
csp._MAPPINGS[cp.TYPE_XBL] = cspr_sd.DEFAULT_SRC;
|
||||
csp._MAPPINGS[cp.TYPE_PING] = cspr_sd.DEFAULT_SRC;
|
||||
csp._MAPPINGS[cp.TYPE_DTD] = cspr_sd.DEFAULT_SRC;
|
||||
}
|
||||
|
||||
ContentSecurityPolicy.prototype = {
|
||||
@ -157,7 +133,7 @@ ContentSecurityPolicy.prototype = {
|
||||
|
||||
_buildViolatedDirectiveString:
|
||||
function(aDirectiveName, aPolicy) {
|
||||
var SD = CSPRep.SRC_DIRECTIVES_NEW;
|
||||
var SD = CSPRep.SRC_DIRECTIVES;
|
||||
var cspContext = (SD[aDirectiveName] in aPolicy._directives) ? SD[aDirectiveName] : SD.DEFAULT_SRC;
|
||||
var directive = aPolicy._directives[cspContext];
|
||||
return cspContext + ' ' + directive.toString();
|
||||
@ -410,8 +386,7 @@ ContentSecurityPolicy.prototype = {
|
||||
*/
|
||||
appendPolicy:
|
||||
function csp_appendPolicy(aPolicy, selfURI, aReportOnly, aSpecCompliant) {
|
||||
return this._appendPolicyInternal(aPolicy, selfURI, aReportOnly,
|
||||
aSpecCompliant, true);
|
||||
return this._appendPolicyInternal(aPolicy, selfURI, aReportOnly, true);
|
||||
},
|
||||
|
||||
/**
|
||||
@ -420,12 +395,10 @@ ContentSecurityPolicy.prototype = {
|
||||
* @returns the count of policies.
|
||||
*/
|
||||
_appendPolicyInternal:
|
||||
function csp_appendPolicy(aPolicy, selfURI, aReportOnly, aSpecCompliant,
|
||||
aEnforceSelfChecks) {
|
||||
function csp_appendPolicy(aPolicy, selfURI, aReportOnly, aEnforceSelfChecks) {
|
||||
#ifndef MOZ_B2G
|
||||
CSPdebug("APPENDING POLICY: " + aPolicy);
|
||||
CSPdebug(" SELF: " + (selfURI ? selfURI.asciiSpec : " null"));
|
||||
CSPdebug("CSP 1.0 COMPLIANT : " + aSpecCompliant);
|
||||
#endif
|
||||
|
||||
// For nested schemes such as view-source: make sure we are taking the
|
||||
@ -446,26 +419,9 @@ ContentSecurityPolicy.prototype = {
|
||||
// Note that we pass the full URI since when it's parsed as 'self' to construct a
|
||||
// CSPSource only the scheme, host, and port are kept.
|
||||
|
||||
// If we want to be CSP 1.0 spec compliant, use the new parser.
|
||||
// The old one will be deprecated in the future and will be
|
||||
// removed at that time.
|
||||
if (aSpecCompliant) {
|
||||
newpolicy = CSPRep.fromStringSpecCompliant(aPolicy,
|
||||
selfURI,
|
||||
aReportOnly,
|
||||
this._weakDocRequest.get(),
|
||||
this,
|
||||
aEnforceSelfChecks);
|
||||
} else {
|
||||
newpolicy = CSPRep.fromString(aPolicy,
|
||||
selfURI,
|
||||
aReportOnly,
|
||||
this._weakDocRequest.get(),
|
||||
this,
|
||||
aEnforceSelfChecks);
|
||||
}
|
||||
|
||||
newpolicy._specCompliant = !!aSpecCompliant;
|
||||
newpolicy = CSPRep.fromString(aPolicy, selfURI, aReportOnly,
|
||||
this._weakDocRequest.get(),
|
||||
this, aEnforceSelfChecks);
|
||||
newpolicy._isInitialized = true;
|
||||
this._policies.push(newpolicy);
|
||||
this._cache.clear(); // reset cache since effective policy changes
|
||||
@ -711,7 +667,7 @@ ContentSecurityPolicy.prototype = {
|
||||
// scan the discovered ancestors
|
||||
// frame-ancestors is the same in both old and new source directives,
|
||||
// so don't need to differentiate here.
|
||||
let cspContext = CSPRep.SRC_DIRECTIVES_NEW.FRAME_ANCESTORS;
|
||||
let cspContext = CSPRep.SRC_DIRECTIVES.FRAME_ANCESTORS;
|
||||
for (let i in ancestors) {
|
||||
let ancestor = ancestors[i];
|
||||
if (!policy.permits(ancestor, cspContext)) {
|
||||
@ -806,22 +762,11 @@ ContentSecurityPolicy.prototype = {
|
||||
for (let policyIndex=0; policyIndex < this._policies.length; policyIndex++) {
|
||||
let policy = this._policies[policyIndex];
|
||||
|
||||
cspContext = ContentSecurityPolicy._MAPPINGS[aContentType];
|
||||
|
||||
#ifndef MOZ_B2G
|
||||
CSPdebug("policy is " + (policy._specCompliant ?
|
||||
"1.0 compliant" : "pre-1.0"));
|
||||
CSPdebug("policy is " + (policy._reportOnlyMode ?
|
||||
"report-only" : "blocking"));
|
||||
#endif
|
||||
|
||||
if (aContentType == cp.TYPE_XMLHTTPREQUEST && this._policies[policyIndex]._specCompliant) {
|
||||
cspContext = ContentSecurityPolicy._MAPPINGS[CSP_TYPE_XMLHTTPREQUEST_SPEC_COMPLIANT];
|
||||
} else if (aContentType == cp.TYPE_WEBSOCKET && this._policies[policyIndex]._specCompliant) {
|
||||
cspContext = ContentSecurityPolicy._MAPPINGS[CSP_TYPE_WEBSOCKET_SPEC_COMPLIANT];
|
||||
} else {
|
||||
cspContext = ContentSecurityPolicy._MAPPINGS[aContentType];
|
||||
}
|
||||
|
||||
#ifndef MOZ_B2G
|
||||
CSPdebug("shouldLoad cspContext = " + cspContext);
|
||||
#endif
|
||||
|
||||
@ -979,11 +924,9 @@ ContentSecurityPolicy.prototype = {
|
||||
for (let pCount = aStream.read32(); pCount > 0; pCount--) {
|
||||
let polStr = aStream.readString();
|
||||
let reportOnly = aStream.readBoolean();
|
||||
let specCompliant = aStream.readBoolean();
|
||||
// don't need self info because when the policy is turned back into a
|
||||
// string, 'self' is replaced with the explicit source expression.
|
||||
this._appendPolicyInternal(polStr, null, reportOnly, specCompliant,
|
||||
false);
|
||||
this._appendPolicyInternal(polStr, null, reportOnly, false);
|
||||
}
|
||||
|
||||
// NOTE: the document instance that's deserializing this object (via its
|
||||
@ -1010,7 +953,6 @@ ContentSecurityPolicy.prototype = {
|
||||
for each (var policy in this._policies) {
|
||||
aStream.writeWStringZ(policy.toString());
|
||||
aStream.writeBoolean(policy._reportOnlyMode);
|
||||
aStream.writeBoolean(policy._specCompliant);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
@ -821,6 +821,7 @@ class CSPReportSenderRunnable MOZ_FINAL : public nsRunnable
|
||||
CSPReportSenderRunnable(nsISupports* aBlockedContentSource,
|
||||
nsIURI* aOriginalURI,
|
||||
uint32_t aViolatedPolicyIndex,
|
||||
bool aReportOnlyFlag,
|
||||
const nsAString& aViolatedDirective,
|
||||
const nsAString& aObserverSubject,
|
||||
const nsAString& aSourceFile,
|
||||
@ -831,6 +832,7 @@ class CSPReportSenderRunnable MOZ_FINAL : public nsRunnable
|
||||
: mBlockedContentSource(aBlockedContentSource)
|
||||
, mOriginalURI(aOriginalURI)
|
||||
, mViolatedPolicyIndex(aViolatedPolicyIndex)
|
||||
, mReportOnlyFlag(aReportOnlyFlag)
|
||||
, mViolatedDirective(aViolatedDirective)
|
||||
, mSourceFile(aSourceFile)
|
||||
, mScriptSample(aScriptSample)
|
||||
@ -887,7 +889,9 @@ class CSPReportSenderRunnable MOZ_FINAL : public nsRunnable
|
||||
nsString blockedDataChar16 = NS_ConvertUTF8toUTF16(blockedDataStr);
|
||||
const char16_t* params[] = { mViolatedDirective.get(),
|
||||
blockedDataChar16.get() };
|
||||
CSP_LogLocalizedStr(NS_LITERAL_STRING("CSPViolationWithURI").get(),
|
||||
|
||||
CSP_LogLocalizedStr(mReportOnlyFlag ? NS_LITERAL_STRING("CSPROViolationWithURI").get() :
|
||||
NS_LITERAL_STRING("CSPViolationWithURI").get(),
|
||||
params, ArrayLength(params),
|
||||
mSourceFile, mScriptSample, mLineNum, 0,
|
||||
nsIScriptError::errorFlag, "CSP", mInnerWindowID);
|
||||
@ -899,6 +903,7 @@ class CSPReportSenderRunnable MOZ_FINAL : public nsRunnable
|
||||
nsCOMPtr<nsISupports> mBlockedContentSource;
|
||||
nsCOMPtr<nsIURI> mOriginalURI;
|
||||
uint32_t mViolatedPolicyIndex;
|
||||
bool mReportOnlyFlag;
|
||||
nsString mViolatedDirective;
|
||||
nsCOMPtr<nsISupports> mObserverSubject;
|
||||
nsString mSourceFile;
|
||||
@ -943,9 +948,12 @@ nsCSPContext::AsyncReportViolation(nsISupports* aBlockedContentSource,
|
||||
const nsAString& aScriptSample,
|
||||
uint32_t aLineNum)
|
||||
{
|
||||
NS_ENSURE_ARG_MAX(aViolatedPolicyIndex, mPolicies.Length() - 1);
|
||||
|
||||
NS_DispatchToMainThread(new CSPReportSenderRunnable(aBlockedContentSource,
|
||||
aOriginalURI,
|
||||
aViolatedPolicyIndex,
|
||||
mPolicies[aViolatedPolicyIndex]->getReportOnlyFlag(),
|
||||
aViolatedDirective,
|
||||
aObserverSubject,
|
||||
aSourceFile,
|
||||
|
@ -519,7 +519,7 @@ nsContentList::Item(uint32_t aIndex, bool aDoFlush)
|
||||
}
|
||||
|
||||
if (mState != LIST_UP_TO_DATE)
|
||||
PopulateSelf(std::min(aIndex, uint32_t(UINT32_MAX - 1)) + 1);
|
||||
PopulateSelf(std::min(aIndex, UINT32_MAX - 1) + 1);
|
||||
|
||||
ASSERT_IN_SYNC;
|
||||
NS_ASSERTION(!mRootNode || mState != LIST_DIRTY,
|
||||
|
@ -2682,18 +2682,9 @@ nsDocument::InitCSP(nsIChannel* aChannel)
|
||||
}
|
||||
|
||||
nsAutoCString tCspHeaderValue, tCspROHeaderValue;
|
||||
nsAutoCString tCspOldHeaderValue, tCspOldROHeaderValue;
|
||||
|
||||
nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(aChannel);
|
||||
if (httpChannel) {
|
||||
httpChannel->GetResponseHeader(
|
||||
NS_LITERAL_CSTRING("x-content-security-policy"),
|
||||
tCspOldHeaderValue);
|
||||
|
||||
httpChannel->GetResponseHeader(
|
||||
NS_LITERAL_CSTRING("x-content-security-policy-report-only"),
|
||||
tCspOldROHeaderValue);
|
||||
|
||||
httpChannel->GetResponseHeader(
|
||||
NS_LITERAL_CSTRING("content-security-policy"),
|
||||
tCspHeaderValue);
|
||||
@ -2704,35 +2695,6 @@ nsDocument::InitCSP(nsIChannel* aChannel)
|
||||
}
|
||||
NS_ConvertASCIItoUTF16 cspHeaderValue(tCspHeaderValue);
|
||||
NS_ConvertASCIItoUTF16 cspROHeaderValue(tCspROHeaderValue);
|
||||
NS_ConvertASCIItoUTF16 cspOldHeaderValue(tCspOldHeaderValue);
|
||||
NS_ConvertASCIItoUTF16 cspOldROHeaderValue(tCspOldROHeaderValue);
|
||||
|
||||
// Only use the CSP 1.0 spec compliant headers if a pref to do so
|
||||
// is set. This lets us turn on the 1.0 parser per platform. This
|
||||
// pref is also set by the tests for 1.0 spec compliant CSP.
|
||||
bool specCompliantEnabled =
|
||||
Preferences::GetBool("security.csp.speccompliant");
|
||||
|
||||
// If spec compliant pref isn't set, pretend we never got these headers.
|
||||
if ((!cspHeaderValue.IsEmpty() || !cspROHeaderValue.IsEmpty()) &&
|
||||
!specCompliantEnabled) {
|
||||
PR_LOG(gCspPRLog, PR_LOG_DEBUG,
|
||||
("Got spec compliant CSP headers but pref was not set"));
|
||||
cspHeaderValue.Truncate();
|
||||
cspROHeaderValue.Truncate();
|
||||
}
|
||||
|
||||
// If both the new header AND the old header are present, warn that
|
||||
// the old header will be ignored. Otherwise, if the old header is
|
||||
// present, warn that it will be deprecated.
|
||||
bool oldHeaderIsPresent = !cspOldHeaderValue.IsEmpty() || !cspOldROHeaderValue.IsEmpty();
|
||||
bool newHeaderIsPresent = !cspHeaderValue.IsEmpty() || !cspROHeaderValue.IsEmpty();
|
||||
|
||||
if (oldHeaderIsPresent && newHeaderIsPresent) {
|
||||
mCSPWebConsoleErrorQueue.Add("BothCSPHeadersPresent");
|
||||
} else if (oldHeaderIsPresent) {
|
||||
mCSPWebConsoleErrorQueue.Add("OldCSPHeaderDeprecated");
|
||||
}
|
||||
|
||||
// Figure out if we need to apply an app default CSP or a CSP from an app manifest
|
||||
nsIPrincipal* principal = NodePrincipal();
|
||||
@ -2760,9 +2722,7 @@ nsDocument::InitCSP(nsIChannel* aChannel)
|
||||
if (!applyAppDefaultCSP &&
|
||||
!applyAppManifestCSP &&
|
||||
cspHeaderValue.IsEmpty() &&
|
||||
cspROHeaderValue.IsEmpty() &&
|
||||
cspOldHeaderValue.IsEmpty() &&
|
||||
cspOldROHeaderValue.IsEmpty()) {
|
||||
cspROHeaderValue.IsEmpty()) {
|
||||
#ifdef PR_LOGGING
|
||||
nsCOMPtr<nsIURI> chanURI;
|
||||
aChannel->GetURI(getter_AddRefs(chanURI));
|
||||
@ -2812,7 +2772,7 @@ nsDocument::InitCSP(nsIChannel* aChannel)
|
||||
// * however, we still support XCSP headers during the transition phase
|
||||
// and fall back to the JS implementation if we find an XCSP header.
|
||||
|
||||
if (newHeaderIsPresent && CSPService::sNewBackendEnabled) {
|
||||
if (CSPService::sNewBackendEnabled) {
|
||||
csp = do_CreateInstance("@mozilla.org/cspcontext;1", &rv);
|
||||
}
|
||||
else {
|
||||
@ -2845,36 +2805,25 @@ nsDocument::InitCSP(nsIChannel* aChannel)
|
||||
}
|
||||
|
||||
if (appCSP) {
|
||||
// Use the 1.0 CSP parser for apps if the pref to do so is set.
|
||||
csp->AppendPolicy(appCSP, selfURI, false, specCompliantEnabled);
|
||||
csp->AppendPolicy(appCSP, selfURI, false, true);
|
||||
}
|
||||
}
|
||||
|
||||
// ----- if the doc is an app and specifies a CSP in its manifest, apply it.
|
||||
if (applyAppManifestCSP) {
|
||||
// Use the 1.0 CSP parser for apps if the pref to do so is set.
|
||||
csp->AppendPolicy(appManifestCSP, selfURI, false, specCompliantEnabled);
|
||||
csp->AppendPolicy(appManifestCSP, selfURI, false, true);
|
||||
}
|
||||
|
||||
// While we are supporting both CSP 1.0 and the x- headers, the 1.0 headers
|
||||
// take priority. If both are present, the x-* headers are ignored.
|
||||
|
||||
// ----- if there's a full-strength CSP header, apply it.
|
||||
if (!cspHeaderValue.IsEmpty()) {
|
||||
rv = AppendCSPFromHeader(csp, cspHeaderValue, selfURI, false, true);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
} else if (!cspOldHeaderValue.IsEmpty()) {
|
||||
rv = AppendCSPFromHeader(csp, cspOldHeaderValue, selfURI, false, false);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
// ----- if there's a report-only CSP header, apply it.
|
||||
if (!cspROHeaderValue.IsEmpty()) {
|
||||
rv = AppendCSPFromHeader(csp, cspROHeaderValue, selfURI, true, true);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
} else if (!cspOldROHeaderValue.IsEmpty()) {
|
||||
rv = AppendCSPFromHeader(csp, cspOldROHeaderValue, selfURI, true, false);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
// ----- Enforce frame-ancestor policy on any applied policies
|
||||
|
@ -1715,7 +1715,7 @@ private:
|
||||
nsRefPtr<mozilla::dom::ImportManager> mImportManager;
|
||||
|
||||
#ifdef DEBUG
|
||||
protected:
|
||||
public:
|
||||
bool mWillReparent;
|
||||
#endif
|
||||
};
|
||||
|
@ -6,7 +6,6 @@
|
||||
|
||||
TEST_TOOL_DIRS += [
|
||||
'csp',
|
||||
'xcsp',
|
||||
'websocket_hybi',
|
||||
]
|
||||
|
||||
|
@ -1,163 +0,0 @@
|
||||
|
||||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
const Cu = Components.utils;
|
||||
const Cr = Components.results;
|
||||
|
||||
Cu.import('resource://gre/modules/CSPUtils.jsm');
|
||||
|
||||
var httpserv = null;
|
||||
|
||||
const POLICY_FROM_URI = "allow 'self'; img-src *";
|
||||
const POLICY_PORT = 9000;
|
||||
const POLICY_URI = "http://localhost:" + POLICY_PORT + "/policy";
|
||||
const POLICY_URI_RELATIVE = "/policy";
|
||||
const DOCUMENT_URI = "http://localhost:" + POLICY_PORT + "/document";
|
||||
const CSP_DOC_BODY = "CSP doc content";
|
||||
const SD = CSPRep.SRC_DIRECTIVES;
|
||||
|
||||
// this will get populated by run_tests()
|
||||
var TESTS = [];
|
||||
|
||||
// helper to make URIs
|
||||
function mkuri(foo) {
|
||||
return Cc["@mozilla.org/network/io-service;1"]
|
||||
.getService(Ci.nsIIOService)
|
||||
.newURI(foo, null, null);
|
||||
}
|
||||
|
||||
// helper to use .equals on stuff
|
||||
function do_check_equivalent(foo, bar, stack) {
|
||||
if (!stack)
|
||||
stack = Components.stack.caller;
|
||||
|
||||
var text = foo + ".equals(" + bar + ")";
|
||||
|
||||
if (foo.equals && foo.equals(bar)) {
|
||||
dump("TEST-PASS | " + stack.filename + " | [" + stack.name + " : " +
|
||||
stack.lineNumber + "] " + text + "\n");
|
||||
return;
|
||||
}
|
||||
do_throw(text, stack);
|
||||
}
|
||||
|
||||
function listener(csp, cspr_static) {
|
||||
this.buffer = "";
|
||||
this._csp = csp;
|
||||
this._cspr_static = cspr_static;
|
||||
}
|
||||
|
||||
listener.prototype = {
|
||||
onStartRequest: function (request, ctx) {
|
||||
},
|
||||
|
||||
onDataAvailable: function (request, ctx, stream, offset, count) {
|
||||
var sInputStream = Cc["@mozilla.org/scriptableinputstream;1"]
|
||||
.createInstance(Ci.nsIScriptableInputStream);
|
||||
sInputStream.init(stream);
|
||||
this.buffer = this.buffer.concat(sInputStream.read(count));
|
||||
},
|
||||
|
||||
onStopRequest: function (request, ctx, status) {
|
||||
// make sure that we have the full document content, guaranteeing that
|
||||
// the document channel has been resumed, before we do the comparisons
|
||||
if (this.buffer == CSP_DOC_BODY) {
|
||||
|
||||
// need to re-grab cspr since it may have changed inside the document's
|
||||
// nsIContentSecurityPolicy instance. The problem is, this cspr_str is a
|
||||
// string and not a policy due to the way it's exposed from
|
||||
// nsIContentSecurityPolicy, so we have to re-parse it.
|
||||
let cspr_str = this._csp.getPolicy(0);
|
||||
let cspr = CSPRep.fromString(cspr_str, mkuri(DOCUMENT_URI));
|
||||
|
||||
// and in reparsing it, we lose the 'self' relationships, so need to also
|
||||
// reparse the static one (or find a way to resolve 'self' in the parsed
|
||||
// policy when doing comparisons).
|
||||
let cspr_static_str = this._cspr_static.toString();
|
||||
let cspr_static_reparse = CSPRep.fromString(cspr_static_str, mkuri(DOCUMENT_URI));
|
||||
|
||||
// not null, and one policy .equals the other one
|
||||
do_check_neq(null, cspr);
|
||||
do_check_true(cspr.equals(cspr_static_reparse));
|
||||
|
||||
// final teardown
|
||||
if (TESTS.length == 0) {
|
||||
httpserv.stop(do_test_finished);
|
||||
} else {
|
||||
do_test_finished();
|
||||
(TESTS.shift())();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function run_test() {
|
||||
httpserv = new HttpServer();
|
||||
httpserv.registerPathHandler("/document", csp_doc_response);
|
||||
httpserv.registerPathHandler("/policy", csp_policy_response);
|
||||
httpserv.start(POLICY_PORT);
|
||||
TESTS = [ test_CSPRep_fromPolicyURI, test_CSPRep_fromRelativePolicyURI ];
|
||||
|
||||
// when this triggers the "onStopRequest" callback, it'll
|
||||
// go to the next test.
|
||||
(TESTS.shift())();
|
||||
}
|
||||
|
||||
function makeChan(url) {
|
||||
var ios = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
|
||||
var chan = ios.newChannel(url, null, null).QueryInterface(Ci.nsIHttpChannel);
|
||||
return chan;
|
||||
}
|
||||
|
||||
function csp_doc_response(metadata, response) {
|
||||
response.setStatusLine(metadata.httpVersion, 200, "OK");
|
||||
response.setHeader("Content-Type", "text/html", false);
|
||||
response.bodyOutputStream.write(CSP_DOC_BODY, CSP_DOC_BODY.length);
|
||||
}
|
||||
|
||||
function csp_policy_response(metadata, response) {
|
||||
response.setStatusLine(metadata.httpVersion, 200, "OK");
|
||||
response.setHeader("Content-Type", "text/csp", false);
|
||||
response.bodyOutputStream.write(POLICY_FROM_URI, POLICY_FROM_URI.length);
|
||||
}
|
||||
|
||||
///////////////////// TEST POLICY_URI //////////////////////
|
||||
function test_CSPRep_fromPolicyURI() {
|
||||
do_test_pending();
|
||||
let csp = Cc["@mozilla.org/contentsecuritypolicy;1"]
|
||||
.createInstance(Ci.nsIContentSecurityPolicy);
|
||||
// once the policy-uri is returned we will compare our static CSPRep with one
|
||||
// we generated from the content we got back from the network to make sure
|
||||
// they are equivalent
|
||||
let cspr_static = CSPRep.fromString(POLICY_FROM_URI, mkuri(DOCUMENT_URI));
|
||||
|
||||
// simulates the request for the parent document
|
||||
var docChan = makeChan(DOCUMENT_URI);
|
||||
docChan.asyncOpen(new listener(csp, cspr_static), null);
|
||||
|
||||
// the resulting policy here can be discarded, since it's going to be
|
||||
// "allow *"; when the policy-uri fetching call-back happens, the *real*
|
||||
// policy will be in csp.policy
|
||||
CSPRep.fromString("policy-uri " + POLICY_URI,
|
||||
mkuri(DOCUMENT_URI), false, docChan, csp);
|
||||
}
|
||||
|
||||
function test_CSPRep_fromRelativePolicyURI() {
|
||||
do_test_pending();
|
||||
let csp = Cc["@mozilla.org/contentsecuritypolicy;1"]
|
||||
.createInstance(Ci.nsIContentSecurityPolicy);
|
||||
// once the policy-uri is returned we will compare our static CSPRep with one
|
||||
// we generated from the content we got back from the network to make sure
|
||||
// they are equivalent
|
||||
let cspr_static = CSPRep.fromString(POLICY_FROM_URI, mkuri(DOCUMENT_URI));
|
||||
|
||||
// simulates the request for the parent document
|
||||
var docChan = makeChan(DOCUMENT_URI);
|
||||
docChan.asyncOpen(new listener(csp, cspr_static), null);
|
||||
|
||||
// the resulting policy here can be discarded, since it's going to be
|
||||
// "allow *"; when the policy-uri fetching call-back happens, the *real*
|
||||
// policy will be in csp.policy
|
||||
CSPRep.fromString("policy-uri " + POLICY_URI_RELATIVE,
|
||||
mkuri(DOCUMENT_URI), false, docChan, csp);
|
||||
}
|
@ -27,7 +27,7 @@ function testValidSRCsHostSourceWithSchemeAndPath() {
|
||||
]
|
||||
|
||||
var obj;
|
||||
var expected = "http://test1.example.com:80";
|
||||
var expected = "http://test1.example.com";
|
||||
for (let i in csps) {
|
||||
var src = csps[i];
|
||||
obj = CSPSourceList.fromString(src, undefined, self);
|
||||
@ -53,7 +53,7 @@ function testValidSRCsRegularHost() {
|
||||
]
|
||||
|
||||
var obj;
|
||||
var expected = "http://test1.example.com:80";
|
||||
var expected = "http://test1.example.com";
|
||||
for (let i in csps) {
|
||||
var src = csps[i];
|
||||
obj = CSPSourceList.fromString(src, undefined, self);
|
||||
@ -77,7 +77,7 @@ function testValidSRCsWildCardHost() {
|
||||
]
|
||||
|
||||
var obj;
|
||||
var expected = "http://*.example.com:80";
|
||||
var expected = "http://*.example.com";
|
||||
for (let i in csps) {
|
||||
var src = csps[i];
|
||||
obj = CSPSourceList.fromString(src, undefined, self);
|
||||
@ -99,7 +99,7 @@ function testValidSRCsRegularPort() {
|
||||
]
|
||||
|
||||
var obj;
|
||||
var expected = "http://test1.example.com:80";
|
||||
var expected = "http://test1.example.com";
|
||||
for (let i in csps) {
|
||||
var src = csps[i];
|
||||
obj = CSPSourceList.fromString(src, undefined, self);
|
||||
|
@ -63,8 +63,9 @@ function makeTest(id, expectedJSON, useReportOnlyPolicy, callback) {
|
||||
|
||||
// set up a new CSP instance for each test.
|
||||
var csp = Cc["@mozilla.org/contentsecuritypolicy;1"]
|
||||
//var csp = Cc["@mozilla.org/cspcontext;1"]
|
||||
.createInstance(Ci.nsIContentSecurityPolicy);
|
||||
var policy = "allow 'none'; " +
|
||||
var policy = "default-src 'none'; " +
|
||||
"report-uri " + REPORT_SERVER_URI +
|
||||
":" + REPORT_SERVER_PORT +
|
||||
"/test" + id;
|
||||
@ -80,7 +81,7 @@ function makeTest(id, expectedJSON, useReportOnlyPolicy, callback) {
|
||||
|
||||
// Load up the policy
|
||||
// set as report-only if that's the case
|
||||
csp.appendPolicy(policy, selfuri, useReportOnlyPolicy, false);
|
||||
csp.appendPolicy(policy, selfuri, useReportOnlyPolicy, true);
|
||||
|
||||
// prime the report server
|
||||
var handler = makeReportHandler("/test" + id, "Test " + id, expectedJSON);
|
||||
|
@ -35,7 +35,7 @@ function do_check_in_array(arr, val, stack) {
|
||||
var text = val + " in [" + arr.join(",") + "]";
|
||||
|
||||
for(var i in arr) {
|
||||
dump(".......... " + i + "> " + arr[i] + "\n");
|
||||
//dump(".......... " + i + "> " + arr[i] + "\n");
|
||||
if(arr[i] == val) {
|
||||
//succeed
|
||||
++_passedChecks;
|
||||
@ -261,7 +261,7 @@ test(
|
||||
test(
|
||||
function test_CSPSourceList_fromString_twohost() {
|
||||
var str = "foo.bar:21 https://ras.bar";
|
||||
var parsed = "http://foo.bar:21 https://ras.bar:443";
|
||||
var parsed = "http://foo.bar:21 https://ras.bar";
|
||||
var sd = CSPSourceList.fromString(str, undefined, URI("http://self.com:80"));
|
||||
//"two-host list should parse"
|
||||
do_check_neq(null,sd);
|
||||
@ -321,43 +321,26 @@ test(
|
||||
do_check_false(wildcardHostSourceList.permits("http://barbaz.com"));
|
||||
});
|
||||
|
||||
///////////////////// Test the Whole CSP rep object //////////////////////
|
||||
|
||||
//////////////// TEST CSP REP SPEC COMPLIANT PARSER ////////////
|
||||
test(
|
||||
function test_CSPRep_fromString() {
|
||||
|
||||
// check default init
|
||||
//ASSERT(!(new CSPRep())._isInitialized, "Uninitialized rep thinks it is.")
|
||||
|
||||
var cspr;
|
||||
var cspr_allowval;
|
||||
var SD = CSPRep.SRC_DIRECTIVES_OLD;
|
||||
var SD = CSPRep.SRC_DIRECTIVES;
|
||||
var DEFAULTS = [SD.STYLE_SRC, SD.MEDIA_SRC, SD.IMG_SRC, SD.SCRIPT_SRC, SD.FONT_SRC,
|
||||
SD.OBJECT_SRC, SD.FRAME_SRC, SD.CONNECT_SRC];
|
||||
|
||||
// check default policy "allow *"
|
||||
cspr = CSPRep.fromString("allow *", URI("http://self.com:80"));
|
||||
// "DEFAULT_SRC directive is missing when specified in fromString"
|
||||
do_check_has_key(cspr._directives, SD.DEFAULT_SRC);
|
||||
|
||||
});
|
||||
|
||||
|
||||
test(
|
||||
function test_CSPRep_defaultSrc() {
|
||||
var cspr, cspr_default_val, cspr_allow;
|
||||
var SD = CSPRep.SRC_DIRECTIVES_OLD;
|
||||
|
||||
// apply policy of "default-src *" (e.g. "allow *")
|
||||
// check default policy "default-src *"
|
||||
cspr = CSPRep.fromString("default-src *", URI("http://self.com:80"));
|
||||
// "DEFAULT_SRC directive is missing when specified in fromString"
|
||||
do_check_has_key(cspr._directives, SD.DEFAULT_SRC);
|
||||
|
||||
// check that |allow *| and |default-src *| are parsed equivalently and
|
||||
// result in the same set of explicit policy directives
|
||||
cspr = CSPRep.fromString("default-src *", URI("http://self.com:80"));
|
||||
cspr_allow = CSPRep.fromString("allow *", URI("http://self.com:80"));
|
||||
|
||||
do_check_equivalent(cspr._directives['default-src'],
|
||||
cspr_allow._directives['default-src']);
|
||||
for(var x in DEFAULTS) {
|
||||
// each of these should be equivalent to DEFAULT_SRC
|
||||
//DEFAULTS[x] + " does not use default rule."
|
||||
do_check_true(cspr.permits("http://bar.com", DEFAULTS[x]));
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@ -365,11 +348,12 @@ test(
|
||||
function test_CSPRep_fromString_oneDir() {
|
||||
|
||||
var cspr;
|
||||
var SD = CSPRep.SRC_DIRECTIVES_OLD;
|
||||
var DEFAULTS = [SD.STYLE_SRC, SD.MEDIA_SRC, SD.IMG_SRC, SD.FRAME_SRC];
|
||||
var SD = CSPRep.SRC_DIRECTIVES;
|
||||
var DEFAULTS = [SD.STYLE_SRC, SD.MEDIA_SRC, SD.IMG_SRC,
|
||||
SD.FRAME_SRC, SD.CONNECT_SRC];
|
||||
|
||||
// check one-directive policies
|
||||
cspr = CSPRep.fromString("allow bar.com; script-src https://foo.com",
|
||||
cspr = CSPRep.fromString("default-src bar.com; script-src https://foo.com",
|
||||
URI("http://self.com"));
|
||||
|
||||
for(var x in DEFAULTS) {
|
||||
@ -389,15 +373,18 @@ test(
|
||||
});
|
||||
|
||||
test(
|
||||
function test_CSPRep_fromString_twodir() {
|
||||
function test_CSPRep_fromString_twoDir() {
|
||||
var cspr;
|
||||
var SD = CSPRep.SRC_DIRECTIVES_OLD;
|
||||
var DEFAULTS = [SD.STYLE_SRC, SD.MEDIA_SRC, SD.FRAME_SRC];
|
||||
|
||||
var SD = CSPRep.SRC_DIRECTIVES;
|
||||
|
||||
var DEFAULTS = [SD.STYLE_SRC, SD.MEDIA_SRC, SD.FRAME_SRC,
|
||||
SD.CONNECT_SRC];
|
||||
|
||||
// check two-directive policies
|
||||
var polstr = "allow allow.com; "
|
||||
+ "script-src https://foo.com; "
|
||||
+ "img-src bar.com:*";
|
||||
var polstr = "default-src allow.com; " +
|
||||
"script-src https://foo.com; " +
|
||||
"img-src bar.com:*";
|
||||
cspr = CSPRep.fromString(polstr, URI("http://self.com"));
|
||||
|
||||
for(var x in DEFAULTS) {
|
||||
@ -425,123 +412,12 @@ test(
|
||||
|
||||
test(function test_CSPRep_fromString_withself() {
|
||||
var cspr;
|
||||
var SD = CSPRep.SRC_DIRECTIVES_OLD;
|
||||
var self = "https://self.com:34";
|
||||
var SD = CSPRep.SRC_DIRECTIVES;
|
||||
|
||||
// check one-directive policies
|
||||
cspr = CSPRep.fromString("allow 'self'; script-src 'self' https://*:*",
|
||||
URI(self));
|
||||
//"img-src does not enforce default rule, 'self'.
|
||||
do_check_false(cspr.permits("https://foo.com:400", SD.IMG_SRC));
|
||||
//"img-src does not allow self
|
||||
do_check_true(cspr.permits(self, SD.IMG_SRC));
|
||||
//"script-src is too relaxed
|
||||
do_check_false(cspr.permits("http://evil.com", SD.SCRIPT_SRC));
|
||||
//"script-src should allow self
|
||||
do_check_true(cspr.permits(self, SD.SCRIPT_SRC));
|
||||
//"script-src is too strict on host/port
|
||||
do_check_true(cspr.permits("https://evil.com:100", SD.SCRIPT_SRC));
|
||||
});
|
||||
|
||||
|
||||
//////////////// TEST CSP REP SPEC COMPLIANT PARSER ////////////
|
||||
test(
|
||||
function test_CSPRep_fromStringSpecCompliant() {
|
||||
|
||||
var cspr;
|
||||
var cspr_allowval;
|
||||
var SD = CSPRep.SRC_DIRECTIVES_NEW;
|
||||
var DEFAULTS = [SD.STYLE_SRC, SD.MEDIA_SRC, SD.IMG_SRC, SD.SCRIPT_SRC, SD.FONT_SRC,
|
||||
SD.OBJECT_SRC, SD.FRAME_SRC, SD.CONNECT_SRC];
|
||||
|
||||
// check default policy "default-src *"
|
||||
cspr = CSPRep.fromStringSpecCompliant("default-src *", URI("http://self.com:80"));
|
||||
// "DEFAULT_SRC directive is missing when specified in
|
||||
// fromStringSpecCompliant"
|
||||
do_check_has_key(cspr._directives, SD.DEFAULT_SRC);
|
||||
|
||||
for(var x in DEFAULTS) {
|
||||
// each of these should be equivalent to DEFAULT_SRC
|
||||
//DEFAULTS[x] + " does not use default rule."
|
||||
do_check_true(cspr.permits("http://bar.com", DEFAULTS[x]));
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
test(
|
||||
function test_CSPRep_fromStringSpecCompliant_oneDir() {
|
||||
|
||||
var cspr;
|
||||
var SD = CSPRep.SRC_DIRECTIVES_NEW;
|
||||
var DEFAULTS = [SD.STYLE_SRC, SD.MEDIA_SRC, SD.IMG_SRC,
|
||||
SD.FRAME_SRC, SD.CONNECT_SRC];
|
||||
|
||||
// check one-directive policies
|
||||
cspr = CSPRep.fromStringSpecCompliant("default-src bar.com; script-src https://foo.com",
|
||||
URI("http://self.com"));
|
||||
|
||||
for(var x in DEFAULTS) {
|
||||
//DEFAULTS[x] + " does not use default rule."
|
||||
do_check_false(cspr.permits("http://bar.com:22", DEFAULTS[x]));
|
||||
//DEFAULTS[x] + " does not use default rule."
|
||||
do_check_true(cspr.permits("http://bar.com:80", DEFAULTS[x]));
|
||||
//DEFAULTS[x] + " does not use default rule."
|
||||
do_check_false(cspr.permits("https://foo.com:400", DEFAULTS[x]));
|
||||
//DEFAULTS[x] + " does not use default rule."
|
||||
do_check_false(cspr.permits("https://foo.com", DEFAULTS[x]));
|
||||
}
|
||||
//"script-src false positive in policy.
|
||||
do_check_false(cspr.permits("http://bar.com:22", SD.SCRIPT_SRC));
|
||||
//"script-src false negative in policy.
|
||||
do_check_true(cspr.permits("https://foo.com:443", SD.SCRIPT_SRC));
|
||||
});
|
||||
|
||||
test(
|
||||
function test_CSPRep_fromStringSpecCompliant_twodir() {
|
||||
var cspr;
|
||||
|
||||
var SD = CSPRep.SRC_DIRECTIVES_NEW;
|
||||
|
||||
var DEFAULTS = [SD.STYLE_SRC, SD.MEDIA_SRC, SD.FRAME_SRC,
|
||||
SD.CONNECT_SRC];
|
||||
|
||||
// check two-directive policies
|
||||
var polstr = "default-src allow.com; " +
|
||||
"script-src https://foo.com; " +
|
||||
"img-src bar.com:*";
|
||||
cspr = CSPRep.fromStringSpecCompliant(polstr, URI("http://self.com"));
|
||||
|
||||
for(var x in DEFAULTS) {
|
||||
do_check_true(cspr.permits("http://allow.com", DEFAULTS[x]));
|
||||
//DEFAULTS[x] + " does not use default rule.
|
||||
do_check_false(cspr.permits("https://foo.com:400", DEFAULTS[x]));
|
||||
//DEFAULTS[x] + " does not use default rule.
|
||||
do_check_false(cspr.permits("http://bar.com:400", DEFAULTS[x]));
|
||||
//DEFAULTS[x] + " does not use default rule.
|
||||
}
|
||||
//"img-src does not use default rule.
|
||||
do_check_false(cspr.permits("http://allow.com:22", SD.IMG_SRC));
|
||||
//"img-src does not use default rule.
|
||||
do_check_false(cspr.permits("https://foo.com:400", SD.IMG_SRC));
|
||||
//"img-src does not use default rule.
|
||||
do_check_true(cspr.permits("http://bar.com:88", SD.IMG_SRC));
|
||||
|
||||
//"script-src does not use default rule.
|
||||
do_check_false(cspr.permits("http://allow.com:22", SD.SCRIPT_SRC));
|
||||
//"script-src does not use default rule.
|
||||
do_check_true(cspr.permits("https://foo.com:443", SD.SCRIPT_SRC));
|
||||
//"script-src does not use default rule.
|
||||
do_check_false(cspr.permits("http://bar.com:400", SD.SCRIPT_SRC));
|
||||
});
|
||||
|
||||
test(function test_CSPRep_fromStringSpecCompliant_withself() {
|
||||
var cspr;
|
||||
var self = "https://self.com:34";
|
||||
var SD = CSPRep.SRC_DIRECTIVES_NEW;
|
||||
|
||||
// check one-directive policies
|
||||
cspr = CSPRep.fromStringSpecCompliant("default-src 'self'; script-src 'self' https://*:*",
|
||||
URI(self));
|
||||
cspr = CSPRep.fromString("default-src 'self'; script-src 'self' https://*:*",
|
||||
URI(self));
|
||||
//"img-src does not enforce default rule, 'self'.
|
||||
do_check_false(cspr.permits("https://foo.com:400", SD.IMG_SRC));
|
||||
//"img-src does not allow self
|
||||
@ -559,34 +435,10 @@ test(function test_CSPRep_fromStringSpecCompliant_withself() {
|
||||
// (see bug 555068)
|
||||
test(function test_FrameAncestor_defaults() {
|
||||
var cspr;
|
||||
var SD = CSPRep.SRC_DIRECTIVES_OLD;
|
||||
var self = "http://self.com:34";
|
||||
var SD = CSPRep.SRC_DIRECTIVES;
|
||||
|
||||
cspr = CSPRep.fromString("allow 'none'", URI(self));
|
||||
|
||||
//"frame-ancestors should default to * not 'allow' value"
|
||||
do_check_true(cspr.permits("https://foo.com:400", SD.FRAME_ANCESTORS));
|
||||
do_check_true(cspr.permits("http://self.com:34", SD.FRAME_ANCESTORS));
|
||||
do_check_true(cspr.permits("https://self.com:34", SD.FRAME_ANCESTORS));
|
||||
do_check_true(cspr.permits("http://self.com", SD.FRAME_ANCESTORS));
|
||||
do_check_true(cspr.permits("http://subd.self.com:34", SD.FRAME_ANCESTORS));
|
||||
|
||||
cspr = CSPRep.fromString("allow 'none'; frame-ancestors 'self'", URI(self));
|
||||
|
||||
//"frame-ancestors should only allow self"
|
||||
do_check_true(cspr.permits("http://self.com:34", SD.FRAME_ANCESTORS));
|
||||
do_check_false(cspr.permits("https://foo.com:400", SD.FRAME_ANCESTORS));
|
||||
do_check_false(cspr.permits("https://self.com:34", SD.FRAME_ANCESTORS));
|
||||
do_check_false(cspr.permits("http://self.com", SD.FRAME_ANCESTORS));
|
||||
do_check_false(cspr.permits("http://subd.self.com:34", SD.FRAME_ANCESTORS));
|
||||
});
|
||||
|
||||
test(function test_FrameAncestor_defaults_specCompliant() {
|
||||
var cspr;
|
||||
var self = "http://self.com:34";
|
||||
var SD = CSPRep.SRC_DIRECTIVES_NEW;
|
||||
|
||||
cspr = CSPRep.fromStringSpecCompliant("default-src 'none'", URI(self));
|
||||
cspr = CSPRep.fromString("default-src 'none'", URI(self));
|
||||
|
||||
//"frame-ancestors should default to * not 'default-src' value"
|
||||
do_check_true(cspr.permits("https://foo.com:400", SD.FRAME_ANCESTORS));
|
||||
@ -595,7 +447,7 @@ test(function test_FrameAncestor_defaults_specCompliant() {
|
||||
do_check_true(cspr.permits("http://self.com", SD.FRAME_ANCESTORS));
|
||||
do_check_true(cspr.permits("http://subd.self.com:34", SD.FRAME_ANCESTORS));
|
||||
|
||||
cspr = CSPRep.fromStringSpecCompliant("default-src 'none'; frame-ancestors 'self'", URI(self));
|
||||
cspr = CSPRep.fromString("default-src 'none'; frame-ancestors 'self'", URI(self));
|
||||
|
||||
//"frame-ancestors should only allow self"
|
||||
do_check_true(cspr.permits("http://self.com:34", SD.FRAME_ANCESTORS));
|
||||
@ -608,10 +460,10 @@ test(function test_FrameAncestor_defaults_specCompliant() {
|
||||
|
||||
test(function test_FrameAncestor_TLD_defaultPorts() {
|
||||
var cspr;
|
||||
var SD = CSPRep.SRC_DIRECTIVES_OLD;
|
||||
var SD = CSPRep.SRC_DIRECTIVES;
|
||||
var self = "http://self"; //TLD only, no .com or anything.
|
||||
|
||||
cspr = CSPRep.fromString("allow 'self'; frame-ancestors 'self' http://foo:80 bar:80 http://three", URI(self));
|
||||
cspr = CSPRep.fromString("default-src 'self'; frame-ancestors 'self' http://foo:80 bar:80 http://three", URI(self));
|
||||
|
||||
//"frame-ancestors should default to * not 'allow' value"
|
||||
do_check_true(cspr.permits("http://self", SD.FRAME_ANCESTORS));
|
||||
@ -630,7 +482,7 @@ test(function test_FrameAncestor_TLD_defaultPorts() {
|
||||
|
||||
test(function test_FrameAncestor_ignores_userpass_bug779918() {
|
||||
var cspr;
|
||||
var SD = CSPRep.SRC_DIRECTIVES_OLD;
|
||||
var SD = CSPRep.SRC_DIRECTIVES;
|
||||
var self = "http://self.com/bar";
|
||||
var testPolicy = "default-src 'self'; frame-ancestors 'self'";
|
||||
|
||||
@ -678,7 +530,7 @@ test(function test_FrameAncestor_ignores_userpass_bug779918() {
|
||||
|
||||
test(function test_CSP_ReportURI_parsing() {
|
||||
var cspr;
|
||||
var SD = CSPRep.SRC_DIRECTIVES_NEW;
|
||||
var SD = CSPRep.SRC_DIRECTIVES;
|
||||
var self = "http://self.com:34";
|
||||
var parsedURIs = [];
|
||||
|
||||
@ -692,48 +544,48 @@ test(function test_CSP_ReportURI_parsing() {
|
||||
var uri_other_scheme_absolute = "https://self.com/report.py";
|
||||
var uri_other_scheme_and_host_absolute = "https://foo.com/report.py";
|
||||
|
||||
cspr = CSPRep.fromStringSpecCompliant("default-src *; report-uri " + uri_valid_absolute, URI(self));
|
||||
cspr = CSPRep.fromString("default-src *; report-uri " + uri_valid_absolute, URI(self));
|
||||
parsedURIs = cspr.getReportURIs().split(/\s+/);
|
||||
do_check_in_array(parsedURIs, uri_valid_absolute);
|
||||
do_check_eq(parsedURIs.length, 1);
|
||||
|
||||
cspr = CSPRep.fromStringSpecCompliant("default-src *; report-uri " + uri_other_host_absolute, URI(self));
|
||||
cspr = CSPRep.fromString("default-src *; report-uri " + uri_other_host_absolute, URI(self));
|
||||
parsedURIs = cspr.getReportURIs().split(/\s+/);
|
||||
do_check_in_array(parsedURIs, uri_other_host_absolute);
|
||||
do_check_eq(parsedURIs.length, 1); // the empty string is in there.
|
||||
|
||||
cspr = CSPRep.fromStringSpecCompliant("default-src *; report-uri " + uri_invalid_relative, URI(self));
|
||||
cspr = CSPRep.fromString("default-src *; report-uri " + uri_invalid_relative, URI(self));
|
||||
parsedURIs = cspr.getReportURIs().split(/\s+/);
|
||||
do_check_in_array(parsedURIs, "");
|
||||
do_check_eq(parsedURIs.length, 1);
|
||||
|
||||
cspr = CSPRep.fromStringSpecCompliant("default-src *; report-uri " + uri_valid_relative, URI(self));
|
||||
cspr = CSPRep.fromString("default-src *; report-uri " + uri_valid_relative, URI(self));
|
||||
parsedURIs = cspr.getReportURIs().split(/\s+/);
|
||||
do_check_in_array(parsedURIs, uri_valid_relative_expanded);
|
||||
do_check_eq(parsedURIs.length, 1);
|
||||
|
||||
cspr = CSPRep.fromStringSpecCompliant("default-src *; report-uri " + uri_valid_relative2, URI(self));
|
||||
cspr = CSPRep.fromString("default-src *; report-uri " + uri_valid_relative2, URI(self));
|
||||
parsedURIs = cspr.getReportURIs().split(/\s+/);
|
||||
dump(parsedURIs.length);
|
||||
do_check_in_array(parsedURIs, uri_valid_relative2_expanded);
|
||||
do_check_eq(parsedURIs.length, 1);
|
||||
|
||||
// make sure cross-scheme reporting works
|
||||
cspr = CSPRep.fromStringSpecCompliant("default-src *; report-uri " + uri_other_scheme_absolute, URI(self));
|
||||
cspr = CSPRep.fromString("default-src *; report-uri " + uri_other_scheme_absolute, URI(self));
|
||||
parsedURIs = cspr.getReportURIs().split(/\s+/);
|
||||
dump(parsedURIs.length);
|
||||
do_check_in_array(parsedURIs, uri_other_scheme_absolute);
|
||||
do_check_eq(parsedURIs.length, 1);
|
||||
|
||||
// make sure cross-scheme, cross-host reporting works
|
||||
cspr = CSPRep.fromStringSpecCompliant("default-src *; report-uri " + uri_other_scheme_and_host_absolute, URI(self));
|
||||
cspr = CSPRep.fromString("default-src *; report-uri " + uri_other_scheme_and_host_absolute, URI(self));
|
||||
parsedURIs = cspr.getReportURIs().split(/\s+/);
|
||||
dump(parsedURIs.length);
|
||||
do_check_in_array(parsedURIs, uri_other_scheme_and_host_absolute);
|
||||
do_check_eq(parsedURIs.length, 1);
|
||||
|
||||
// combination!
|
||||
cspr = CSPRep.fromStringSpecCompliant("default-src *; report-uri " +
|
||||
cspr = CSPRep.fromString("default-src *; report-uri " +
|
||||
uri_valid_relative2 + " " +
|
||||
uri_valid_absolute, URI(self));
|
||||
parsedURIs = cspr.getReportURIs().split(/\s+/);
|
||||
@ -741,7 +593,7 @@ test(function test_CSP_ReportURI_parsing() {
|
||||
do_check_in_array(parsedURIs, uri_valid_absolute);
|
||||
do_check_eq(parsedURIs.length, 2);
|
||||
|
||||
cspr = CSPRep.fromStringSpecCompliant("default-src *; report-uri " +
|
||||
cspr = CSPRep.fromString("default-src *; report-uri " +
|
||||
uri_valid_relative2 + " " +
|
||||
uri_other_host_absolute + " " +
|
||||
uri_valid_absolute, URI(self));
|
||||
@ -755,32 +607,22 @@ test(function test_CSP_ReportURI_parsing() {
|
||||
test(
|
||||
function test_bug634778_duplicateDirective_Detection() {
|
||||
var cspr;
|
||||
var SD = CSPRep.SRC_DIRECTIVES_OLD;
|
||||
var SD = CSPRep.SRC_DIRECTIVES;
|
||||
var self = "http://self.com:34";
|
||||
var firstDomain = "http://first.com";
|
||||
var secondDomain = "http://second.com";
|
||||
var thirdDomain = "http://third.com";
|
||||
|
||||
// check for duplicate "default-src" directives
|
||||
// Spec says first directive persists (subsequent re-statement is
|
||||
// ignored)
|
||||
cspr = CSPRep.fromString("default-src " + self + "; default-src " +
|
||||
firstDomain, URI(self));
|
||||
do_check_true(cspr.permits(self, SD.DEFAULT_SRC));
|
||||
do_check_false(cspr.permits(firstDomain, SD.DEFAULT_SRC));
|
||||
|
||||
// check for duplicate "allow" directives
|
||||
cspr = CSPRep.fromString("allow " + self + "; allow " + firstDomain,
|
||||
URI(self));
|
||||
do_check_true(cspr.permits(self, SD.DEFAULT_SRC));
|
||||
do_check_false(cspr.permits(firstDomain, SD.DEFAULT_SRC));
|
||||
|
||||
// check for duplicate "allow" + "default-src" directives
|
||||
cspr = CSPRep.fromString("allow " + self + "; default-src " + firstDomain,
|
||||
URI(self));
|
||||
do_check_true(cspr.permits(self, SD.DEFAULT_SRC));
|
||||
do_check_false(cspr.permits(firstDomain, SD.DEFAULT_SRC));
|
||||
|
||||
// check for duplicate report-uri directives
|
||||
cspr = CSPRep.fromString("allow *; report-uri " + self + "/report.py; report-uri "
|
||||
cspr = CSPRep.fromString("default-src *; report-uri " + self + "/report.py; report-uri "
|
||||
+ firstDomain + "/report.py", URI(self));
|
||||
parsedURIs = cspr.getReportURIs().split(/\s+/);
|
||||
do_check_in_array(parsedURIs, self + "/report.py");
|
||||
@ -896,9 +738,7 @@ test(
|
||||
|
||||
test(
|
||||
function test_bug764937_defaultSrcMissing() {
|
||||
var cspObjSpecCompliant = Cc["@mozilla.org/contentsecuritypolicy;1"]
|
||||
.createInstance(Ci.nsIContentSecurityPolicy);
|
||||
var cspObjOld = Cc["@mozilla.org/contentsecuritypolicy;1"]
|
||||
var cspObj = Cc["@mozilla.org/contentsecuritypolicy;1"]
|
||||
.createInstance(Ci.nsIContentSecurityPolicy);
|
||||
var selfURI = URI("http://self.com/");
|
||||
|
||||
@ -908,39 +748,21 @@ test(
|
||||
};
|
||||
|
||||
const policy = "script-src 'self'";
|
||||
cspObjSpecCompliant.appendPolicy(policy, selfURI, false, true);
|
||||
cspObj.appendPolicy(policy, selfURI, false, true);
|
||||
|
||||
// Spec-Compliant policy default-src defaults to *.
|
||||
// This means all images are allowed, and only 'self'
|
||||
// script is allowed.
|
||||
do_check_true(testPermits(cspObjSpecCompliant,
|
||||
do_check_true(testPermits(cspObj,
|
||||
URI("http://bar.com/foo.png"),
|
||||
Ci.nsIContentPolicy.TYPE_IMAGE));
|
||||
do_check_true(testPermits(cspObjSpecCompliant,
|
||||
do_check_true(testPermits(cspObj,
|
||||
URI("http://self.com/foo.png"),
|
||||
Ci.nsIContentPolicy.TYPE_IMAGE));
|
||||
do_check_true(testPermits(cspObjSpecCompliant,
|
||||
do_check_true(testPermits(cspObj,
|
||||
URI("http://self.com/foo.js"),
|
||||
Ci.nsIContentPolicy.TYPE_SCRIPT));
|
||||
do_check_false(testPermits(cspObjSpecCompliant,
|
||||
URI("http://bar.com/foo.js"),
|
||||
Ci.nsIContentPolicy.TYPE_SCRIPT));
|
||||
|
||||
cspObjOld.appendPolicy(policy, selfURI, false, false);
|
||||
|
||||
// non-Spec-Compliant policy default-src defaults to 'none'
|
||||
// This means all images are blocked, and so are all scripts (because the
|
||||
// policy is ignored and fails closed).
|
||||
do_check_false(testPermits(cspObjOld,
|
||||
URI("http://bar.com/foo.png"),
|
||||
Ci.nsIContentPolicy.TYPE_IMAGE));
|
||||
do_check_false(testPermits(cspObjOld,
|
||||
URI("http://self.com/foo.png"),
|
||||
Ci.nsIContentPolicy.TYPE_IMAGE));
|
||||
do_check_false(testPermits(cspObjOld,
|
||||
URI("http://self.com/foo.js"),
|
||||
Ci.nsIContentPolicy.TYPE_SCRIPT));
|
||||
do_check_false(testPermits(cspObjOld,
|
||||
do_check_false(testPermits(cspObj,
|
||||
URI("http://bar.com/foo.js"),
|
||||
Ci.nsIContentPolicy.TYPE_SCRIPT));
|
||||
|
||||
@ -955,10 +777,10 @@ test(function test_equals_does_case_insensitive_comparison() {
|
||||
// CSPSource equals ignores case
|
||||
var upperCaseHost = "http://FOO.COM";
|
||||
var lowerCaseHost = "http://foo.com";
|
||||
src1 = CSPSource.fromString(lowerCaseHost);
|
||||
src2 = CSPSource.fromString(lowerCaseHost);
|
||||
var src1 = CSPSource.fromString(lowerCaseHost);
|
||||
var src2 = CSPSource.fromString(lowerCaseHost);
|
||||
do_check_true(src1.equals(src2))
|
||||
src3 = CSPSource.fromString(upperCaseHost);
|
||||
var src3 = CSPSource.fromString(upperCaseHost);
|
||||
do_check_true(src1.equals(src3))
|
||||
|
||||
// CSPHost equals ignores case
|
||||
@ -983,7 +805,7 @@ test(function test_equals_does_case_insensitive_comparison() {
|
||||
|
||||
test(function test_csp_permits_case_insensitive() {
|
||||
var cspr;
|
||||
var SD = CSPRep.SRC_DIRECTIVES_NEW;
|
||||
var SD = CSPRep.SRC_DIRECTIVES;
|
||||
|
||||
// checks directives can be case-insensitive
|
||||
var selfHost = "http://self.com";
|
||||
@ -1042,12 +864,15 @@ function run_test() {
|
||||
httpServer.registerPathHandler("/policy", policyresponder);
|
||||
|
||||
for(let i in tests) {
|
||||
tests[i]();
|
||||
add_task(tests[i]);
|
||||
}
|
||||
|
||||
//teardown
|
||||
httpServer.stop(function() { });
|
||||
do_test_finished();
|
||||
do_register_cleanup(function () {
|
||||
//teardown
|
||||
httpServer.stop(function() { });
|
||||
});
|
||||
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
|
||||
|
@ -21,7 +21,6 @@ support-files =
|
||||
4_result_6.xml
|
||||
|
||||
[test_bug553888.js]
|
||||
[test_bug558431.js]
|
||||
[test_bug737966.js]
|
||||
[test_csputils.js]
|
||||
[test_cspreports.js]
|
||||
|
@ -1,4 +0,0 @@
|
||||
[DEFAULT]
|
||||
|
||||
[test_csp_bug768029.html]
|
||||
[test_csp_bug773891.html]
|
@ -1,20 +0,0 @@
|
||||
/*
|
||||
* 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/content/base/test/xcsp/file_CSP.sjs?testid=font_bad&type=application/octet-stream');
|
||||
}
|
||||
|
||||
.div_arbitrary_good { font-family: "arbitrary_good"; }
|
||||
.div_arbitrary_bad { font-family: "arbitrary_bad"; }
|
||||
|
@ -1,26 +0,0 @@
|
||||
// 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']));
|
||||
}
|
||||
}
|
@ -1,16 +0,0 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<body>
|
||||
<ol>
|
||||
<li id="inline-script">Inline script (green if allowed, black if blocked)</li>
|
||||
</ol>
|
||||
|
||||
<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=img_bad&type=img/png"></img>
|
||||
|
||||
</body>
|
||||
</html>
|
@ -1 +0,0 @@
|
||||
x-content-security-policy-report-only: options eval-script; script-src 'self' ; report-uri /csp_report
|
@ -1,12 +0,0 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>CSP eval script tests</title>
|
||||
<script type="application/javascript"
|
||||
src="file_CSP_evalscript_main.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
Foo.
|
||||
|
||||
</body>
|
||||
</html>
|
@ -1,2 +0,0 @@
|
||||
Cache-Control: no-cache
|
||||
X-Content-Security-Policy: default-src 'self'
|
@ -1,126 +0,0 @@
|
||||
// some javascript for the CSP eval() tests
|
||||
|
||||
function logResult(str, passed) {
|
||||
var elt = document.createElement('div');
|
||||
var color = passed ? "#cfc;" : "#fcc";
|
||||
elt.setAttribute('style', 'background-color:' + color + '; width:100%; border:1px solid black; padding:3px; margin:4px;');
|
||||
elt.innerHTML = str;
|
||||
document.body.appendChild(elt);
|
||||
}
|
||||
|
||||
window._testResults = {};
|
||||
|
||||
// callback for when stuff is allowed by CSP
|
||||
var onevalexecuted = (function(window) {
|
||||
return function(shouldrun, what, data) {
|
||||
window._testResults[what] = "ran";
|
||||
window.parent.scriptRan(shouldrun, what, data);
|
||||
logResult((shouldrun ? "PASS: " : "FAIL: ") + what + " : " + data, shouldrun);
|
||||
};})(window);
|
||||
|
||||
// callback for when stuff is blocked
|
||||
var onevalblocked = (function(window) {
|
||||
return function(shouldrun, what, data) {
|
||||
window._testResults[what] = "blocked";
|
||||
window.parent.scriptBlocked(shouldrun, what, data);
|
||||
logResult((shouldrun ? "FAIL: " : "PASS: ") + what + " : " + data, !shouldrun);
|
||||
};})(window);
|
||||
|
||||
|
||||
// Defer until document is loaded so that we can write the pretty result boxes
|
||||
// out.
|
||||
addEventListener('load', function() {
|
||||
// setTimeout(String) test -- mutate something in the window._testResults
|
||||
// obj, then check it.
|
||||
{
|
||||
var str_setTimeoutWithStringRan = 'onevalexecuted(false, "setTimeout(String)", "setTimeout with a string was enabled.");';
|
||||
function fcn_setTimeoutWithStringCheck() {
|
||||
if (this._testResults["setTimeout(String)"] !== "ran") {
|
||||
onevalblocked(false, "setTimeout(String)",
|
||||
"setTimeout with a string was blocked");
|
||||
}
|
||||
}
|
||||
setTimeout(fcn_setTimeoutWithStringCheck.bind(window), 10);
|
||||
setTimeout(str_setTimeoutWithStringRan, 10);
|
||||
}
|
||||
|
||||
// setTimeout(function) test -- mutate something in the window._testResults
|
||||
// obj, then check it.
|
||||
{
|
||||
function fcn_setTimeoutWithFunctionRan() {
|
||||
onevalexecuted(true, "setTimeout(function)",
|
||||
"setTimeout with a function was enabled.")
|
||||
}
|
||||
function fcn_setTimeoutWithFunctionCheck() {
|
||||
if (this._testResults["setTimeout(function)"] !== "ran") {
|
||||
onevalblocked(true, "setTimeout(function)",
|
||||
"setTimeout with a function was blocked");
|
||||
}
|
||||
}
|
||||
setTimeout(fcn_setTimeoutWithFunctionRan.bind(window), 10);
|
||||
setTimeout(fcn_setTimeoutWithFunctionCheck.bind(window), 10);
|
||||
}
|
||||
|
||||
// eval() test -- should throw exception as per spec
|
||||
try {
|
||||
eval('onevalexecuted(false, "eval(String)", "eval() was enabled.");');
|
||||
} catch (e) {
|
||||
onevalblocked(false, "eval(String)",
|
||||
"eval() was blocked");
|
||||
}
|
||||
|
||||
// eval(foo,bar) test -- should throw exception as per spec
|
||||
try {
|
||||
eval('onevalexecuted(false, "eval(String,scope)", "eval() was enabled.");',1);
|
||||
} catch (e) {
|
||||
onevalblocked(false, "eval(String,object)",
|
||||
"eval() with scope was blocked");
|
||||
}
|
||||
|
||||
// [foo,bar].sort(eval) test -- should throw exception as per spec
|
||||
try {
|
||||
['onevalexecuted(false, "[String, obj].sort(eval)", "eval() was enabled.");',1].sort(eval);
|
||||
} catch (e) {
|
||||
onevalblocked(false, "[String, obj].sort(eval)",
|
||||
"eval() with scope via sort was blocked");
|
||||
}
|
||||
|
||||
// [].sort.call([foo,bar], eval) test -- should throw exception as per spec
|
||||
try {
|
||||
[].sort.call(['onevalexecuted(false, "[String, obj].sort(eval)", "eval() was enabled.");',1], eval);
|
||||
} catch (e) {
|
||||
onevalblocked(false, "[].sort.call([String, obj], eval)",
|
||||
"eval() with scope via sort/call was blocked");
|
||||
}
|
||||
|
||||
// new Function() test -- should throw exception as per spec
|
||||
try {
|
||||
var fcn = new Function('onevalexecuted(false, "new Function(String)", "new Function(String) was enabled.");');
|
||||
fcn();
|
||||
} catch (e) {
|
||||
onevalblocked(false, "new Function(String)",
|
||||
"new Function(String) was blocked.");
|
||||
}
|
||||
|
||||
// setTimeout(eval, 0, str)
|
||||
{
|
||||
// error is not catchable here, instead, we're going to side-effect
|
||||
// 'worked'.
|
||||
var worked = false;
|
||||
|
||||
setTimeout(eval, 0, 'worked = true');
|
||||
setTimeout(function(worked) {
|
||||
if (worked) {
|
||||
onevalexecuted(false, "setTimeout(eval, 0, str)",
|
||||
"setTimeout(eval, 0, string) was enabled.");
|
||||
} else {
|
||||
onevalblocked(false, "setTimeout(eval, 0, str)",
|
||||
"setTimeout(eval, 0, str) was blocked.");
|
||||
}
|
||||
}, 0, worked);
|
||||
}
|
||||
|
||||
}, false);
|
||||
|
||||
|
||||
|
@ -1,12 +0,0 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>CSP eval script tests</title>
|
||||
<script type="application/javascript"
|
||||
src="file_CSP_evalscript_main_getCRMFRequest.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
Foo.
|
||||
|
||||
</body>
|
||||
</html>
|
@ -1,2 +0,0 @@
|
||||
Cache-Control: no-cache
|
||||
X-Content-Security-Policy: default-src 'self'
|
@ -1,48 +0,0 @@
|
||||
// some javascript for the CSP eval() tests
|
||||
|
||||
function logResult(str, passed) {
|
||||
var elt = document.createElement('div');
|
||||
var color = passed ? "#cfc;" : "#fcc";
|
||||
elt.setAttribute('style', 'background-color:' + color + '; width:100%; border:1px solid black; padding:3px; margin:4px;');
|
||||
elt.innerHTML = str;
|
||||
document.body.appendChild(elt);
|
||||
}
|
||||
|
||||
window._testResults = {};
|
||||
|
||||
// callback for when stuff is allowed by CSP
|
||||
var onevalexecuted = (function(window) {
|
||||
return function(shouldrun, what, data) {
|
||||
window._testResults[what] = "ran";
|
||||
window.parent.scriptRan(shouldrun, what, data);
|
||||
logResult((shouldrun ? "PASS: " : "FAIL: ") + what + " : " + data, shouldrun);
|
||||
};})(window);
|
||||
|
||||
// callback for when stuff is blocked
|
||||
var onevalblocked = (function(window) {
|
||||
return function(shouldrun, what, data) {
|
||||
window._testResults[what] = "blocked";
|
||||
window.parent.scriptBlocked(shouldrun, what, data);
|
||||
logResult((shouldrun ? "FAIL: " : "PASS: ") + what + " : " + data, !shouldrun);
|
||||
};})(window);
|
||||
|
||||
|
||||
// Defer until document is loaded so that we can write the pretty result boxes
|
||||
// out.
|
||||
addEventListener('load', function() {
|
||||
// generateCRMFRequest test -- make sure we cannot eval the callback if CSP is in effect
|
||||
try {
|
||||
var script = 'console.log("dynamic script eval\'d in crypto.generateCRMFRequest should be disallowed")';
|
||||
crypto.generateCRMFRequest('CN=0', 0, 0, null, script, 384, null, 'rsa-dual-use');
|
||||
onevalexecuted(false, "crypto.generateCRMFRequest()",
|
||||
"crypto.generateCRMFRequest() should not run!");
|
||||
} catch (e) {
|
||||
onevalblocked(false, "eval(script) inside crypto.generateCRMFRequest",
|
||||
"eval was blocked during crypto.generateCRMFRequest");
|
||||
}
|
||||
|
||||
|
||||
}, false);
|
||||
|
||||
|
||||
|
@ -1,12 +0,0 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>CSP eval script tests: no CSP specified</title>
|
||||
<script type="application/javascript"
|
||||
src="file_CSP_evalscript_no_CSP_at_all.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
Foo. See bug 824652
|
||||
|
||||
</body>
|
||||
</html>
|
@ -1 +0,0 @@
|
||||
Cache-Control: no-cache
|
@ -1,42 +0,0 @@
|
||||
// some javascript for the CSP eval() tests
|
||||
// all of these evals should succeed, as the document loading this script
|
||||
// has script-src 'self' 'unsafe-eval'
|
||||
|
||||
function logResult(str, passed) {
|
||||
var elt = document.createElement('div');
|
||||
var color = passed ? "#cfc;" : "#fcc";
|
||||
elt.setAttribute('style', 'background-color:' + color + '; width:100%; border:1px solid black; padding:3px; margin:4px;');
|
||||
elt.innerHTML = str;
|
||||
document.body.appendChild(elt);
|
||||
}
|
||||
|
||||
// callback for when stuff is allowed by CSP
|
||||
var onevalexecuted = (function(window) {
|
||||
return function(shouldrun, what, data) {
|
||||
window.parent.scriptRan(shouldrun, what, data);
|
||||
logResult((shouldrun ? "PASS: " : "FAIL: ") + what + " : " + data, shouldrun);
|
||||
};})(window);
|
||||
|
||||
// callback for when stuff is blocked
|
||||
var onevalblocked = (function(window) {
|
||||
return function(shouldrun, what, data) {
|
||||
window.parent.scriptBlocked(shouldrun, what, data);
|
||||
logResult((shouldrun ? "FAIL: " : "PASS: ") + what + " : " + data, !shouldrun);
|
||||
};})(window);
|
||||
|
||||
|
||||
// Defer until document is loaded so that we can write the pretty result boxes
|
||||
// out.
|
||||
addEventListener('load', function() {
|
||||
// test that allows crypto.generateCRMFRequest eval to run when there is no CSP at all in place
|
||||
try {
|
||||
var script =
|
||||
'console.log("dynamic script passed to crypto.generateCRMFRequest should execute")';
|
||||
crypto.generateCRMFRequest('CN=0', 0, 0, null, script, 384, null, 'rsa-dual-use');
|
||||
onevalexecuted(true, "eval(script) inside crypto.generateCRMFRequest: no CSP at all",
|
||||
"eval executed during crypto.generateCRMFRequest where no CSP is set at all");
|
||||
} catch (e) {
|
||||
onevalblocked(true, "eval(script) inside crypto.generateCRMFRequest",
|
||||
"eval was blocked during crypto.generateCRMFRequest");
|
||||
}
|
||||
}, false);
|
@ -1,54 +0,0 @@
|
||||
// SJS file for CSP frame ancestor 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);
|
||||
|
||||
// grab the desired policy from the query, and then serve a page
|
||||
if (query['csp'])
|
||||
response.setHeader("X-Content-Security-Policy",
|
||||
unescape(query['csp']),
|
||||
false);
|
||||
if (query['scriptedreport']) {
|
||||
// spit back a script that records that the page loaded
|
||||
response.setHeader("Content-Type", "text/javascript", false);
|
||||
if (query['double'])
|
||||
response.write('window.parent.parent.parent.postMessage({call: "frameLoaded", testname: "' + query['scriptedreport'] + '", uri: "window.location.toString()"}, "*");');
|
||||
else
|
||||
response.write('window.parent.parent.postMessage({call: "frameLoaded", testname: "' + query['scriptedreport'] + '", uri: "window.location.toString()"}, "*");');
|
||||
} else if (query['internalframe']) {
|
||||
// spit back an internal iframe (one that might be blocked)
|
||||
response.setHeader("Content-Type", "text/html", false);
|
||||
response.write('<html><head>');
|
||||
if (query['double'])
|
||||
response.write('<script src="file_CSP_frameancestors.sjs?double=1&scriptedreport=' + query['testid'] + '"></script>');
|
||||
else
|
||||
response.write('<script src="file_CSP_frameancestors.sjs?scriptedreport=' + query['testid'] + '"></script>');
|
||||
response.write('</head><body>');
|
||||
response.write(unescape(query['internalframe']));
|
||||
response.write('</body></html>');
|
||||
} else if (query['externalframe']) {
|
||||
// spit back an internal iframe (one that won't be blocked, and probably
|
||||
// has no CSP)
|
||||
response.setHeader("Content-Type", "text/html", false);
|
||||
response.write('<html><head>');
|
||||
response.write('</head><body>');
|
||||
response.write(unescape(query['externalframe']));
|
||||
response.write('</body></html>');
|
||||
} else {
|
||||
// default case: error.
|
||||
response.setHeader("Content-Type", "text/html", false);
|
||||
response.write('<html><body>');
|
||||
response.write("ERROR: not sure what to serve.");
|
||||
response.write('</body></html>');
|
||||
}
|
||||
}
|
@ -1,44 +0,0 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>CSP frame ancestors tests</title>
|
||||
|
||||
<!-- this page shouldn't have a CSP, just the sub-pages. -->
|
||||
<script src='file_CSP_frameancestors_main.js'></script>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<!-- These iframes will get populated by the attached javascript. -->
|
||||
<tt> aa_allow: /* innermost frame allows a */</tt><br/>
|
||||
<iframe id='aa_allow'></iframe><br/>
|
||||
|
||||
<tt> aa_block: /* innermost frame denies a */</tt><br/>
|
||||
<iframe id='aa_block'></iframe><br/>
|
||||
|
||||
<tt> ab_allow: /* innermost frame allows a */</tt><br/>
|
||||
<iframe id='ab_allow'></iframe><br/>
|
||||
|
||||
<tt> ab_block: /* innermost frame denies a */</tt><br/>
|
||||
<iframe id='ab_block'></iframe><br/>
|
||||
|
||||
<tt> aba_allow: /* innermost frame allows b,a */</tt><br/>
|
||||
<iframe id='aba_allow'></iframe><br/>
|
||||
|
||||
<tt> aba_block: /* innermost frame denies b */</tt><br/>
|
||||
<iframe id='aba_block'></iframe><br/>
|
||||
|
||||
<tt> aba2_block: /* innermost frame denies a */</tt><br/>
|
||||
<iframe id='aba2_block'></iframe><br/>
|
||||
|
||||
<tt> abb_allow: /* innermost frame allows b,a */</tt><br/>
|
||||
<iframe id='abb_allow'></iframe><br/>
|
||||
|
||||
<tt> abb_block: /* innermost frame denies b */</tt><br/>
|
||||
<iframe id='abb_block'></iframe><br/>
|
||||
|
||||
<tt> abb2_block: /* innermost frame denies a */</tt><br/>
|
||||
<iframe id='abb2_block'></iframe><br/>
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
@ -1,65 +0,0 @@
|
||||
// Script to populate the test frames in the frame ancestors mochitest.
|
||||
//
|
||||
function setupFrames() {
|
||||
|
||||
var $ = function(v) { return document.getElementById(v); }
|
||||
var base = {
|
||||
self: '/tests/content/base/test/xcsp/file_CSP_frameancestors.sjs',
|
||||
a: 'http://mochi.test:8888/tests/content/base/test/xcsp/file_CSP_frameancestors.sjs',
|
||||
b: 'http://example.com/tests/content/base/test/xcsp/file_CSP_frameancestors.sjs'
|
||||
};
|
||||
|
||||
var host = { a: 'http://mochi.test:8888', b: 'http://example.com:80' };
|
||||
|
||||
var innerframeuri = null;
|
||||
var elt = null;
|
||||
|
||||
elt = $('aa_allow');
|
||||
elt.src = base.a + "?testid=aa_allow&internalframe=aa_a&csp=" +
|
||||
escape("allow 'none'; frame-ancestors " + host.a + "; script-src 'self'");
|
||||
|
||||
elt = $('aa_block');
|
||||
elt.src = base.a + "?testid=aa_block&internalframe=aa_b&csp=" +
|
||||
escape("allow 'none'; frame-ancestors 'none'; script-src 'self'");
|
||||
|
||||
elt = $('ab_allow');
|
||||
elt.src = base.b + "?testid=ab_allow&internalframe=ab_a&csp=" +
|
||||
escape("allow 'none'; frame-ancestors " + host.a + "; script-src 'self'");
|
||||
|
||||
elt = $('ab_block');
|
||||
elt.src = base.b + "?testid=ab_block&internalframe=ab_b&csp=" +
|
||||
escape("allow 'none'; frame-ancestors 'none'; script-src 'self'");
|
||||
|
||||
/* .... two-level framing */
|
||||
elt = $('aba_allow');
|
||||
innerframeuri = base.a + "?testid=aba_allow&double=1&internalframe=aba_a&csp=" +
|
||||
escape("allow 'none'; frame-ancestors " + host.a + " " + host.b + "; script-src 'self'");
|
||||
elt.src = base.b + "?externalframe=" + escape('<iframe src="' + innerframeuri + '"></iframe>');
|
||||
|
||||
elt = $('aba_block');
|
||||
innerframeuri = base.a + "?testid=aba_allow&double=1&internalframe=aba_b&csp=" +
|
||||
escape("allow 'none'; frame-ancestors " + host.a + "; script-src 'self'");
|
||||
elt.src = base.b + "?externalframe=" + escape('<iframe src="' + innerframeuri + '"></iframe>');
|
||||
|
||||
elt = $('aba2_block');
|
||||
innerframeuri = base.a + "?testid=aba_allow&double=1&internalframe=aba2_b&csp=" +
|
||||
escape("allow 'none'; frame-ancestors " + host.b + "; script-src 'self'");
|
||||
elt.src = base.b + "?externalframe=" + escape('<iframe src="' + innerframeuri + '"></iframe>');
|
||||
|
||||
elt = $('abb_allow');
|
||||
innerframeuri = base.b + "?testid=abb_allow&double=1&internalframe=abb_a&csp=" +
|
||||
escape("allow 'none'; frame-ancestors " + host.a + " " + host.b + "; script-src 'self'");
|
||||
elt.src = base.b + "?externalframe=" + escape('<iframe src="' + innerframeuri + '"></iframe>');
|
||||
|
||||
elt = $('abb_block');
|
||||
innerframeuri = base.b + "?testid=abb_allow&double=1&internalframe=abb_b&csp=" +
|
||||
escape("allow 'none'; frame-ancestors " + host.a + "; script-src 'self'");
|
||||
elt.src = base.b + "?externalframe=" + escape('<iframe src="' + innerframeuri + '"></iframe>');
|
||||
|
||||
elt = $('abb2_block');
|
||||
innerframeuri = base.b + "?testid=abb_allow&double=1&internalframe=abb2_b&csp=" +
|
||||
escape("allow 'none'; frame-ancestors " + host.b + "; script-src 'self'");
|
||||
elt.src = base.b + "?externalframe=" + escape('<iframe src="' + innerframeuri + '"></iframe>');
|
||||
}
|
||||
|
||||
window.addEventListener('load', setupFrames, false);
|
@ -1,20 +0,0 @@
|
||||
<!--
|
||||
-- The original CSP implementation predates the CSP 1.0 spec and didn't
|
||||
-- block inline styles, so when the prefixed X-Content-Security-Policy header is used,
|
||||
-- as it is for this file, inline styles should be allowed.
|
||||
-->
|
||||
<html>
|
||||
<head>
|
||||
<title>CSP inline script tests</title>
|
||||
</head>
|
||||
<body onload="window.parent.scriptRan(false, 'eventattr', 'event attribute in body tag fired')">
|
||||
|
||||
<script type="text/javascript">
|
||||
window.parent.scriptRan(false, "textnode", "text node in a script tag executed.");
|
||||
</script>
|
||||
|
||||
<iframe src='javascript:window.parent.parent.scriptRan(false, "jsuri", "javascript: uri in image tag")'></iframe>
|
||||
|
||||
<a id='anchortoclick' href='javascript:window.parent.scriptRan(false, "jsuri", "javascript: uri in anchor tag ran when clicked.");'>stuff</a>
|
||||
</body>
|
||||
</html>
|
@ -1,2 +0,0 @@
|
||||
X-Content-Security-Policy: allow 'self'
|
||||
Cache-Control: no-cache
|
@ -1,63 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<html>
|
||||
<head>
|
||||
<title>CSP inline script tests</title>
|
||||
<!-- content= "div#linkstylediv { color: #0f0; }" -->
|
||||
<link rel="stylesheet" type="text/css"
|
||||
href='file_CSP.sjs?type=text/css&content=div%23linkstylediv%20%7B%20color%3A%20%230f0%3B%20%7D' />
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<style type="text/css">
|
||||
div#inlinestylediv {
|
||||
color: #00ff00;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div id='linkstylediv'>Link tag (external) stylesheet test (should be green)</div>
|
||||
<div id='attrstylediv' style="color: #00ff00;">Attribute stylesheet test (should be green)</div>
|
||||
<div id='inlinestylediv'>Inline stylesheet test (should be green)</div>
|
||||
|
||||
<!-- tests for SMIL stuff - animations -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
width="100%"
|
||||
height="100px">
|
||||
|
||||
<!-- Animates XML attribute, which is mapped into style. -->
|
||||
<text id="xmlTest" x="0" y="15">
|
||||
This should be green since the animation should be allowed by CSP.
|
||||
|
||||
<animate attributeName="fill" attributeType="XML"
|
||||
values="lime;green;lime" dur="2s"
|
||||
repeatCount="indefinite" />
|
||||
</text>
|
||||
|
||||
<!-- Animates override value for CSS property. -->
|
||||
<text id="cssOverrideTest" x="0" y="35">
|
||||
This should be green since the animation should be allowed by CSP.
|
||||
|
||||
<animate attributeName="fill" attributeType="CSS"
|
||||
values="lime;green;lime" dur="2s"
|
||||
repeatCount="indefinite" />
|
||||
</text>
|
||||
|
||||
<!-- Animates override value for CSS property targeted via ID. -->
|
||||
<text id="cssOverrideTestById" x="0" y="55">
|
||||
This should be green since the animation should be allowed by CSP.
|
||||
</text>
|
||||
<animate xlink:href="#cssOverrideTestById"
|
||||
attributeName="fill"
|
||||
values="lime;green;lime"
|
||||
dur="2s" repeatCount="indefinite" />
|
||||
|
||||
<!-- Sets value for CSS property targeted via ID. -->
|
||||
<text id="cssSetTestById" x="0" y="75">
|
||||
This should be green since the <set> should be allowed by CSP.
|
||||
</text>
|
||||
<set xlink:href="#cssSetTestById"
|
||||
attributeName="fill"
|
||||
to="lime" />
|
||||
</svg>
|
||||
</body>
|
||||
</html>
|
@ -1,2 +0,0 @@
|
||||
X-Content-Security-Policy: default-src 'self'
|
||||
Cache-Control: no-cache
|
@ -1,45 +0,0 @@
|
||||
<html>
|
||||
<head>
|
||||
<link rel='stylesheet' type='text/css'
|
||||
href='http://example.org/tests/content/base/test/csp/file_CSP.sjs?testid=style_bad&type=text/css' />
|
||||
<link rel='stylesheet' type='text/css'
|
||||
href='file_CSP.sjs?testid=style_good&type=text/css' />
|
||||
|
||||
<!-- Used to embed inline styles here for testing fonts, but can't do that -->
|
||||
<!-- due to bug 763879 (block inline styles). Moved these to an external, CSS -->
|
||||
<!-- file (file_CSP.css). -->
|
||||
<link rel='stylesheet' type='text/css' href='file_CSP.css' />
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<!-- these should be stopped by CSP. :) -->
|
||||
<img src="http://example.org/tests/content/base/test/csp/file_CSP.sjs?testid=img_bad&type=img/png"> </img>
|
||||
<audio src="http://example.org/tests/content/base/test/csp/file_CSP.sjs?testid=media_bad&type=audio/vorbis"></audio>
|
||||
<script src='http://example.org/tests/content/base/test/csp/file_CSP.sjs?testid=script_bad&type=text/javascript'></script>
|
||||
<iframe src='http://example.org/tests/content/base/test/csp/file_CSP.sjs?testid=frame_bad&content=FAIL'></iframe>
|
||||
<object width="10" height="10">
|
||||
<param name="movie" value="http://example.org/tests/content/base/test/csp/file_CSP.sjs?testid=object_bad&type=application/x-shockwave-flash">
|
||||
<embed src="http://example.org/tests/content/base/test/csp/file_CSP.sjs?testid=object_bad&type=application/x-shockwave-flash"></embed>
|
||||
</object>
|
||||
|
||||
<!-- these should load ok. :) -->
|
||||
<img src="file_CSP.sjs?testid=img_good&type=img/png" />
|
||||
<audio src="file_CSP.sjs?testid=media_good&type=audio/vorbis"></audio>
|
||||
<script src='file_CSP.sjs?testid=script_good&type=text/javascript'></script>
|
||||
<iframe src='file_CSP.sjs?testid=frame_good&content=PASS'></iframe>
|
||||
|
||||
<object width="10" height="10">
|
||||
<param name="movie" value="file_CSP.sjs?testid=object_good&type=application/x-shockwave-flash">
|
||||
<embed src="file_CSP.sjs?testid=object_good&type=application/x-shockwave-flash"></embed>
|
||||
</object>
|
||||
|
||||
<!-- XHR tests... they're taken care of in this script,
|
||||
and since the URI doesn't have any 'testid' values,
|
||||
it will just be ignored by the test framework. -->
|
||||
<script src='file_CSP_main.js'></script>
|
||||
|
||||
<!-- Support elements for the @font-face test -->
|
||||
<div class="div_arbitrary_good">arbitrary good</div>
|
||||
<div class="div_arbitrary_bad">arbitrary_bad</div>
|
||||
</body>
|
||||
</html>
|
@ -1 +0,0 @@
|
||||
X-Content-Security-Policy: default-src 'self'
|
@ -1,16 +0,0 @@
|
||||
// some javascript for the CSP XHR tests
|
||||
//
|
||||
|
||||
try {
|
||||
var xhr_good = new XMLHttpRequest();
|
||||
var xhr_good_uri ="http://mochi.test:8888/tests/content/base/test/csp/file_CSP.sjs?testid=xhr_good";
|
||||
xhr_good.open("GET", xhr_good_uri, true);
|
||||
xhr_good.send(null);
|
||||
} catch(e) {}
|
||||
|
||||
try {
|
||||
var xhr_bad = new XMLHttpRequest();
|
||||
var xhr_bad_uri ="http://example.com/tests/content/base/test/csp/file_CSP.sjs?testid=xhr_bad";
|
||||
xhr_bad.open("GET", xhr_bad_uri, true);
|
||||
xhr_bad.send(null);
|
||||
} catch(e) {}
|
@ -1,6 +0,0 @@
|
||||
<html>
|
||||
<body>
|
||||
<img src="http://example.org/prefixed.jpg"></img>
|
||||
<img src="/unprefixed.jpg"></img>
|
||||
</body>
|
||||
</html>
|
@ -1,2 +0,0 @@
|
||||
X-Content-Security-Policy: default-src 'none' ; img-src http://example.org
|
||||
Content-Security-Policy: default-src 'self'
|
@ -1,25 +0,0 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=768029
|
||||
-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>This is an app for testing</title>
|
||||
|
||||
<link rel="stylesheet" type="text/css"
|
||||
href="file_csp_bug768029.sjs?type=style&origin=same_origin" />
|
||||
<link rel="stylesheet" type="text/css"
|
||||
href="http://example.com/tests/content/base/test/csp/file_csp_bug768029.sjs?type=style&origin=cross_origin" />
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<script src="file_csp_bug768029.sjs?type=script&origin=same_origin"></script>
|
||||
<script src="http://example.com/tests/content/base/test/csp/file_csp_bug768029.sjs?type=script&origin=cross_origin"></script>
|
||||
<img src="file_csp_bug768029.sjs?type=img&origin=same_origin" />
|
||||
<img src="http://example.com/tests/content/base/test/csp/file_csp_bug768029.sjs?type=img&origin=cross_origin" />
|
||||
|
||||
Test for CSP applied to (simulated) app.
|
||||
|
||||
</body>
|
||||
</html>
|
@ -1,29 +0,0 @@
|
||||
function handleRequest(request, response) {
|
||||
|
||||
var query = {};
|
||||
|
||||
request.queryString.split('&').forEach(function(val) {
|
||||
var [name, value] = val.split('=');
|
||||
query[name] = unescape(value);
|
||||
});
|
||||
response.setHeader("Cache-Control", "no-cache", false);
|
||||
|
||||
if ("type" in query) {
|
||||
switch (query.type) {
|
||||
case "script":
|
||||
response.setHeader("Content-Type", "application/javascript");
|
||||
response.write("\n\ndocument.write('<pre>script loaded\\n</pre>');\n\n");
|
||||
return;
|
||||
case "style":
|
||||
response.setHeader("Content-Type", "text/css");
|
||||
response.write("\n\n.cspfoo { color:red; }\n\n");
|
||||
return;
|
||||
case "img":
|
||||
response.setHeader("Content-Type", "image/png");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
response.setHeader("Content-Type", "text/plain");
|
||||
response.write("ohnoes!");
|
||||
}
|
@ -1,25 +0,0 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=773891
|
||||
-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>This is an app for csp testing</title>
|
||||
|
||||
<link rel="stylesheet" type="text/css"
|
||||
href="file_csp_bug773891.sjs?type=style&origin=same_origin" />
|
||||
<link rel="stylesheet" type="text/css"
|
||||
href="http://example.com/tests/content/base/test/csp/file_csp_bug773891.sjs?type=style&origin=cross_origin" />
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<script src="file_csp_bug773891.sjs?type=script&origin=same_origin"></script>
|
||||
<script src="http://example.com/tests/content/base/test/csp/file_csp_bug773891.sjs?type=script&origin=cross_origin"></script>
|
||||
<img src="file_csp_bug773891.sjs?type=img&origin=same_origin" />
|
||||
<img src="http://example.com/tests/content/base/test/csp/file_csp_bug773891.sjs?type=img&origin=cross_origin" />
|
||||
|
||||
Test for CSP applied to (simulated) app.
|
||||
|
||||
</body>
|
||||
</html>
|
@ -1,29 +0,0 @@
|
||||
function handleRequest(request, response) {
|
||||
|
||||
var query = {};
|
||||
|
||||
request.queryString.split('&').forEach(function(val) {
|
||||
var [name, value] = val.split('=');
|
||||
query[name] = unescape(value);
|
||||
});
|
||||
response.setHeader("Cache-Control", "no-cache", false);
|
||||
|
||||
if ("type" in query) {
|
||||
switch (query.type) {
|
||||
case "script":
|
||||
response.setHeader("Content-Type", "application/javascript");
|
||||
response.write("\n\ndocument.write('<pre>script loaded\\n</pre>');\n\n");
|
||||
return;
|
||||
case "style":
|
||||
response.setHeader("Content-Type", "text/css");
|
||||
response.write("\n\n.cspfoo { color:red; }\n\n");
|
||||
return;
|
||||
case "img":
|
||||
response.setHeader("Content-Type", "image/png");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
response.setHeader("Content-Type", "text/plain");
|
||||
response.write("ohnoes!");
|
||||
}
|
@ -1,35 +0,0 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>CSP redirect tests</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="container"></div>
|
||||
</body>
|
||||
|
||||
<script>
|
||||
var thisSite = "http://mochi.test:8888";
|
||||
var otherSite = "http://example.com";
|
||||
var page = "/tests/content/base/test/xcsp/file_csp_redirects_page.sjs";
|
||||
|
||||
var tests = { "font-src": thisSite+page+"?testid=font-src&csp=1",
|
||||
"frame-src": thisSite+page+"?testid=frame-src&csp=1",
|
||||
"img-src": thisSite+page+"?testid=img-src&csp=1",
|
||||
"media-src": thisSite+page+"?testid=media-src&csp=1",
|
||||
"object-src": thisSite+page+"?testid=object-src&csp=1",
|
||||
"script-src": thisSite+page+"?testid=script-src&csp=1",
|
||||
"style-src": thisSite+page+"?testid=style-src&csp=1",
|
||||
"worker": thisSite+page+"?testid=worker&csp=1",
|
||||
"xhr-src": thisSite+page+"?testid=xhr-src&csp=1",
|
||||
};
|
||||
|
||||
var container = document.getElementById("container");
|
||||
|
||||
// load each test in its own iframe
|
||||
for (tid in tests) {
|
||||
var i = document.createElement("iframe");
|
||||
i.id = tid;
|
||||
i.src = tests[tid];
|
||||
container.appendChild(i);
|
||||
}
|
||||
</script>
|
||||
</html>
|
@ -1,133 +0,0 @@
|
||||
// SJS file for CSP redirect mochitests
|
||||
// This file serves pages which can optionally specify a Content Security Policy
|
||||
function handleRequest(request, response)
|
||||
{
|
||||
var query = {};
|
||||
request.queryString.split('&').forEach(function (val) {
|
||||
var [name, value] = val.split('=');
|
||||
query[name] = unescape(value);
|
||||
});
|
||||
|
||||
response.setHeader("Cache-Control", "no-cache", false);
|
||||
response.setHeader("Content-Type", "text/html", false);
|
||||
|
||||
var resource = "/tests/content/base/test/csp/file_csp_redirects_resource.sjs";
|
||||
|
||||
// CSP header value
|
||||
if (query["csp"] == 1) {
|
||||
if (query["spec"] == 1) {
|
||||
response.setHeader("Content-Security-Policy", "default-src 'self' ; style-src 'self' 'unsafe-inline'", false);
|
||||
} else {
|
||||
response.setHeader("X-Content-Security-Policy", "allow 'self'", false);
|
||||
}
|
||||
}
|
||||
|
||||
// downloadable font that redirects to another site
|
||||
if (query["testid"] == "font-src") {
|
||||
var resp = '<style type="text/css"> @font-face { font-family:' +
|
||||
'"Redirecting Font"; src: url("' + resource +
|
||||
'?res=font&redir=other&id=font-src-redir")} #test{font-family:' +
|
||||
'"Redirecting Font"}</style></head><body>' +
|
||||
'<div id="test">test</div></body>';
|
||||
response.write(resp);
|
||||
return;
|
||||
}
|
||||
|
||||
if (query["testid"] == "font-src-spec-compliant") {
|
||||
var resp = '<style type="text/css"> @font-face { font-family:' +
|
||||
'"Redirecting Font Spec Compliant"; src: url("' + resource +
|
||||
'?res=font-spec-compliant&redir=other&id=font-src-redir-spec-compliant")} #test{font-family:' +
|
||||
'"Redirecting Font Spec Compliant"}</style></head><body>' +
|
||||
'<div id="test">test</div></body>';
|
||||
response.write(resp);
|
||||
return;
|
||||
}
|
||||
|
||||
// iframe that redirects to another site
|
||||
if (query["testid"] == "frame-src") {
|
||||
response.write('<iframe src="'+resource+'?res=iframe&redir=other&id=frame-src-redir"></iframe>');
|
||||
return;
|
||||
}
|
||||
|
||||
if (query["testid"] == "frame-src-spec-compliant") {
|
||||
response.write('<iframe src="'+resource+'?res=iframe&redir=other&id=frame-src-redir-spec-compliant"></iframe>');
|
||||
return;
|
||||
}
|
||||
|
||||
// image that redirects to another site
|
||||
if (query["testid"] == "img-src") {
|
||||
response.write('<img src="'+resource+'?res=image&redir=other&id=img-src-redir" />');
|
||||
return;
|
||||
}
|
||||
|
||||
if (query["testid"] == "img-src-spec-compliant") {
|
||||
response.write('<img src="'+resource+'?res=image&redir=other&id=img-src-redir-spec-compliant" />');
|
||||
return;
|
||||
}
|
||||
|
||||
// video content that redirects to another site
|
||||
if (query["testid"] == "media-src") {
|
||||
response.write('<video src="'+resource+'?res=media&redir=other&id=media-src-redir"></video>');
|
||||
return;
|
||||
}
|
||||
|
||||
if (query["testid"] == "media-src-spec-compliant") {
|
||||
response.write('<video src="'+resource+'?res=media&redir=other&id=media-src-redir-spec-compliant"></video>');
|
||||
return;
|
||||
}
|
||||
|
||||
// object content that redirects to another site
|
||||
if (query["testid"] == "object-src") {
|
||||
response.write('<object type="text/html" data="'+resource+'?res=object&redir=other&id=object-src-redir"></object>');
|
||||
return;
|
||||
}
|
||||
|
||||
if (query["testid"] == "object-src-spec-compliant") {
|
||||
response.write('<object type="text/html" data="'+resource+'?res=object&redir=other&id=object-src-redir-spec-compliant"></object>');
|
||||
return;
|
||||
}
|
||||
|
||||
// external script that redirects to another site
|
||||
if (query["testid"] == "script-src") {
|
||||
response.write('<script src="'+resource+'?res=script&redir=other&id=script-src-redir"></script>');
|
||||
return;
|
||||
}
|
||||
|
||||
if (query["testid"] == "script-src-spec-compliant") {
|
||||
response.write('<script src="'+resource+'?res=script&redir=other&id=script-src-redir-spec-compliant"></script>');
|
||||
return;
|
||||
}
|
||||
|
||||
// external stylesheet that redirects to another site
|
||||
if (query["testid"] == "style-src") {
|
||||
response.write('<link rel="stylesheet" type="text/css" href="'+resource+'?res=style&redir=other&id=style-src-redir"></script>');
|
||||
return;
|
||||
}
|
||||
|
||||
if (query["testid"] == "style-src-spec-compliant") {
|
||||
response.write('<link rel="stylesheet" type="text/css" href="'+resource+'?res=style&redir=other&id=style-src-redir-spec-compliant"></script>');
|
||||
return;
|
||||
}
|
||||
|
||||
// worker script resource that redirects to another site
|
||||
if (query["testid"] == "worker") {
|
||||
response.write('<script src="'+resource+'?res=worker&redir=other&id=worker-redir"></script>');
|
||||
return;
|
||||
}
|
||||
|
||||
if (query["testid"] == "worker-spec-compliant") {
|
||||
response.write('<script src="'+resource+'?res=worker&redir=other&id=worker-redir-spec-compliant"></script>');
|
||||
return;
|
||||
}
|
||||
|
||||
// script that XHR's to a resource that redirects to another site
|
||||
if (query["testid"] == "xhr-src") {
|
||||
response.write('<script src="'+resource+'?res=xhr"></script>');
|
||||
return;
|
||||
}
|
||||
|
||||
if (query["testid"] == "xhr-src-spec-compliant") {
|
||||
response.write('<script src="'+resource+'?res=xhr-spec-compliant"></script>');
|
||||
return;
|
||||
}
|
||||
}
|
@ -1,128 +0,0 @@
|
||||
// SJS file to serve resources for CSP redirect tests
|
||||
// This file mimics serving resources, e.g. fonts, images, etc., which a CSP
|
||||
// can include. The resource may redirect to a different resource, if specified.
|
||||
function handleRequest(request, response)
|
||||
{
|
||||
var query = {};
|
||||
request.queryString.split('&').forEach(function (val) {
|
||||
var [name, value] = val.split('=');
|
||||
query[name] = unescape(value);
|
||||
});
|
||||
|
||||
var thisSite = "http://mochi.test:8888";
|
||||
var otherSite = "http://example.com";
|
||||
var resource = "/tests/content/base/test/csp/file_csp_redirects_resource.sjs";
|
||||
|
||||
response.setHeader("Cache-Control", "no-cache", false);
|
||||
|
||||
// redirect to a resource on this site
|
||||
if (query["redir"] == "same") {
|
||||
var loc = thisSite+resource+"?res="+query["res"]+"&testid="+query["id"];
|
||||
response.setStatusLine("1.1", 302, "Found");
|
||||
response.setHeader("Location", loc, false);
|
||||
return;
|
||||
}
|
||||
|
||||
// redirect to a resource on a different site
|
||||
else if (query["redir"] == "other") {
|
||||
var loc = otherSite+resource+"?res="+query["res"]+"&testid="+query["id"];
|
||||
response.setStatusLine("1.1", 302, "Found");
|
||||
response.setHeader("Location", loc, false);
|
||||
return;
|
||||
}
|
||||
|
||||
// not a redirect. serve some content.
|
||||
// the content doesn't have to be valid, since we're only checking whether
|
||||
// the request for the content was sent or not.
|
||||
|
||||
// downloadable font
|
||||
if (query["res"] == "font") {
|
||||
response.setHeader("Access-Control-Allow-Origin", "*", false);
|
||||
response.setHeader("Content-Type", "text/plain", false);
|
||||
response.write("font data...");
|
||||
return;
|
||||
}
|
||||
|
||||
if (query["res"] == "font-spec-compliant") {
|
||||
response.setHeader("Access-Control-Allow-Origin", "*", false);
|
||||
response.setHeader("Content-Type", "text/plain", false);
|
||||
response.write("font data...");
|
||||
return;
|
||||
}
|
||||
|
||||
// iframe with arbitrary content
|
||||
if (query["res"] == "iframe") {
|
||||
response.setHeader("Content-Type", "text/html", false);
|
||||
response.write("iframe content...");
|
||||
return;
|
||||
}
|
||||
|
||||
// image
|
||||
if (query["res"] == "image") {
|
||||
response.setHeader("Content-Type", "image/gif", false);
|
||||
response.write("image data...");
|
||||
return;
|
||||
}
|
||||
|
||||
// media content, e.g. Ogg video
|
||||
if (query["res"] == "media") {
|
||||
response.setHeader("Content-Type", "video/ogg", false);
|
||||
response.write("video data...");
|
||||
return;
|
||||
}
|
||||
|
||||
// plugin content, e.g. <object>
|
||||
if (query["res"] == "object") {
|
||||
response.setHeader("Content-Type", "text/html", false);
|
||||
response.write("object data...");
|
||||
return;
|
||||
}
|
||||
|
||||
// script
|
||||
if (query["res"] == "script") {
|
||||
response.setHeader("Content-Type", "application/javascript", false);
|
||||
response.write("some script...");
|
||||
return;
|
||||
}
|
||||
|
||||
// external stylesheet
|
||||
if (query["res"] == "style") {
|
||||
response.setHeader("Content-Type", "text/css", false);
|
||||
response.write("css data...");
|
||||
return;
|
||||
}
|
||||
|
||||
// web worker resource
|
||||
if (query["res"] == "worker") {
|
||||
response.setHeader("Content-Type", "application/javascript", false);
|
||||
response.write("worker script data...");
|
||||
return;
|
||||
}
|
||||
|
||||
// script that invokes XHR
|
||||
if (query["res"] == "xhr") {
|
||||
response.setHeader("Content-Type", "text/html", false);
|
||||
var resp = 'var x = new XMLHttpRequest(); x.open("GET", "' + otherSite +
|
||||
resource+'?res=xhr-resp&testid=xhr-src-redir", false); ' +
|
||||
'x.send(null);';
|
||||
response.write(resp);
|
||||
return;
|
||||
}
|
||||
|
||||
if (query["res"] == "xhr-spec-compliant") {
|
||||
response.setHeader("Content-Type", "text/html", false);
|
||||
var resp = 'var x = new XMLHttpRequest(); x.open("GET", "' + otherSite +
|
||||
resource+'?res=xhr-resp-spec-compliant&testid=xhr-src-redir-spec-compliant", false); ' +
|
||||
'x.send(null);';
|
||||
response.write(resp);
|
||||
return;
|
||||
}
|
||||
|
||||
// response to XHR
|
||||
if (query["res"] == "xhr-resp-spec-compliant") {
|
||||
response.setHeader("Access-Control-Allow-Origin", "*", false);
|
||||
response.setHeader("Content-Type", "text/html", false);
|
||||
response.write('XHR response...');
|
||||
return;
|
||||
}
|
||||
}
|
@ -1,25 +0,0 @@
|
||||
// SJS file for CSP violation report test
|
||||
// https://bugzilla.mozilla.org/show_bug.cgi?id=548193
|
||||
function handleRequest(request, response)
|
||||
{
|
||||
var query = {};
|
||||
request.queryString.split('&').forEach(function (val) {
|
||||
var [name, value] = val.split('=');
|
||||
query[name] = unescape(value);
|
||||
});
|
||||
|
||||
response.setHeader("Content-Type", "text/html", false);
|
||||
|
||||
// avoid confusing cache behaviors
|
||||
response.setHeader("Cache-Control", "no-cache", false);
|
||||
|
||||
// set CSP header
|
||||
response.setHeader("X-Content-Security-Policy",
|
||||
"allow 'self'; report-uri http://mochi.test:8888/csp-report.cgi",
|
||||
false);
|
||||
|
||||
// content which will trigger a violation report
|
||||
response.write('<html><body>');
|
||||
response.write('<img src="http://example.org/tests/content/base/test/file_CSP.sjs?testid=img_bad&type=img/png"> </img>');
|
||||
response.write('</body></html>');
|
||||
}
|
@ -1,2 +0,0 @@
|
||||
Content-Security-Policy: default-src 'self' 'unsafe-inline';
|
||||
X-Content-Security-Policy: allow 'self' 'inline-script';
|
@ -1,15 +0,0 @@
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=717511
|
||||
-->
|
||||
<body>
|
||||
<!-- these should be stopped by CSP after fixing bug 717511. :) -->
|
||||
<img src="http://example.org/tests/content/base/test/file_CSP.sjs?testid=img_bad&type=img/png"> </img>
|
||||
<script src='http://example.org/tests/content/base/test/file_CSP.sjs?testid=script_bad&type=text/javascript'></script>
|
||||
|
||||
<!-- these should load ok after fixing bug 717511. :) -->
|
||||
<img src="file_CSP.sjs?testid=img_good&type=img/png" />
|
||||
<script src='file_CSP.sjs?testid=script_good&type=text/javascript'></script>
|
||||
|
||||
</body>
|
||||
</html>
|
@ -1 +0,0 @@
|
||||
X-Content-Security-Policy: default-src 'self', allow *
|
@ -1,15 +0,0 @@
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=717511
|
||||
-->
|
||||
<body>
|
||||
<!-- these should be stopped by CSP after fixing bug 717511. :) -->
|
||||
<img src="http://example.org/tests/content/base/test/file_CSP.sjs?testid=img2_bad&type=img/png"> </img>
|
||||
<script src='http://example.org/tests/content/base/test/file_CSP.sjs?testid=script2_bad&type=text/javascript'></script>
|
||||
|
||||
<!-- these should load ok after fixing bug 717511. :) -->
|
||||
<img src="file_CSP.sjs?testid=img2_good&type=img/png" />
|
||||
<script src='file_CSP.sjs?testid=script2_good&type=text/javascript'></script>
|
||||
|
||||
</body>
|
||||
</html>
|
@ -1 +0,0 @@
|
||||
X-Content-Security-Policy: default-src 'self' , allow *
|
@ -1,5 +0,0 @@
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=558431
|
||||
-->
|
||||
<iframe id="inner"
|
||||
src="/tests/content/base/test/file_CSP.sjs?content=%3Cdiv%20id%3D%22test%22%3Etest%20558431%3C/div%3E"></iframe>
|
@ -1 +0,0 @@
|
||||
X-Content-Security-Policy: invalid-uri
|
@ -1,38 +0,0 @@
|
||||
// https://bugzilla.mozilla.org/show_bug.cgi?id=650386
|
||||
// This SJS file serves file_redirect_content.html
|
||||
// with a CSP that will trigger a violation and that will report it
|
||||
// to file_redirect_report.sjs
|
||||
//
|
||||
// This handles 301, 302, 303 and 307 redirects. The HTTP status code
|
||||
// returned/type of redirect to do comes from the query string
|
||||
// parameter passed in from the test_bug650386_* files and then also
|
||||
// uses that value in the report-uri parameter of the CSP
|
||||
function handleRequest(request, response) {
|
||||
response.setHeader("Cache-Control", "no-cache", false);
|
||||
|
||||
// this gets used in the CSP as part of the report URI.
|
||||
var redirect = request.queryString;
|
||||
|
||||
if (redirect < 301 || (redirect > 303 && redirect <= 306) || redirect > 307) {
|
||||
// if we somehow got some bogus redirect code here,
|
||||
// do a 302 redirect to the same URL as the report URI
|
||||
// redirects to - this will fail the test.
|
||||
var loc = "http://example.com/some/fake/path";
|
||||
response.setStatusLine("1.1", 302, "Found");
|
||||
response.setHeader("Location", loc, false);
|
||||
return;
|
||||
}
|
||||
|
||||
var csp = "default-src \'self\';report-uri http://mochi.test:8888/tests/content/base/test/csp/file_redirect_report.sjs?" + redirect;
|
||||
|
||||
response.setHeader("X-Content-Security-Policy", csp, false);
|
||||
|
||||
// the actual file content.
|
||||
// this image load will (intentionally) fail due to the CSP policy of default-src: 'self'
|
||||
// specified by the CSP string above.
|
||||
var content = "<!DOCTYPE HTML><html><body><img src = \"http://some.other.domain.example.com\"></body></html>";
|
||||
|
||||
response.write(content);
|
||||
|
||||
return;
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
// https://bugzilla.mozilla.org/show_bug.cgi?id=650386
|
||||
// This SJS file serves as CSP violation report target
|
||||
// and issues a redirect, to make sure the browser does not post to the target
|
||||
// of the redirect, per CSP spec.
|
||||
// This handles 301, 302, 303 and 307 redirects. The HTTP status code
|
||||
// returned/type of redirect to do comes from the query string
|
||||
// parameter
|
||||
function handleRequest(request, response) {
|
||||
response.setHeader("Cache-Control", "no-cache", false);
|
||||
|
||||
var redirect = request.queryString;
|
||||
|
||||
var loc = "http://example.com/some/fake/path";
|
||||
response.setStatusLine("1.1", redirect, "Found");
|
||||
response.setHeader("Location", loc, false);
|
||||
return;
|
||||
}
|
@ -1,13 +0,0 @@
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=702439
|
||||
|
||||
This document is a child frame of a CSP document and the
|
||||
test verifies that it is permitted to run javascript: URLs
|
||||
if the parent has a policy that allows them.
|
||||
-->
|
||||
<body onload="document.getElementById('a').click()">
|
||||
<a id="a" href="javascript:parent.javascript_link_ran = true;
|
||||
parent.checkResult();">click</a>
|
||||
</body>
|
||||
</html>
|
@ -1 +0,0 @@
|
||||
X-Content-Security-Policy: default-src *; options inline-script
|
@ -1,69 +0,0 @@
|
||||
[DEFAULT]
|
||||
support-files =
|
||||
file_CSP.css
|
||||
file_CSP.sjs
|
||||
file_CSP_bug916446.html
|
||||
file_CSP_bug916446.html^headers^
|
||||
file_CSP_evalscript_main.html
|
||||
file_CSP_evalscript_main.html^headers^
|
||||
file_CSP_evalscript_main.js
|
||||
file_CSP_evalscript_main_getCRMFRequest.html
|
||||
file_CSP_evalscript_main_getCRMFRequest.html^headers^
|
||||
file_CSP_evalscript_main_getCRMFRequest.js
|
||||
file_CSP_evalscript_no_CSP_at_all.html
|
||||
file_CSP_evalscript_no_CSP_at_all.html^headers^
|
||||
file_CSP_evalscript_no_CSP_at_all.js
|
||||
file_CSP_frameancestors.sjs
|
||||
file_CSP_frameancestors_main.html
|
||||
file_CSP_frameancestors_main.js
|
||||
file_CSP_inlinescript_main.html
|
||||
file_CSP_inlinescript_main.html^headers^
|
||||
file_CSP_inlinestyle_main.html
|
||||
file_CSP_inlinestyle_main.html^headers^
|
||||
file_CSP_main.html
|
||||
file_CSP_main.html^headers^
|
||||
file_CSP_main.js
|
||||
file_bothCSPheaders.html
|
||||
file_bothCSPheaders.html^headers^
|
||||
file_csp_bug768029.html
|
||||
file_csp_bug768029.sjs
|
||||
file_csp_bug773891.html
|
||||
file_csp_bug773891.sjs
|
||||
file_csp_redirects_main.html
|
||||
file_csp_redirects_page.sjs
|
||||
file_csp_redirects_resource.sjs
|
||||
file_dual_headers_warning.html
|
||||
file_dual_headers_warning.html^headers^
|
||||
file_csp_report.sjs
|
||||
file_policyuri_async_fetch.html
|
||||
file_policyuri_async_fetch.html^headers^
|
||||
file_redirect_content.sjs
|
||||
file_redirect_report.sjs
|
||||
file_subframe_run_js_if_allowed.html
|
||||
file_subframe_run_js_if_allowed.html^headers^
|
||||
file_multi_policy_injection_bypass.html
|
||||
file_multi_policy_injection_bypass.html^headers^
|
||||
file_multi_policy_injection_bypass_2.html
|
||||
file_multi_policy_injection_bypass_2.html^headers^
|
||||
|
||||
[test_CSP.html]
|
||||
[test_CSP_bug916446.html]
|
||||
[test_CSP_evalscript.html]
|
||||
[test_CSP_evalscript_getCRMFRequest.html]
|
||||
skip-if = buildapp == 'b2g' || toolkit == 'android' || e10s # no (deprecated) window.crypto support in multiprocess (bug 824652)
|
||||
[test_CSP_frameancestors.html]
|
||||
skip-if = (buildapp == 'b2g' && (toolkit != 'gonk' || debug)) || toolkit == 'android' # Times out, not sure why (bug 1008445)
|
||||
[test_CSP_inlinescript.html]
|
||||
[test_CSP_inlinestyle.html]
|
||||
[test_bothCSPheaders.html]
|
||||
[test_csp_redirects.html]
|
||||
[test_dual_headers_warning.html]
|
||||
[test_csp_report.html]
|
||||
skip-if = e10s || buildapp == 'b2g' # http-on-opening-request observer not supported in child process (bug 1009632)
|
||||
[test_policyuri_async_fetch.html]
|
||||
[test_301_redirect.html]
|
||||
[test_302_redirect.html]
|
||||
[test_303_redirect.html]
|
||||
[test_307_redirect.html]
|
||||
[test_subframe_run_js_if_allowed.html]
|
||||
[test_multi_policy_injection_bypass.html]
|
@ -1,73 +0,0 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=650386
|
||||
Test that CSP violation reports are not sent when a 301 redirect is encountered
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 650386</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=650386">Mozilla Bug 650386</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
<iframe id = "content_iframe"></iframe>
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
|
||||
/** Test for Bug 650386 **/
|
||||
|
||||
// This is used to watch the redirect of the report POST get blocked
|
||||
function examiner() {
|
||||
SpecialPowers.addObserver(this, "csp-on-violate-policy", false);
|
||||
SpecialPowers.addObserver(this, "specialpowers-http-notify-request", false);
|
||||
}
|
||||
|
||||
examiner.prototype = {
|
||||
observe: function(subject, topic, data) {
|
||||
if (topic === "specialpowers-http-notify-request") {
|
||||
// this is used to fail the test - if we see the POST to the target of the redirect
|
||||
// we know this is a fail
|
||||
var uri = data;
|
||||
if (uri == "http://example.com/some/fake/path")
|
||||
window.done(false);
|
||||
}
|
||||
|
||||
if(topic === "csp-on-violate-policy") {
|
||||
// something was blocked, but we are looking specifically for the redirect being blocked
|
||||
if (data == "denied redirect while sending violation report")
|
||||
window.done(true);
|
||||
}
|
||||
},
|
||||
|
||||
// must eventually call this to remove the listener,
|
||||
// or mochitests might get borked.
|
||||
remove: function() {
|
||||
SpecialPowers.removeObserver(this, "csp-on-violate-policy");
|
||||
SpecialPowers.removeObserver(this, "specialpowers-http-notify-request");
|
||||
}
|
||||
}
|
||||
|
||||
window.examiner = new examiner();
|
||||
|
||||
// result == true if we saw the redirect blocked notify, false if we saw the post
|
||||
// to the redirect target go out
|
||||
window.done = function(result) {
|
||||
ok(result, "a 301 redirect when posting violation report should be blocked");
|
||||
|
||||
// clean up observers and finish the test
|
||||
window.examiner.remove();
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
// save this for last so that our listeners are registered.
|
||||
document.getElementById('content_iframe').src = 'file_redirect_content.sjs?301';
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
@ -1,73 +0,0 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=650386
|
||||
Test that CSP violation reports are not sent when a 302 redirect is encountered
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 650386</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=650386">Mozilla Bug 650386</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
<iframe id = "content_iframe"></iframe>
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
|
||||
/** Test for Bug 650386 **/
|
||||
|
||||
// This is used to watch the redirect of the report POST get blocked
|
||||
function examiner() {
|
||||
SpecialPowers.addObserver(this, "csp-on-violate-policy", false);
|
||||
SpecialPowers.addObserver(this, "specialpowers-http-notify-request", false);
|
||||
}
|
||||
|
||||
examiner.prototype = {
|
||||
observe: function(subject, topic, data) {
|
||||
if (topic === "specialpowers-http-notify-request") {
|
||||
// this is used to fail the test - if we see the POST to the target of the redirect
|
||||
// we know this is a fail
|
||||
var uri = data;
|
||||
if (uri == "http://example.com/some/fake/path")
|
||||
window.done(false);
|
||||
}
|
||||
|
||||
if(topic === "csp-on-violate-policy") {
|
||||
// something was blocked, but we are looking specifically for the redirect being blocked
|
||||
if (data == "denied redirect while sending violation report")
|
||||
window.done(true);
|
||||
}
|
||||
},
|
||||
|
||||
// must eventually call this to remove the listener,
|
||||
// or mochitests might get borked.
|
||||
remove: function() {
|
||||
SpecialPowers.removeObserver(this, "csp-on-violate-policy");
|
||||
SpecialPowers.removeObserver(this, "specialpowers-http-notify-request");
|
||||
}
|
||||
}
|
||||
|
||||
window.examiner = new examiner();
|
||||
|
||||
// result == true if we saw the redirect blocked notify, false if we saw the post
|
||||
// to the redirect target go out
|
||||
window.done = function(result) {
|
||||
ok(result, "a 302 redirect when posting violation report should be blocked");
|
||||
|
||||
// clean up observers and finish the test
|
||||
window.examiner.remove();
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
// save this for last so that our listeners are registered.
|
||||
document.getElementById('content_iframe').src = 'file_redirect_content.sjs?302';
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
@ -1,73 +0,0 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=650386
|
||||
Test that CSP violation reports are not sent when a 303 redirect is encountered
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 650386</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=650386">Mozilla Bug 650386</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
<iframe id = "content_iframe"></iframe>
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
|
||||
/** Test for Bug 650386 **/
|
||||
|
||||
// This is used to watch the redirect of the report POST get blocked
|
||||
function examiner() {
|
||||
SpecialPowers.addObserver(this, "csp-on-violate-policy", false);
|
||||
SpecialPowers.addObserver(this, "specialpowers-http-notify-request", false);
|
||||
}
|
||||
|
||||
examiner.prototype = {
|
||||
observe: function(subject, topic, data) {
|
||||
if (topic === "specialpowers-http-notify-request") {
|
||||
// this is used to fail the test - if we see the POST to the target of the redirect
|
||||
// we know this is a fail
|
||||
var uri = data;
|
||||
if (uri == "http://example.com/some/fake/path")
|
||||
window.done(false);
|
||||
}
|
||||
|
||||
if(topic === "csp-on-violate-policy") {
|
||||
// something was blocked, but we are looking specifically for the redirect being blocked
|
||||
if (data == "denied redirect while sending violation report")
|
||||
window.done(true);
|
||||
}
|
||||
},
|
||||
|
||||
// must eventually call this to remove the listener,
|
||||
// or mochitests might get borked.
|
||||
remove: function() {
|
||||
SpecialPowers.removeObserver(this, "csp-on-violate-policy");
|
||||
SpecialPowers.removeObserver(this, "specialpowers-http-notify-request");
|
||||
}
|
||||
}
|
||||
|
||||
window.examiner = new examiner();
|
||||
|
||||
// result == true if we saw the redirect blocked notify, false if we saw the post
|
||||
// to the redirect target go out
|
||||
window.done = function(result) {
|
||||
ok(result, "a 303 redirect when posting violation report should be blocked");
|
||||
|
||||
// clean up observers and finish the test
|
||||
window.examiner.remove();
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
// save this for last so that our listeners are registered.
|
||||
document.getElementById('content_iframe').src = 'file_redirect_content.sjs?303';
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
@ -1,73 +0,0 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=650386
|
||||
Test that CSP violation reports are not sent when a 307 redirect is encountered
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 650386</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=650386">Mozilla Bug 650386</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
<iframe id = "content_iframe"></iframe>
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
|
||||
/** Test for Bug 650386 **/
|
||||
|
||||
// This is used to watch the redirect of the report POST get blocked
|
||||
function examiner() {
|
||||
SpecialPowers.addObserver(this, "csp-on-violate-policy", false);
|
||||
SpecialPowers.addObserver(this, "specialpowers-http-notify-request", false);
|
||||
}
|
||||
|
||||
examiner.prototype = {
|
||||
observe: function(subject, topic, data) {
|
||||
if (topic === "specialpowers-http-notify-request") {
|
||||
// this is used to fail the test - if we see the POST to the target of the redirect
|
||||
// we know this is a fail
|
||||
var uri = data;
|
||||
if (uri == "http://example.com/some/fake/path")
|
||||
window.done(false);
|
||||
}
|
||||
|
||||
if(topic === "csp-on-violate-policy") {
|
||||
// something was blocked, but we are looking specifically for the redirect being blocked
|
||||
if (data == "denied redirect while sending violation report")
|
||||
window.done(true);
|
||||
}
|
||||
},
|
||||
|
||||
// must eventually call this to remove the listener,
|
||||
// or mochitests might get borked.
|
||||
remove: function() {
|
||||
SpecialPowers.removeObserver(this, "csp-on-violate-policy");
|
||||
SpecialPowers.removeObserver(this, "specialpowers-http-notify-request");
|
||||
}
|
||||
}
|
||||
|
||||
window.examiner = new examiner();
|
||||
|
||||
// result == true if we saw the redirect blocked notify, false if we saw the post
|
||||
// to the redirect target go out
|
||||
window.done = function(result) {
|
||||
ok(result, "a 307 redirect when posting violation report should be blocked");
|
||||
|
||||
// clean up observers and finish the test
|
||||
window.examiner.remove();
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
// save this for last so that our listeners are registered.
|
||||
document.getElementById('content_iframe').src = 'file_redirect_content.sjs?307';
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
@ -1,119 +0,0 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Test for Content Security Policy Connections</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"></p>
|
||||
<div id="content" style="display: none">
|
||||
</div>
|
||||
<iframe style="width:200px;height:200px;" id='cspframe'></iframe>
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
// These are test results: -1 means it hasn't run,
|
||||
// true/false is the pass/fail result.
|
||||
window.tests = {
|
||||
img_good: -1,
|
||||
img_bad: -1,
|
||||
style_good: -1,
|
||||
style_bad: -1,
|
||||
frame_good: -1,
|
||||
frame_bad: -1,
|
||||
script_good: -1,
|
||||
script_bad: -1,
|
||||
xhr_good: -1,
|
||||
xhr_bad: -1,
|
||||
media_good: -1,
|
||||
media_bad: -1,
|
||||
font_good: -1,
|
||||
font_bad: -1,
|
||||
object_good: -1,
|
||||
object_bad: -1,
|
||||
};
|
||||
|
||||
// This is used to watch the blocked data bounce off CSP and allowed data
|
||||
// get sent out to the wire.
|
||||
function examiner() {
|
||||
SpecialPowers.addObserver(this, "csp-on-violate-policy", false);
|
||||
SpecialPowers.addObserver(this, "specialpowers-http-notify-request", false);
|
||||
}
|
||||
examiner.prototype = {
|
||||
observe: function(subject, topic, data) {
|
||||
var testpat = new RegExp("testid=([a-z0-9_]+)");
|
||||
|
||||
//_good things better be allowed!
|
||||
//_bad things better be stopped!
|
||||
|
||||
// This is a special observer topic that is proxied from
|
||||
// http-on-modify-request in the parent process to inform us when a URI is
|
||||
// loaded
|
||||
if (topic === "specialpowers-http-notify-request") {
|
||||
var uri = data;
|
||||
if (!testpat.test(uri)) return;
|
||||
var testid = testpat.exec(uri)[1];
|
||||
|
||||
window.testResult(testid,
|
||||
/_good/.test(testid),
|
||||
uri + " allowed by csp");
|
||||
}
|
||||
|
||||
if (topic === "csp-on-violate-policy") {
|
||||
// these were blocked... record that they were blocked
|
||||
var asciiSpec = SpecialPowers.getPrivilegedProps(SpecialPowers.do_QueryInterface(subject, "nsIURI"), "asciiSpec");
|
||||
if (!testpat.test(asciiSpec)) return;
|
||||
var testid = testpat.exec(asciiSpec)[1];
|
||||
window.testResult(testid,
|
||||
/_bad/.test(testid),
|
||||
asciiSpec + " blocked by \"" + data + "\"");
|
||||
}
|
||||
},
|
||||
|
||||
// must eventually call this to remove the listener,
|
||||
// or mochitests might get borked.
|
||||
remove: function() {
|
||||
SpecialPowers.removeObserver(this, "csp-on-violate-policy");
|
||||
SpecialPowers.removeObserver(this, "specialpowers-http-notify-request");
|
||||
}
|
||||
}
|
||||
|
||||
window.examiner = new examiner();
|
||||
|
||||
window.testResult = function(testname, result, msg) {
|
||||
//test already complete.... forget it... remember the first result.
|
||||
if (window.tests[testname] != -1)
|
||||
return;
|
||||
|
||||
window.tests[testname] = result;
|
||||
is(result, true, testname + ' test: ' + msg);
|
||||
|
||||
// if any test is incomplete, keep waiting
|
||||
for (var v in window.tests)
|
||||
if(tests[v] == -1)
|
||||
return;
|
||||
|
||||
// ... otherwise, finish
|
||||
window.examiner.remove();
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
SpecialPowers.pushPrefEnv(
|
||||
{'set':[["security.csp.speccompliant", true],
|
||||
// This defaults to 0 ("preload none") on mobile (B2G/Android), which
|
||||
// blocks loading the resource until the user interacts with a
|
||||
// corresponding widget, which breaks the media_* tests. We set it
|
||||
// back to the default used by desktop Firefox to get consistent
|
||||
// behavior.
|
||||
["media.preload.default", 2]]},
|
||||
function() {
|
||||
// save this for last so that our listeners are registered.
|
||||
// ... this loads the testbed of good and bad requests.
|
||||
document.getElementById('cspframe').src = 'file_CSP_main.html';
|
||||
});
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user