diff --git a/content/base/test/xcsp/chrome.ini b/content/base/test/xcsp/chrome.ini new file mode 100644 index 00000000000..fb55f3e1272 --- /dev/null +++ b/content/base/test/xcsp/chrome.ini @@ -0,0 +1,4 @@ +[DEFAULT] + +[test_csp_bug768029.html] +[test_csp_bug773891.html] diff --git a/content/base/test/xcsp/file_CSP.css b/content/base/test/xcsp/file_CSP.css new file mode 100644 index 00000000000..f83930e541c --- /dev/null +++ b/content/base/test/xcsp/file_CSP.css @@ -0,0 +1,20 @@ +/* + * Moved this CSS from an inline stylesheet to an external file when we added + * inline-style blocking in bug 763879. + * This test may hang if the load for this .css file is blocked due to a + * malfunction of CSP, but should pass if the style_good test passes. + */ + +/* CSS font embedding tests */ +@font-face { + font-family: "arbitrary_good"; + src: url('file_CSP.sjs?testid=font_good&type=application/octet-stream'); +} +@font-face { + font-family: "arbitrary_bad"; + src: url('http://example.org/tests/content/base/test/csp/file_CSP.sjs?testid=font_bad&type=application/octet-stream'); +} + +.div_arbitrary_good { font-family: "arbitrary_good"; } +.div_arbitrary_bad { font-family: "arbitrary_bad"; } + diff --git a/content/base/test/xcsp/file_CSP.sjs b/content/base/test/xcsp/file_CSP.sjs new file mode 100644 index 00000000000..85c2df3ba47 --- /dev/null +++ b/content/base/test/xcsp/file_CSP.sjs @@ -0,0 +1,26 @@ +// SJS file for CSP mochitests + +function handleRequest(request, response) +{ + var query = {}; + request.queryString.split('&').forEach(function (val) { + var [name, value] = val.split('='); + query[name] = unescape(value); + }); + + var isPreflight = request.method == "OPTIONS"; + + + //avoid confusing cache behaviors + response.setHeader("Cache-Control", "no-cache", false); + + if ("type" in query) { + response.setHeader("Content-Type", unescape(query['type']), false); + } else { + response.setHeader("Content-Type", "text/html", false); + } + + if ("content" in query) { + response.write(unescape(query['content'])); + } +} diff --git a/content/base/test/xcsp/file_CSP_evalscript_main.js b/content/base/test/xcsp/file_CSP_evalscript_main.js new file mode 100644 index 00000000000..a00fbb8362e --- /dev/null +++ b/content/base/test/xcsp/file_CSP_evalscript_main.js @@ -0,0 +1,126 @@ +// 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); + + + diff --git a/content/base/test/xcsp/file_CSP_evalscript_main_getCRMFRequest.html b/content/base/test/xcsp/file_CSP_evalscript_main_getCRMFRequest.html new file mode 100644 index 00000000000..7b122389be5 --- /dev/null +++ b/content/base/test/xcsp/file_CSP_evalscript_main_getCRMFRequest.html @@ -0,0 +1,12 @@ + + + CSP eval script tests + + + + + Foo. + + + diff --git a/content/base/test/xcsp/file_CSP_evalscript_main_getCRMFRequest.html^headers^ b/content/base/test/xcsp/file_CSP_evalscript_main_getCRMFRequest.html^headers^ new file mode 100644 index 00000000000..a9c761cfc14 --- /dev/null +++ b/content/base/test/xcsp/file_CSP_evalscript_main_getCRMFRequest.html^headers^ @@ -0,0 +1,2 @@ +Cache-Control: no-cache +X-Content-Security-Policy: default-src 'self' diff --git a/content/base/test/xcsp/file_CSP_evalscript_main_getCRMFRequest.js b/content/base/test/xcsp/file_CSP_evalscript_main_getCRMFRequest.js new file mode 100644 index 00000000000..90826e3bc9d --- /dev/null +++ b/content/base/test/xcsp/file_CSP_evalscript_main_getCRMFRequest.js @@ -0,0 +1,48 @@ +// 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); + + + diff --git a/content/base/test/xcsp/file_CSP_evalscript_no_CSP_at_all.html b/content/base/test/xcsp/file_CSP_evalscript_no_CSP_at_all.html new file mode 100644 index 00000000000..d36aeaaf106 --- /dev/null +++ b/content/base/test/xcsp/file_CSP_evalscript_no_CSP_at_all.html @@ -0,0 +1,12 @@ + + + CSP eval script tests: no CSP specified + + + + + Foo. See bug 824652 + + + diff --git a/content/base/test/xcsp/file_CSP_evalscript_no_CSP_at_all.html^headers^ b/content/base/test/xcsp/file_CSP_evalscript_no_CSP_at_all.html^headers^ new file mode 100644 index 00000000000..9e23c73b7ff --- /dev/null +++ b/content/base/test/xcsp/file_CSP_evalscript_no_CSP_at_all.html^headers^ @@ -0,0 +1 @@ +Cache-Control: no-cache diff --git a/content/base/test/xcsp/file_CSP_evalscript_no_CSP_at_all.js b/content/base/test/xcsp/file_CSP_evalscript_no_CSP_at_all.js new file mode 100644 index 00000000000..520491fb8ef --- /dev/null +++ b/content/base/test/xcsp/file_CSP_evalscript_no_CSP_at_all.js @@ -0,0 +1,42 @@ +// 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); diff --git a/content/base/test/xcsp/file_csp_bug768029.html b/content/base/test/xcsp/file_csp_bug768029.html new file mode 100644 index 00000000000..d7f2730e6c7 --- /dev/null +++ b/content/base/test/xcsp/file_csp_bug768029.html @@ -0,0 +1,25 @@ + + + + + + This is an app for testing + + + + + + + + + + + + Test for CSP applied to (simulated) app. + + + diff --git a/content/base/test/xcsp/file_csp_bug768029.sjs b/content/base/test/xcsp/file_csp_bug768029.sjs new file mode 100644 index 00000000000..9ae353055ef --- /dev/null +++ b/content/base/test/xcsp/file_csp_bug768029.sjs @@ -0,0 +1,29 @@ +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('
script loaded\\n
');\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!"); +} diff --git a/content/base/test/xcsp/file_csp_bug773891.html b/content/base/test/xcsp/file_csp_bug773891.html new file mode 100644 index 00000000000..563e5f1699c --- /dev/null +++ b/content/base/test/xcsp/file_csp_bug773891.html @@ -0,0 +1,25 @@ + + + + + + This is an app for csp testing + + + + + + + + + + + + Test for CSP applied to (simulated) app. + + + diff --git a/content/base/test/xcsp/file_csp_bug773891.sjs b/content/base/test/xcsp/file_csp_bug773891.sjs new file mode 100644 index 00000000000..9ae353055ef --- /dev/null +++ b/content/base/test/xcsp/file_csp_bug773891.sjs @@ -0,0 +1,29 @@ +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('
script loaded\\n
');\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!"); +} diff --git a/content/base/test/xcsp/file_csp_redirects_main.html b/content/base/test/xcsp/file_csp_redirects_main.html new file mode 100644 index 00000000000..102f7469282 --- /dev/null +++ b/content/base/test/xcsp/file_csp_redirects_main.html @@ -0,0 +1,44 @@ + + +CSP redirect tests + + +
+ + + + diff --git a/content/base/test/xcsp/file_csp_redirects_page.sjs b/content/base/test/xcsp/file_csp_redirects_page.sjs new file mode 100644 index 00000000000..7f5d6bad41e --- /dev/null +++ b/content/base/test/xcsp/file_csp_redirects_page.sjs @@ -0,0 +1,133 @@ +// 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 = '' + + '
test
'; + response.write(resp); + return; + } + + if (query["testid"] == "font-src-spec-compliant") { + var resp = '' + + '
test
'; + response.write(resp); + return; + } + + // iframe that redirects to another site + if (query["testid"] == "frame-src") { + response.write(''); + return; + } + + if (query["testid"] == "frame-src-spec-compliant") { + response.write(''); + return; + } + + // image that redirects to another site + if (query["testid"] == "img-src") { + response.write(''); + return; + } + + if (query["testid"] == "img-src-spec-compliant") { + response.write(''); + return; + } + + // video content that redirects to another site + if (query["testid"] == "media-src") { + response.write(''); + return; + } + + if (query["testid"] == "media-src-spec-compliant") { + response.write(''); + return; + } + + // object content that redirects to another site + if (query["testid"] == "object-src") { + response.write(''); + return; + } + + if (query["testid"] == "object-src-spec-compliant") { + response.write(''); + return; + } + + // external script that redirects to another site + if (query["testid"] == "script-src") { + response.write(''); + return; + } + + if (query["testid"] == "script-src-spec-compliant") { + response.write(''); + return; + } + + // external stylesheet that redirects to another site + if (query["testid"] == "style-src") { + response.write(''); + return; + } + + if (query["testid"] == "style-src-spec-compliant") { + response.write(''); + return; + } + + // worker script resource that redirects to another site + if (query["testid"] == "worker") { + response.write(''); + return; + } + + if (query["testid"] == "worker-spec-compliant") { + response.write(''); + return; + } + + // script that XHR's to a resource that redirects to another site + if (query["testid"] == "xhr-src") { + response.write(''); + return; + } + + if (query["testid"] == "xhr-src-spec-compliant") { + response.write(''); + return; + } +} diff --git a/content/base/test/xcsp/file_csp_redirects_resource.sjs b/content/base/test/xcsp/file_csp_redirects_resource.sjs new file mode 100644 index 00000000000..60924ee09da --- /dev/null +++ b/content/base/test/xcsp/file_csp_redirects_resource.sjs @@ -0,0 +1,128 @@ +// 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. + 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; + } +} diff --git a/content/base/test/xcsp/file_csp_report.sjs b/content/base/test/xcsp/file_csp_report.sjs new file mode 100644 index 00000000000..baf88b02d4a --- /dev/null +++ b/content/base/test/xcsp/file_csp_report.sjs @@ -0,0 +1,25 @@ +// 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(''); + response.write(' '); + response.write(''); +} diff --git a/content/base/test/xcsp/file_multi_policy_injection_bypass.html b/content/base/test/xcsp/file_multi_policy_injection_bypass.html new file mode 100644 index 00000000000..82eed84570a --- /dev/null +++ b/content/base/test/xcsp/file_multi_policy_injection_bypass.html @@ -0,0 +1,15 @@ + + + + + + + + + + + + + diff --git a/content/base/test/xcsp/file_multi_policy_injection_bypass.html^headers^ b/content/base/test/xcsp/file_multi_policy_injection_bypass.html^headers^ new file mode 100644 index 00000000000..fc46a167c3d --- /dev/null +++ b/content/base/test/xcsp/file_multi_policy_injection_bypass.html^headers^ @@ -0,0 +1 @@ +X-Content-Security-Policy: default-src 'self', allow * diff --git a/content/base/test/xcsp/file_multi_policy_injection_bypass_2.html b/content/base/test/xcsp/file_multi_policy_injection_bypass_2.html new file mode 100644 index 00000000000..6f27a043fb8 --- /dev/null +++ b/content/base/test/xcsp/file_multi_policy_injection_bypass_2.html @@ -0,0 +1,15 @@ + + + + + + + + + + + + + diff --git a/content/base/test/xcsp/file_multi_policy_injection_bypass_2.html^headers^ b/content/base/test/xcsp/file_multi_policy_injection_bypass_2.html^headers^ new file mode 100644 index 00000000000..772246e1247 --- /dev/null +++ b/content/base/test/xcsp/file_multi_policy_injection_bypass_2.html^headers^ @@ -0,0 +1 @@ +X-Content-Security-Policy: default-src 'self' , allow * diff --git a/content/base/test/xcsp/file_redirect_content.sjs b/content/base/test/xcsp/file_redirect_content.sjs new file mode 100644 index 00000000000..9a6461d69bb --- /dev/null +++ b/content/base/test/xcsp/file_redirect_content.sjs @@ -0,0 +1,38 @@ +// 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 = ""; + + response.write(content); + + return; +} diff --git a/content/base/test/xcsp/file_redirect_report.sjs b/content/base/test/xcsp/file_redirect_report.sjs new file mode 100644 index 00000000000..9cc7e654863 --- /dev/null +++ b/content/base/test/xcsp/file_redirect_report.sjs @@ -0,0 +1,17 @@ +// 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; +} diff --git a/content/base/test/xcsp/file_subframe_run_js_if_allowed.html b/content/base/test/xcsp/file_subframe_run_js_if_allowed.html new file mode 100644 index 00000000000..3ba970ce846 --- /dev/null +++ b/content/base/test/xcsp/file_subframe_run_js_if_allowed.html @@ -0,0 +1,13 @@ + + + +click + + diff --git a/content/base/test/xcsp/file_subframe_run_js_if_allowed.html^headers^ b/content/base/test/xcsp/file_subframe_run_js_if_allowed.html^headers^ new file mode 100644 index 00000000000..426d8738c60 --- /dev/null +++ b/content/base/test/xcsp/file_subframe_run_js_if_allowed.html^headers^ @@ -0,0 +1 @@ +X-Content-Security-Policy: default-src *; options inline-script diff --git a/content/base/test/xcsp/mochitest.ini b/content/base/test/xcsp/mochitest.ini new file mode 100644 index 00000000000..7fdf90e83b5 --- /dev/null +++ b/content/base/test/xcsp/mochitest.ini @@ -0,0 +1,165 @@ +[DEFAULT] +support-files = + file_CSP.css + file_CSP.sjs + file_CSP_bug663567.xsl + file_CSP_bug663567_allows.xml + file_CSP_bug663567_allows.xml^headers^ + file_CSP_bug663567_blocks.xml + file_CSP_bug663567_blocks.xml^headers^ + file_CSP_bug802872.html + file_CSP_bug802872.html^headers^ + file_CSP_bug802872.js + file_CSP_bug802872.sjs + file_CSP_bug885433_allows.html + file_CSP_bug885433_allows.html^headers^ + file_CSP_bug885433_blocks.html + file_CSP_bug885433_blocks.html^headers^ + file_CSP_bug888172.html + file_CSP_bug888172.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_allowed.js + file_CSP_evalscript_main_allowed_getCRMFRequest.js + file_CSP_evalscript_main_getCRMFRequest.html + file_CSP_evalscript_main_getCRMFRequest.html^headers^ + file_CSP_evalscript_main_getCRMFRequest.js + file_CSP_evalscript_main_spec_compliant.html + file_CSP_evalscript_main_spec_compliant.html^headers^ + file_CSP_evalscript_main_spec_compliant_allowed.html + file_CSP_evalscript_main_spec_compliant_allowed.html^headers^ + file_CSP_evalscript_main_spec_compliant_allowed_getCRMFRequest.html + file_CSP_evalscript_main_spec_compliant_allowed_getCRMFRequest.html^headers^ + file_CSP_evalscript_main_spec_compliant_getCRMFRequest.html + file_CSP_evalscript_main_spec_compliant_getCRMFRequest.html^headers^ + 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_frameancestors_main_spec_compliant.html + file_CSP_frameancestors_main_spec_compliant.js + file_CSP_frameancestors_spec_compliant.sjs + file_CSP_inlinescript_main.html + file_CSP_inlinescript_main.html^headers^ + file_CSP_inlinescript_main_spec_compliant.html + file_CSP_inlinescript_main_spec_compliant.html^headers^ + file_CSP_inlinescript_main_spec_compliant_allowed.html + file_CSP_inlinescript_main_spec_compliant_allowed.html^headers^ + file_CSP_inlinestyle_main.html + file_CSP_inlinestyle_main.html^headers^ + file_CSP_inlinestyle_main_spec_compliant.html + file_CSP_inlinestyle_main_spec_compliant.html^headers^ + file_CSP_inlinestyle_main_spec_compliant_allowed.html + file_CSP_inlinestyle_main_spec_compliant_allowed.html^headers^ + file_CSP_main.html + file_CSP_main.html^headers^ + file_CSP_main.js + file_CSP_main_spec_compliant.html + file_CSP_main_spec_compliant.html^headers^ + file_CSP_main_spec_compliant.js + file_bothCSPheaders.html + file_bothCSPheaders.html^headers^ + file_bug836922_npolicies.html + file_bug836922_npolicies.html^headers^ + file_bug836922_npolicies_ro_violation.sjs + file_bug836922_npolicies_violation.sjs + file_bug886164.html + file_bug886164.html^headers^ + file_bug886164_2.html + file_bug886164_2.html^headers^ + file_bug886164_3.html + file_bug886164_3.html^headers^ + file_bug886164_4.html + file_bug886164_4.html^headers^ + file_bug886164_5.html + file_bug886164_5.html^headers^ + file_bug886164_6.html + file_bug886164_6.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_CSP_bug910139.sjs + file_CSP_bug910139.xml + file_CSP_bug910139.xsl + file_CSP_bug909029_star.html + file_CSP_bug909029_star.html^headers^ + file_CSP_bug909029_none.html + file_CSP_bug909029_none.html^headers^ + file_policyuri_regression_from_multipolicy.html + file_policyuri_regression_from_multipolicy.html^headers^ + file_policyuri_regression_from_multipolicy_policy + file_nonce_source.html + file_nonce_source.html^headers^ + file_CSP_bug941404.html + file_CSP_bug941404_xhr.html + file_CSP_bug941404_xhr.html^headers^ + file_hash_source.html + file_hash_source.html^headers^ + file_dual_headers_warning.html + file_dual_headers_warning.html^headers^ + file_self_none_as_hostname_confusion.html + file_self_none_as_hostname_confusion.html^headers^ + file_csp_testserver.sjs + file_csp_regexp_parsing.html + file_csp_regexp_parsing.js + file_report_uri_missing_in_report_only_header.html + file_report_uri_missing_in_report_only_header.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_bug663567.html] +[test_CSP_bug802872.html] +[test_CSP_bug885433.html] +[test_CSP_bug888172.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_bug836922_npolicies.html] +[test_bug886164.html] +[test_csp_redirects.html] +[test_CSP_bug910139.html] +[test_CSP_bug909029.html] +[test_policyuri_regression_from_multipolicy.html] +[test_nonce_source.html] +[test_CSP_bug941404.html] +[test_hash_source.html] +skip-if = e10s || buildapp == 'b2g' # can't compute hashes in child process (bug 958702) +[test_dual_headers_warning.html] +[test_self_none_as_hostname_confusion.html] +[test_bug949549.html] +[test_csp_regexp_parsing.html] +[test_report_uri_missing_in_report_only_header.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] diff --git a/content/base/test/xcsp/moz.build b/content/base/test/xcsp/moz.build new file mode 100644 index 00000000000..99b068bc92a --- /dev/null +++ b/content/base/test/xcsp/moz.build @@ -0,0 +1,10 @@ +# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +MOCHITEST_MANIFESTS += ['mochitest.ini'] + +MOCHITEST_CHROME_MANIFESTS += ['chrome.ini'] + diff --git a/content/base/test/xcsp/test_301_redirect.html b/content/base/test/xcsp/test_301_redirect.html new file mode 100644 index 00000000000..4625918d0d4 --- /dev/null +++ b/content/base/test/xcsp/test_301_redirect.html @@ -0,0 +1,77 @@ + + + + + Test for Bug 650386 + + + + +Mozilla Bug 650386 +

+ +
+
+
+ + diff --git a/content/base/test/xcsp/test_302_redirect.html b/content/base/test/xcsp/test_302_redirect.html new file mode 100644 index 00000000000..f0794da6e84 --- /dev/null +++ b/content/base/test/xcsp/test_302_redirect.html @@ -0,0 +1,77 @@ + + + + + Test for Bug 650386 + + + + +Mozilla Bug 650386 +

+ +
+
+
+ + diff --git a/content/base/test/xcsp/test_303_redirect.html b/content/base/test/xcsp/test_303_redirect.html new file mode 100644 index 00000000000..3afd1317d36 --- /dev/null +++ b/content/base/test/xcsp/test_303_redirect.html @@ -0,0 +1,77 @@ + + + + + Test for Bug 650386 + + + + +Mozilla Bug 650386 +

+ +
+
+
+ + diff --git a/content/base/test/xcsp/test_307_redirect.html b/content/base/test/xcsp/test_307_redirect.html new file mode 100644 index 00000000000..e200accfefc --- /dev/null +++ b/content/base/test/xcsp/test_307_redirect.html @@ -0,0 +1,77 @@ + + + + + Test for Bug 650386 + + + + +Mozilla Bug 650386 +

+ +
+
+
+ + diff --git a/content/base/test/xcsp/test_CSP.html b/content/base/test/xcsp/test_CSP.html new file mode 100644 index 00000000000..24a1d711ba2 --- /dev/null +++ b/content/base/test/xcsp/test_CSP.html @@ -0,0 +1,139 @@ + + + + Test for Content Security Policy Connections + + + + +

+ + + + + + + diff --git a/content/base/test/xcsp/test_CSP_evalscript.html b/content/base/test/xcsp/test_CSP_evalscript.html new file mode 100644 index 00000000000..6857277e25b --- /dev/null +++ b/content/base/test/xcsp/test_CSP_evalscript.html @@ -0,0 +1,65 @@ + + + + Test for Content Security Policy "no eval" base restriction + + + + +

+ + + + + + + + diff --git a/content/base/test/xcsp/test_CSP_evalscript_getCRMFRequest.html b/content/base/test/xcsp/test_CSP_evalscript_getCRMFRequest.html new file mode 100644 index 00000000000..c3eee193b17 --- /dev/null +++ b/content/base/test/xcsp/test_CSP_evalscript_getCRMFRequest.html @@ -0,0 +1,65 @@ + + + + Test for Content Security Policy "no eval" in crypto.getCRMFRequest() + + + + +

+ + + + + + + + + diff --git a/content/base/test/xcsp/test_CSP_frameancestors.html b/content/base/test/xcsp/test_CSP_frameancestors.html new file mode 100644 index 00000000000..b294ac153fb --- /dev/null +++ b/content/base/test/xcsp/test_CSP_frameancestors.html @@ -0,0 +1,136 @@ + + + + Test for Content Security Policy Frame Ancestors directive + + + + +

+ + + + + + + diff --git a/content/base/test/xcsp/test_CSP_inlinescript.html b/content/base/test/xcsp/test_CSP_inlinescript.html new file mode 100644 index 00000000000..f8ec16bf533 --- /dev/null +++ b/content/base/test/xcsp/test_CSP_inlinescript.html @@ -0,0 +1,128 @@ + + + + Test for Content Security Policy Frame Ancestors directive + + + + + +

+ + + + + + + + + diff --git a/content/base/test/xcsp/test_CSP_inlinestyle.html b/content/base/test/xcsp/test_CSP_inlinestyle.html new file mode 100644 index 00000000000..203bf69d2d1 --- /dev/null +++ b/content/base/test/xcsp/test_CSP_inlinestyle.html @@ -0,0 +1,142 @@ + + + + Test for Content Security Policy inline stylesheets stuff + + + + +

+ + + + + + + + + diff --git a/content/base/test/xcsp/test_csp_bug768029.html b/content/base/test/xcsp/test_csp_bug768029.html new file mode 100644 index 00000000000..d455326c4cb --- /dev/null +++ b/content/base/test/xcsp/test_csp_bug768029.html @@ -0,0 +1,223 @@ + + + + + + Test for CSP on trusted/certified apps -- bug 768029 + + + + +Mozilla Bug 768029 +

+
+ +
+
+
+
+ + diff --git a/content/base/test/xcsp/test_csp_bug773891.html b/content/base/test/xcsp/test_csp_bug773891.html new file mode 100644 index 00000000000..8d0736fb790 --- /dev/null +++ b/content/base/test/xcsp/test_csp_bug773891.html @@ -0,0 +1,228 @@ + + + + + + Test for CSP on trusted/certified and installed apps -- bug 773891 + + + + +Mozilla Bug 773891 +

+
+ +
+
+
+
+ + diff --git a/content/base/test/xcsp/test_csp_redirects.html b/content/base/test/xcsp/test_csp_redirects.html new file mode 100644 index 00000000000..b1f603bf238 --- /dev/null +++ b/content/base/test/xcsp/test_csp_redirects.html @@ -0,0 +1,148 @@ + + + + Tests for Content Security Policy during redirects + + + + +

+ + + +

+
+
+
+
+
diff --git a/content/base/test/xcsp/test_csp_report.html b/content/base/test/xcsp/test_csp_report.html
new file mode 100644
index 00000000000..1462bd85e46
--- /dev/null
+++ b/content/base/test/xcsp/test_csp_report.html
@@ -0,0 +1,108 @@
+
+
+
+
+  Test for Bug 548193
+  
+  
+
+
+

+ + + + + + + diff --git a/content/base/test/xcsp/test_multi_policy_injection_bypass.html b/content/base/test/xcsp/test_multi_policy_injection_bypass.html new file mode 100644 index 00000000000..5a1315b5be6 --- /dev/null +++ b/content/base/test/xcsp/test_multi_policy_injection_bypass.html @@ -0,0 +1,121 @@ + + + + + Test for Bug 717511 + + + + +

+ + + + + + + + diff --git a/content/base/test/xcsp/test_subframe_run_js_if_allowed.html b/content/base/test/xcsp/test_subframe_run_js_if_allowed.html new file mode 100644 index 00000000000..96a70b366a9 --- /dev/null +++ b/content/base/test/xcsp/test_subframe_run_js_if_allowed.html @@ -0,0 +1,32 @@ + + + + + Test for Bug 702439 + + + + + + + +