1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/content/base/test/unit/test_csputils.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,1054 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 + 1.8 +const Cc = Components.classes; 1.9 +const Ci = Components.interfaces; 1.10 +const Cu = Components.utils; 1.11 +const Cr = Components.results; 1.12 + 1.13 +//load('CSPUtils.jsm'); 1.14 +Cu.import('resource://gre/modules/CSPUtils.jsm'); 1.15 +Cu.import('resource://gre/modules/NetUtil.jsm'); 1.16 + 1.17 +var httpServer = new HttpServer(); 1.18 +httpServer.start(-1); 1.19 + 1.20 +const POLICY_FROM_URI = "default-src 'self'; img-src *"; 1.21 +const POLICY_PORT = httpServer.identity.primaryPort; 1.22 +const POLICY_URI = "http://localhost:" + POLICY_PORT + "/policy"; 1.23 +const POLICY_URI_RELATIVE = "/policy"; 1.24 + 1.25 +//converts string to nsIURI 1.26 +function URI(uriString) { 1.27 + var ioService = Cc["@mozilla.org/network/io-service;1"] 1.28 + .getService(Ci.nsIIOService); 1.29 + return ioService.newURI(uriString, null, null); 1.30 +} 1.31 + 1.32 + 1.33 +// helper to assert that an array has the given value somewhere. 1.34 +function do_check_in_array(arr, val, stack) { 1.35 + if (!stack) 1.36 + stack = Components.stack.caller; 1.37 + 1.38 + var text = val + " in [" + arr.join(",") + "]"; 1.39 + 1.40 + for(var i in arr) { 1.41 + dump(".......... " + i + "> " + arr[i] + "\n"); 1.42 + if(arr[i] == val) { 1.43 + //succeed 1.44 + ++_passedChecks; 1.45 + dump("TEST-PASS | " + stack.filename + " | [" + stack.name + " : " + 1.46 + stack.lineNumber + "] " + text + "\n"); 1.47 + return; 1.48 + } 1.49 + } 1.50 + do_throw(text, stack); 1.51 +} 1.52 + 1.53 +// helper to assert that an object or array must have a given key 1.54 +function do_check_has_key(foo, key, stack) { 1.55 + if (!stack) 1.56 + stack = Components.stack.caller; 1.57 + 1.58 + var keys = []; 1.59 + for (let k in foo) { keys.push(k); } 1.60 + var text = key + " in [" + keys.join(",") + "]"; 1.61 + 1.62 + for (var x in foo) { 1.63 + if (x == key) { 1.64 + //succeed 1.65 + ++_passedChecks; 1.66 + dump("TEST-PASS | " + stack.filename + " | [" + stack.name + " : " + 1.67 + stack.lineNumber + "] " + text + "\n"); 1.68 + return; 1.69 + } 1.70 + } 1.71 + do_throw(text, stack); 1.72 +} 1.73 + 1.74 +// helper to use .equals on stuff 1.75 +function do_check_equivalent(foo, bar, stack) { 1.76 + if (!stack) 1.77 + stack = Components.stack.caller; 1.78 + 1.79 + var text = foo + ".equals(" + bar + ")"; 1.80 + 1.81 + if(foo.equals && foo.equals(bar)) { 1.82 + ++_passedChecks; 1.83 + dump("TEST-PASS | " + stack.filename + " | [" + stack.name + " : " + 1.84 + stack.lineNumber + "] " + text + "\n"); 1.85 + return; 1.86 + } 1.87 + do_throw(text, stack); 1.88 +} 1.89 + 1.90 +var tests = []; 1.91 +function test(fcn) { 1.92 + tests.push(fcn); 1.93 +} 1.94 + 1.95 +test( 1.96 + function test_CSPHost_fromstring() { 1.97 + var h; 1.98 + 1.99 + h = CSPHost.fromString("*"); 1.100 + do_check_neq(null, h); // "* lone wildcard should work" 1.101 + 1.102 + h = CSPHost.fromString("foo.bar"); 1.103 + do_check_neq(null, h); // "standard tuple failed" 1.104 + 1.105 + h = CSPHost.fromString("*.bar"); 1.106 + do_check_neq(null, h); // "wildcard failed" 1.107 + 1.108 + h = CSPHost.fromString("foo.*.bar"); 1.109 + do_check_eq(null, h); // "wildcard in wrong place worked" 1.110 + 1.111 + h = CSPHost.fromString("com"); 1.112 + do_check_neq(null, h); // "lone symbol should not fail" 1.113 + 1.114 + h = CSPHost.fromString("f00b4r.com"); 1.115 + do_check_neq(null, h); // "Numbers in hosts should work" 1.116 + 1.117 + h = CSPHost.fromString("foo-bar.com"); 1.118 + do_check_neq(null, h); // "dashes in hosts should work" 1.119 + 1.120 + 1.121 + h = CSPHost.fromString("foo!bar.com"); 1.122 + do_check_eq(null, h); // "special chars in hosts should fail" 1.123 + 1.124 + h = CSPHost.fromString("{app-url-is-uid}"); 1.125 + do_check_neq(null, h); // "Packaged apps URLs failed" 1.126 + }); 1.127 + 1.128 +test( 1.129 + function test_CSPHost_clone() { 1.130 + h = CSPHost.fromString("*.a.b.c"); 1.131 + h2 = h.clone(); 1.132 + for(var i in h._segments) { 1.133 + // "cloned segments should match" 1.134 + do_check_eq(h._segments[i], h2._segments[i]); 1.135 + } 1.136 + }); 1.137 + 1.138 +test( 1.139 + function test_CSPHost_permits() { 1.140 + var h = CSPHost.fromString("*.b.c"); 1.141 + var h2 = CSPHost.fromString("a.b.c"); 1.142 + do_check_true( h.permits(h2)); //"CSPHost *.b.c should allow CSPHost a.b.c" 1.143 + do_check_true( h.permits("a.b.c")); //"CSPHost *.b.c should allow string a.b.c" 1.144 + do_check_false(h.permits("b.c")); //"CSPHost *.b.c should not allow string b.c" 1.145 + do_check_false(h.permits("a.a.c")); //"CSPHost *.b.c should not allow string a.a.c" 1.146 + do_check_false(h2.permits(h)); //"CSPHost a.b.c should not allow CSPHost *.b.c" 1.147 + do_check_false(h2.permits("b.c")); //"CSPHost a.b.c should not allow string b.c" 1.148 + do_check_true( h2.permits("a.b.c")); //"CSPHost a.b.c should allow string a.b.c" 1.149 + }); 1.150 + 1.151 + 1.152 +///////////////////// Test the Source object ////////////////////// 1.153 + 1.154 +test( 1.155 + function test_CSPSource_fromString() { 1.156 + // can't do these tests because "self" is not defined. 1.157 + //"basic source should not be null."); 1.158 + do_check_neq(null, CSPSource.fromString("a.com", undefined, "http://abc.com")); 1.159 + 1.160 + //"ldh characters should all work for host."); 1.161 + do_check_neq(null, CSPSource.fromString("a2-c.com", undefined, "https://a.com")); 1.162 + 1.163 + //"wildcard should work in first token for host."); 1.164 + do_check_neq(null, CSPSource.fromString("*.a.com", undefined, "http://abc.com")); 1.165 + 1.166 + //print(" --- Ignore the following two errors if they print ---"); 1.167 + //"wildcard should not work in non-first token for host."); 1.168 + do_check_eq(null, CSPSource.fromString("x.*.a.com", undefined, "http://a.com")); 1.169 + 1.170 + //"funny characters (#) should not work for host."); 1.171 + do_check_eq(null, CSPSource.fromString("a#2-c.com", undefined, "http://a.com")); 1.172 + 1.173 + //print(" --- Stop ignoring errors that print ---\n"); 1.174 + 1.175 + //"failed to parse host with port."); 1.176 + do_check_neq(null, CSPSource.create("a.com:23", undefined, "http://a.com")); 1.177 + //"failed to parse host with scheme."); 1.178 + do_check_neq(null, CSPSource.create("https://a.com", undefined, "http://a.com")); 1.179 + //"failed to parse host with scheme and port."); 1.180 + do_check_neq(null, CSPSource.create("https://a.com:200", undefined, "http://a.com")); 1.181 + 1.182 + //Check to make sure we don't match multiple instances with regex 1.183 + do_check_eq(null, CSPSource.create("http://foo.com:bar.com:23")); 1.184 + //Port parsing should work for all schemes 1.185 + do_check_neq(null, CSPSource.create("data:")); 1.186 + do_check_neq(null, CSPSource.create("javascript:")); 1.187 + 1.188 + //"app:// URLs should work, including the {} characters."); 1.189 + do_check_neq(null, CSPSource.fromString("{app-host-is-uid}", undefined, "app://{app-host-is-uid}")); 1.190 + }); 1.191 + 1.192 +test( 1.193 + function test_CSPSource_fromString_withSelf() { 1.194 + var src; 1.195 + src = CSPSource.create("a.com", undefined, "https://foobar.com:443"); 1.196 + //"src should inherit port * 1.197 + do_check_true(src.permits("https://a.com:443")); 1.198 + //"src should inherit and require https scheme 1.199 + do_check_false(src.permits("http://a.com")); 1.200 + //"src should inherit scheme 'https'" 1.201 + do_check_true(src.permits("https://a.com")); 1.202 + 1.203 + src = CSPSource.create("http://a.com", undefined, "https://foobar.com:443"); 1.204 + //"src should inherit and require http scheme" 1.205 + do_check_false(src.permits("https://a.com")); 1.206 + //"src should inherit scheme 'http'" 1.207 + do_check_true(src.permits("http://a.com")); 1.208 + //"src should inherit port and scheme from parent" 1.209 + //"src should inherit default port for 'http'" 1.210 + do_check_true(src.permits("http://a.com:80")); 1.211 + 1.212 + src = CSPSource.create("'self'", undefined, "https://foobar.com:443"); 1.213 + //"src should inherit port * 1.214 + do_check_true(src.permits("https://foobar.com:443")); 1.215 + //"src should inherit and require https scheme 1.216 + do_check_false(src.permits("http://foobar.com")); 1.217 + //"src should inherit scheme 'https'" 1.218 + do_check_true(src.permits("https://foobar.com")); 1.219 + //"src should reject other hosts" 1.220 + do_check_false(src.permits("https://a.com")); 1.221 + 1.222 + src = CSPSource.create("javascript:", undefined, "https://foobar.com:443"); 1.223 + //"hostless schemes should be parseable." 1.224 + var aUri = NetUtil.newURI("javascript:alert('foo');"); 1.225 + do_check_true(src.permits(aUri)); 1.226 + //"src should reject other hosts" 1.227 + do_check_false(src.permits("https://a.com")); 1.228 + //"nothing else should be allowed" 1.229 + do_check_false(src.permits("https://foobar.com")); 1.230 + 1.231 + src = CSPSource.create("{app-host-is-uid}", undefined, "app://{app-host-is-uid}"); 1.232 + //"src should inherit and require 'app' scheme" 1.233 + do_check_false(src.permits("https://{app-host-is-uid}")); 1.234 + //"src should inherit scheme 'app'" 1.235 + do_check_true(src.permits("app://{app-host-is-uid}")); 1.236 + 1.237 + }); 1.238 + 1.239 +///////////////////// Test the source list ////////////////////// 1.240 + 1.241 +test( 1.242 + function test_CSPSourceList_fromString() { 1.243 + var sd = CSPSourceList.fromString("'none'"); 1.244 + //"'none' -- should parse" 1.245 + do_check_neq(null,sd); 1.246 + // "'none' should be a zero-length list" 1.247 + do_check_eq(0, sd._sources.length); 1.248 + do_check_true(sd.isNone()); 1.249 + 1.250 + sd = CSPSourceList.fromString("*"); 1.251 + //"'*' should be a zero-length list" 1.252 + do_check_eq(0, sd._sources.length); 1.253 + 1.254 + //print(" --- Ignore the following three errors if they print ---"); 1.255 + //"funny char in host" 1.256 + do_check_true(CSPSourceList.fromString("f!oo.bar").isNone()); 1.257 + //"funny char in scheme" 1.258 + do_check_true(CSPSourceList.fromString("ht!ps://f-oo.bar").isNone()); 1.259 + //"funny char in port" 1.260 + do_check_true(CSPSourceList.fromString("https://f-oo.bar:3f").isNone()); 1.261 + //print(" --- Stop ignoring errors that print ---\n"); 1.262 + }); 1.263 + 1.264 +test( 1.265 + function test_CSPSourceList_fromString_twohost() { 1.266 + var str = "foo.bar:21 https://ras.bar"; 1.267 + var parsed = "http://foo.bar:21 https://ras.bar:443"; 1.268 + var sd = CSPSourceList.fromString(str, undefined, URI("http://self.com:80")); 1.269 + //"two-host list should parse" 1.270 + do_check_neq(null,sd); 1.271 + //"two-host list should parse to two hosts" 1.272 + do_check_eq(2, sd._sources.length); 1.273 + //"two-host list should contain original data" 1.274 + do_check_eq(parsed, sd.toString()); 1.275 + }); 1.276 + 1.277 +test( 1.278 + function test_CSPSourceList_permits() { 1.279 + var nullSourceList = CSPSourceList.fromString("'none'"); 1.280 + var simpleSourceList = CSPSourceList.fromString("a.com", undefined, URI("http://self.com")); 1.281 + var doubleSourceList = CSPSourceList.fromString("https://foo.com http://bar.com:88", 1.282 + undefined, 1.283 + URI("http://self.com:88")); 1.284 + var allSourceList = CSPSourceList.fromString("*"); 1.285 + var allAndMoreSourceList = CSPSourceList.fromString("* https://bar.com 'none'"); 1.286 + var wildcardHostSourceList = CSPSourceList.fromString("*.foo.com", 1.287 + undefined, URI("http://self.com")); 1.288 + var allDoubledHostSourceList = CSPSourceList.fromString("**"); 1.289 + var allGarbageHostSourceList = CSPSourceList.fromString("*a"); 1.290 + 1.291 + //'none' should permit none." 1.292 + do_check_false( nullSourceList.permits("http://a.com")); 1.293 + //a.com should permit a.com" 1.294 + do_check_true( simpleSourceList.permits("http://a.com")); 1.295 + //wrong host" 1.296 + do_check_false( simpleSourceList.permits("http://b.com")); 1.297 + //double list permits http://bar.com:88" 1.298 + do_check_true( doubleSourceList.permits("http://bar.com:88")); 1.299 + //double list permits https://bar.com:88" 1.300 + do_check_false( doubleSourceList.permits("https://bar.com:88")); 1.301 + //double list does not permit http://bar.com:443" 1.302 + do_check_false( doubleSourceList.permits("http://bar.com:443")); 1.303 + //"double list permits https://foo.com:88" (should not inherit port) 1.304 + do_check_false( doubleSourceList.permits("https://foo.com:88")); 1.305 + //"double list does not permit foo.com on http" 1.306 + do_check_false( doubleSourceList.permits("http://foo.com")); 1.307 + 1.308 + //"* does not permit specific host" 1.309 + do_check_true( allSourceList.permits("http://x.com:23")); 1.310 + //"* does not permit a long host with no port" 1.311 + do_check_true( allSourceList.permits("http://a.b.c.d.e.f.g.h.i.j.k.l.x.com")); 1.312 + 1.313 + //* short circuts parsing 1.314 + do_check_true(allAndMoreSourceList.permits("http://a.com")); 1.315 + 1.316 + //"** permits all" 1.317 + do_check_false(allDoubledHostSourceList.permits("http://barbaz.com")); 1.318 + //"*a permits all" 1.319 + do_check_false(allGarbageHostSourceList.permits("http://barbaz.com")); 1.320 + 1.321 + //"*.foo.com does not permit somerandom.foo.com" 1.322 + do_check_true(wildcardHostSourceList.permits("http://somerandom.foo.com")); 1.323 + //"*.foo.com permits all" 1.324 + do_check_false(wildcardHostSourceList.permits("http://barbaz.com")); 1.325 + }); 1.326 + 1.327 +///////////////////// Test the Whole CSP rep object ////////////////////// 1.328 + 1.329 +test( 1.330 + function test_CSPRep_fromString() { 1.331 + 1.332 + // check default init 1.333 + //ASSERT(!(new CSPRep())._isInitialized, "Uninitialized rep thinks it is.") 1.334 + 1.335 + var cspr; 1.336 + var cspr_allowval; 1.337 + var SD = CSPRep.SRC_DIRECTIVES_OLD; 1.338 + 1.339 + // check default policy "allow *" 1.340 + cspr = CSPRep.fromString("allow *", URI("http://self.com:80")); 1.341 + // "DEFAULT_SRC directive is missing when specified in fromString" 1.342 + do_check_has_key(cspr._directives, SD.DEFAULT_SRC); 1.343 + 1.344 + }); 1.345 + 1.346 + 1.347 +test( 1.348 + function test_CSPRep_defaultSrc() { 1.349 + var cspr, cspr_default_val, cspr_allow; 1.350 + var SD = CSPRep.SRC_DIRECTIVES_OLD; 1.351 + 1.352 + // apply policy of "default-src *" (e.g. "allow *") 1.353 + cspr = CSPRep.fromString("default-src *", URI("http://self.com:80")); 1.354 + // "DEFAULT_SRC directive is missing when specified in fromString" 1.355 + do_check_has_key(cspr._directives, SD.DEFAULT_SRC); 1.356 + 1.357 + // check that |allow *| and |default-src *| are parsed equivalently and 1.358 + // result in the same set of explicit policy directives 1.359 + cspr = CSPRep.fromString("default-src *", URI("http://self.com:80")); 1.360 + cspr_allow = CSPRep.fromString("allow *", URI("http://self.com:80")); 1.361 + 1.362 + do_check_equivalent(cspr._directives['default-src'], 1.363 + cspr_allow._directives['default-src']); 1.364 + }); 1.365 + 1.366 + 1.367 +test( 1.368 + function test_CSPRep_fromString_oneDir() { 1.369 + 1.370 + var cspr; 1.371 + var SD = CSPRep.SRC_DIRECTIVES_OLD; 1.372 + var DEFAULTS = [SD.STYLE_SRC, SD.MEDIA_SRC, SD.IMG_SRC, SD.FRAME_SRC]; 1.373 + 1.374 + // check one-directive policies 1.375 + cspr = CSPRep.fromString("allow bar.com; script-src https://foo.com", 1.376 + URI("http://self.com")); 1.377 + 1.378 + for(var x in DEFAULTS) { 1.379 + //DEFAULTS[x] + " does not use default rule." 1.380 + do_check_false(cspr.permits("http://bar.com:22", DEFAULTS[x])); 1.381 + //DEFAULTS[x] + " does not use default rule." 1.382 + do_check_true(cspr.permits("http://bar.com:80", DEFAULTS[x])); 1.383 + //DEFAULTS[x] + " does not use default rule." 1.384 + do_check_false(cspr.permits("https://foo.com:400", DEFAULTS[x])); 1.385 + //DEFAULTS[x] + " does not use default rule." 1.386 + do_check_false(cspr.permits("https://foo.com", DEFAULTS[x])); 1.387 + } 1.388 + //"script-src false positive in policy. 1.389 + do_check_false(cspr.permits("http://bar.com:22", SD.SCRIPT_SRC)); 1.390 + //"script-src false negative in policy. 1.391 + do_check_true(cspr.permits("https://foo.com:443", SD.SCRIPT_SRC)); 1.392 + }); 1.393 + 1.394 +test( 1.395 + function test_CSPRep_fromString_twodir() { 1.396 + var cspr; 1.397 + var SD = CSPRep.SRC_DIRECTIVES_OLD; 1.398 + var DEFAULTS = [SD.STYLE_SRC, SD.MEDIA_SRC, SD.FRAME_SRC]; 1.399 + 1.400 + // check two-directive policies 1.401 + var polstr = "allow allow.com; " 1.402 + + "script-src https://foo.com; " 1.403 + + "img-src bar.com:*"; 1.404 + cspr = CSPRep.fromString(polstr, URI("http://self.com")); 1.405 + 1.406 + for(var x in DEFAULTS) { 1.407 + do_check_true(cspr.permits("http://allow.com", DEFAULTS[x])); 1.408 + //DEFAULTS[x] + " does not use default rule. 1.409 + do_check_false(cspr.permits("https://foo.com:400", DEFAULTS[x])); 1.410 + //DEFAULTS[x] + " does not use default rule. 1.411 + do_check_false(cspr.permits("http://bar.com:400", DEFAULTS[x])); 1.412 + //DEFAULTS[x] + " does not use default rule. 1.413 + } 1.414 + //"img-src does not use default rule. 1.415 + do_check_false(cspr.permits("http://allow.com:22", SD.IMG_SRC)); 1.416 + //"img-src does not use default rule. 1.417 + do_check_false(cspr.permits("https://foo.com:400", SD.IMG_SRC)); 1.418 + //"img-src does not use default rule. 1.419 + do_check_true(cspr.permits("http://bar.com:88", SD.IMG_SRC)); 1.420 + 1.421 + //"script-src does not use default rule. 1.422 + do_check_false(cspr.permits("http://allow.com:22", SD.SCRIPT_SRC)); 1.423 + //"script-src does not use default rule. 1.424 + do_check_true(cspr.permits("https://foo.com:443", SD.SCRIPT_SRC)); 1.425 + //"script-src does not use default rule. 1.426 + do_check_false(cspr.permits("http://bar.com:400", SD.SCRIPT_SRC)); 1.427 + }); 1.428 + 1.429 +test(function test_CSPRep_fromString_withself() { 1.430 + var cspr; 1.431 + var SD = CSPRep.SRC_DIRECTIVES_OLD; 1.432 + var self = "https://self.com:34"; 1.433 + 1.434 + // check one-directive policies 1.435 + cspr = CSPRep.fromString("allow 'self'; script-src 'self' https://*:*", 1.436 + URI(self)); 1.437 + //"img-src does not enforce default rule, 'self'. 1.438 + do_check_false(cspr.permits("https://foo.com:400", SD.IMG_SRC)); 1.439 + //"img-src does not allow self 1.440 + do_check_true(cspr.permits(self, SD.IMG_SRC)); 1.441 + //"script-src is too relaxed 1.442 + do_check_false(cspr.permits("http://evil.com", SD.SCRIPT_SRC)); 1.443 + //"script-src should allow self 1.444 + do_check_true(cspr.permits(self, SD.SCRIPT_SRC)); 1.445 + //"script-src is too strict on host/port 1.446 + do_check_true(cspr.permits("https://evil.com:100", SD.SCRIPT_SRC)); 1.447 + }); 1.448 + 1.449 + 1.450 +//////////////// TEST CSP REP SPEC COMPLIANT PARSER //////////// 1.451 +test( 1.452 + function test_CSPRep_fromStringSpecCompliant() { 1.453 + 1.454 + var cspr; 1.455 + var cspr_allowval; 1.456 + var SD = CSPRep.SRC_DIRECTIVES_NEW; 1.457 + var DEFAULTS = [SD.STYLE_SRC, SD.MEDIA_SRC, SD.IMG_SRC, SD.SCRIPT_SRC, SD.FONT_SRC, 1.458 + SD.OBJECT_SRC, SD.FRAME_SRC, SD.CONNECT_SRC]; 1.459 + 1.460 + // check default policy "default-src *" 1.461 + cspr = CSPRep.fromStringSpecCompliant("default-src *", URI("http://self.com:80")); 1.462 + // "DEFAULT_SRC directive is missing when specified in 1.463 + // fromStringSpecCompliant" 1.464 + do_check_has_key(cspr._directives, SD.DEFAULT_SRC); 1.465 + 1.466 + for(var x in DEFAULTS) { 1.467 + // each of these should be equivalent to DEFAULT_SRC 1.468 + //DEFAULTS[x] + " does not use default rule." 1.469 + do_check_true(cspr.permits("http://bar.com", DEFAULTS[x])); 1.470 + } 1.471 + }); 1.472 + 1.473 + 1.474 +test( 1.475 + function test_CSPRep_fromStringSpecCompliant_oneDir() { 1.476 + 1.477 + var cspr; 1.478 + var SD = CSPRep.SRC_DIRECTIVES_NEW; 1.479 + var DEFAULTS = [SD.STYLE_SRC, SD.MEDIA_SRC, SD.IMG_SRC, 1.480 + SD.FRAME_SRC, SD.CONNECT_SRC]; 1.481 + 1.482 + // check one-directive policies 1.483 + cspr = CSPRep.fromStringSpecCompliant("default-src bar.com; script-src https://foo.com", 1.484 + URI("http://self.com")); 1.485 + 1.486 + for(var x in DEFAULTS) { 1.487 + //DEFAULTS[x] + " does not use default rule." 1.488 + do_check_false(cspr.permits("http://bar.com:22", DEFAULTS[x])); 1.489 + //DEFAULTS[x] + " does not use default rule." 1.490 + do_check_true(cspr.permits("http://bar.com:80", DEFAULTS[x])); 1.491 + //DEFAULTS[x] + " does not use default rule." 1.492 + do_check_false(cspr.permits("https://foo.com:400", DEFAULTS[x])); 1.493 + //DEFAULTS[x] + " does not use default rule." 1.494 + do_check_false(cspr.permits("https://foo.com", DEFAULTS[x])); 1.495 + } 1.496 + //"script-src false positive in policy. 1.497 + do_check_false(cspr.permits("http://bar.com:22", SD.SCRIPT_SRC)); 1.498 + //"script-src false negative in policy. 1.499 + do_check_true(cspr.permits("https://foo.com:443", SD.SCRIPT_SRC)); 1.500 + }); 1.501 + 1.502 +test( 1.503 + function test_CSPRep_fromStringSpecCompliant_twodir() { 1.504 + var cspr; 1.505 + 1.506 + var SD = CSPRep.SRC_DIRECTIVES_NEW; 1.507 + 1.508 + var DEFAULTS = [SD.STYLE_SRC, SD.MEDIA_SRC, SD.FRAME_SRC, 1.509 + SD.CONNECT_SRC]; 1.510 + 1.511 + // check two-directive policies 1.512 + var polstr = "default-src allow.com; " + 1.513 + "script-src https://foo.com; " + 1.514 + "img-src bar.com:*"; 1.515 + cspr = CSPRep.fromStringSpecCompliant(polstr, URI("http://self.com")); 1.516 + 1.517 + for(var x in DEFAULTS) { 1.518 + do_check_true(cspr.permits("http://allow.com", DEFAULTS[x])); 1.519 + //DEFAULTS[x] + " does not use default rule. 1.520 + do_check_false(cspr.permits("https://foo.com:400", DEFAULTS[x])); 1.521 + //DEFAULTS[x] + " does not use default rule. 1.522 + do_check_false(cspr.permits("http://bar.com:400", DEFAULTS[x])); 1.523 + //DEFAULTS[x] + " does not use default rule. 1.524 + } 1.525 + //"img-src does not use default rule. 1.526 + do_check_false(cspr.permits("http://allow.com:22", SD.IMG_SRC)); 1.527 + //"img-src does not use default rule. 1.528 + do_check_false(cspr.permits("https://foo.com:400", SD.IMG_SRC)); 1.529 + //"img-src does not use default rule. 1.530 + do_check_true(cspr.permits("http://bar.com:88", SD.IMG_SRC)); 1.531 + 1.532 + //"script-src does not use default rule. 1.533 + do_check_false(cspr.permits("http://allow.com:22", SD.SCRIPT_SRC)); 1.534 + //"script-src does not use default rule. 1.535 + do_check_true(cspr.permits("https://foo.com:443", SD.SCRIPT_SRC)); 1.536 + //"script-src does not use default rule. 1.537 + do_check_false(cspr.permits("http://bar.com:400", SD.SCRIPT_SRC)); 1.538 + }); 1.539 + 1.540 +test(function test_CSPRep_fromStringSpecCompliant_withself() { 1.541 + var cspr; 1.542 + var self = "https://self.com:34"; 1.543 + var SD = CSPRep.SRC_DIRECTIVES_NEW; 1.544 + 1.545 + // check one-directive policies 1.546 + cspr = CSPRep.fromStringSpecCompliant("default-src 'self'; script-src 'self' https://*:*", 1.547 + URI(self)); 1.548 + //"img-src does not enforce default rule, 'self'. 1.549 + do_check_false(cspr.permits("https://foo.com:400", SD.IMG_SRC)); 1.550 + //"img-src does not allow self 1.551 + do_check_true(cspr.permits(self, SD.IMG_SRC)); 1.552 + //"script-src is too relaxed 1.553 + do_check_false(cspr.permits("http://evil.com", SD.SCRIPT_SRC)); 1.554 + //"script-src should allow self 1.555 + do_check_true(cspr.permits(self, SD.SCRIPT_SRC)); 1.556 + //"script-src is too strict on host/port 1.557 + do_check_true(cspr.permits("https://evil.com:100", SD.SCRIPT_SRC)); 1.558 + }); 1.559 + 1.560 + 1.561 +//////////////// TEST FRAME ANCESTOR DEFAULTS ///////////////// 1.562 +// (see bug 555068) 1.563 +test(function test_FrameAncestor_defaults() { 1.564 + var cspr; 1.565 + var SD = CSPRep.SRC_DIRECTIVES_OLD; 1.566 + var self = "http://self.com:34"; 1.567 + 1.568 + cspr = CSPRep.fromString("allow 'none'", URI(self)); 1.569 + 1.570 + //"frame-ancestors should default to * not 'allow' value" 1.571 + do_check_true(cspr.permits("https://foo.com:400", SD.FRAME_ANCESTORS)); 1.572 + do_check_true(cspr.permits("http://self.com:34", SD.FRAME_ANCESTORS)); 1.573 + do_check_true(cspr.permits("https://self.com:34", SD.FRAME_ANCESTORS)); 1.574 + do_check_true(cspr.permits("http://self.com", SD.FRAME_ANCESTORS)); 1.575 + do_check_true(cspr.permits("http://subd.self.com:34", SD.FRAME_ANCESTORS)); 1.576 + 1.577 + cspr = CSPRep.fromString("allow 'none'; frame-ancestors 'self'", URI(self)); 1.578 + 1.579 + //"frame-ancestors should only allow self" 1.580 + do_check_true(cspr.permits("http://self.com:34", SD.FRAME_ANCESTORS)); 1.581 + do_check_false(cspr.permits("https://foo.com:400", SD.FRAME_ANCESTORS)); 1.582 + do_check_false(cspr.permits("https://self.com:34", SD.FRAME_ANCESTORS)); 1.583 + do_check_false(cspr.permits("http://self.com", SD.FRAME_ANCESTORS)); 1.584 + do_check_false(cspr.permits("http://subd.self.com:34", SD.FRAME_ANCESTORS)); 1.585 + }); 1.586 + 1.587 +test(function test_FrameAncestor_defaults_specCompliant() { 1.588 + var cspr; 1.589 + var self = "http://self.com:34"; 1.590 + var SD = CSPRep.SRC_DIRECTIVES_NEW; 1.591 + 1.592 + cspr = CSPRep.fromStringSpecCompliant("default-src 'none'", URI(self)); 1.593 + 1.594 + //"frame-ancestors should default to * not 'default-src' value" 1.595 + do_check_true(cspr.permits("https://foo.com:400", SD.FRAME_ANCESTORS)); 1.596 + do_check_true(cspr.permits("http://self.com:34", SD.FRAME_ANCESTORS)); 1.597 + do_check_true(cspr.permits("https://self.com:34", SD.FRAME_ANCESTORS)); 1.598 + do_check_true(cspr.permits("http://self.com", SD.FRAME_ANCESTORS)); 1.599 + do_check_true(cspr.permits("http://subd.self.com:34", SD.FRAME_ANCESTORS)); 1.600 + 1.601 + cspr = CSPRep.fromStringSpecCompliant("default-src 'none'; frame-ancestors 'self'", URI(self)); 1.602 + 1.603 + //"frame-ancestors should only allow self" 1.604 + do_check_true(cspr.permits("http://self.com:34", SD.FRAME_ANCESTORS)); 1.605 + do_check_false(cspr.permits("https://foo.com:400", SD.FRAME_ANCESTORS)); 1.606 + do_check_false(cspr.permits("https://self.com:34", SD.FRAME_ANCESTORS)); 1.607 + do_check_false(cspr.permits("http://self.com", SD.FRAME_ANCESTORS)); 1.608 + do_check_false(cspr.permits("http://subd.self.com:34", SD.FRAME_ANCESTORS)); 1.609 + }); 1.610 + 1.611 + 1.612 +test(function test_FrameAncestor_TLD_defaultPorts() { 1.613 + var cspr; 1.614 + var SD = CSPRep.SRC_DIRECTIVES_OLD; 1.615 + var self = "http://self"; //TLD only, no .com or anything. 1.616 + 1.617 + cspr = CSPRep.fromString("allow 'self'; frame-ancestors 'self' http://foo:80 bar:80 http://three", URI(self)); 1.618 + 1.619 + //"frame-ancestors should default to * not 'allow' value" 1.620 + do_check_true(cspr.permits("http://self", SD.FRAME_ANCESTORS)); 1.621 + do_check_true(cspr.permits("http://self:80", SD.FRAME_ANCESTORS)); 1.622 + do_check_true(cspr.permits("http://foo", SD.FRAME_ANCESTORS)); 1.623 + do_check_true(cspr.permits("http://foo:80", SD.FRAME_ANCESTORS)); 1.624 + do_check_true(cspr.permits("http://bar", SD.FRAME_ANCESTORS)); 1.625 + do_check_true(cspr.permits("http://three:80", SD.FRAME_ANCESTORS)); 1.626 + 1.627 + do_check_false(cspr.permits("https://foo:400", SD.FRAME_ANCESTORS)); 1.628 + do_check_false(cspr.permits("https://self:34", SD.FRAME_ANCESTORS)); 1.629 + do_check_false(cspr.permits("https://bar", SD.FRAME_ANCESTORS)); 1.630 + do_check_false(cspr.permits("http://three:81", SD.FRAME_ANCESTORS)); 1.631 + do_check_false(cspr.permits("https://three:81", SD.FRAME_ANCESTORS)); 1.632 + }); 1.633 + 1.634 +test(function test_FrameAncestor_ignores_userpass_bug779918() { 1.635 + var cspr; 1.636 + var SD = CSPRep.SRC_DIRECTIVES_OLD; 1.637 + var self = "http://self.com/bar"; 1.638 + var testPolicy = "default-src 'self'; frame-ancestors 'self'"; 1.639 + 1.640 + cspr = CSPRep.fromString(testPolicy, URI(self)); 1.641 + 1.642 + // wrapped in URI() because of source parsing 1.643 + do_check_true(cspr.permits(URI("http://username:password@self.com/foo"), SD.FRAME_ANCESTORS)); 1.644 + do_check_true(cspr.permits(URI("http://other:pass1@self.com/foo"), SD.FRAME_ANCESTORS)); 1.645 + do_check_true(cspr.permits(URI("http://self.com:80/foo"), SD.FRAME_ANCESTORS)); 1.646 + do_check_true(cspr.permits(URI("http://self.com/foo"), SD.FRAME_ANCESTORS)); 1.647 + 1.648 + // construct fake ancestry with CSP applied to the child. 1.649 + // [aChildUri] -> [aParentUri] -> (root/top) 1.650 + // and then test "permitsAncestry" on the child/self docshell. 1.651 + function testPermits(aChildUri, aParentUri, aContentType) { 1.652 + let cspObj = Cc["@mozilla.org/contentsecuritypolicy;1"] 1.653 + .createInstance(Ci.nsIContentSecurityPolicy); 1.654 + cspObj.appendPolicy(testPolicy, aChildUri, false, false); 1.655 + let docshellparent = Cc["@mozilla.org/docshell;1"] 1.656 + .createInstance(Ci.nsIDocShell); 1.657 + let docshellchild = Cc["@mozilla.org/docshell;1"] 1.658 + .createInstance(Ci.nsIDocShell); 1.659 + docshellparent.setCurrentURI(aParentUri); 1.660 + docshellchild.setCurrentURI(aChildUri); 1.661 + docshellparent.addChild(docshellchild); 1.662 + return cspObj.permitsAncestry(docshellchild); 1.663 + }; 1.664 + 1.665 + // check parent without userpass 1.666 + do_check_true(testPermits(URI("http://username:password@self.com/foo"), 1.667 + URI("http://self.com/bar"))); 1.668 + do_check_true(testPermits(URI("http://user1:pass1@self.com/foo"), 1.669 + URI("http://self.com/bar"))); 1.670 + do_check_true(testPermits(URI("http://self.com/foo"), 1.671 + URI("http://self.com/bar"))); 1.672 + 1.673 + // check parent with userpass 1.674 + do_check_true(testPermits(URI("http://username:password@self.com/foo"), 1.675 + URI("http://username:password@self.com/bar"))); 1.676 + do_check_true(testPermits(URI("http://user1:pass1@self.com/foo"), 1.677 + URI("http://username:password@self.com/bar"))); 1.678 + do_check_true(testPermits(URI("http://self.com/foo"), 1.679 + URI("http://username:password@self.com/bar"))); 1.680 + }); 1.681 + 1.682 +test(function test_CSP_ReportURI_parsing() { 1.683 + var cspr; 1.684 + var SD = CSPRep.SRC_DIRECTIVES_NEW; 1.685 + var self = "http://self.com:34"; 1.686 + var parsedURIs = []; 1.687 + 1.688 + var uri_valid_absolute = self + "/report.py"; 1.689 + var uri_other_host_absolute = "http://foo.org:34/report.py"; 1.690 + var uri_valid_relative = "/report.py"; 1.691 + var uri_valid_relative_expanded = self + uri_valid_relative; 1.692 + var uri_valid_relative2 = "foo/bar/report.py"; 1.693 + var uri_valid_relative2_expanded = self + "/" + uri_valid_relative2; 1.694 + var uri_invalid_relative = "javascript:alert(1)"; 1.695 + var uri_other_scheme_absolute = "https://self.com/report.py"; 1.696 + var uri_other_scheme_and_host_absolute = "https://foo.com/report.py"; 1.697 + 1.698 + cspr = CSPRep.fromStringSpecCompliant("default-src *; report-uri " + uri_valid_absolute, URI(self)); 1.699 + parsedURIs = cspr.getReportURIs().split(/\s+/); 1.700 + do_check_in_array(parsedURIs, uri_valid_absolute); 1.701 + do_check_eq(parsedURIs.length, 1); 1.702 + 1.703 + cspr = CSPRep.fromStringSpecCompliant("default-src *; report-uri " + uri_other_host_absolute, URI(self)); 1.704 + parsedURIs = cspr.getReportURIs().split(/\s+/); 1.705 + do_check_in_array(parsedURIs, uri_other_host_absolute); 1.706 + do_check_eq(parsedURIs.length, 1); // the empty string is in there. 1.707 + 1.708 + cspr = CSPRep.fromStringSpecCompliant("default-src *; report-uri " + uri_invalid_relative, URI(self)); 1.709 + parsedURIs = cspr.getReportURIs().split(/\s+/); 1.710 + do_check_in_array(parsedURIs, ""); 1.711 + do_check_eq(parsedURIs.length, 1); 1.712 + 1.713 + cspr = CSPRep.fromStringSpecCompliant("default-src *; report-uri " + uri_valid_relative, URI(self)); 1.714 + parsedURIs = cspr.getReportURIs().split(/\s+/); 1.715 + do_check_in_array(parsedURIs, uri_valid_relative_expanded); 1.716 + do_check_eq(parsedURIs.length, 1); 1.717 + 1.718 + cspr = CSPRep.fromStringSpecCompliant("default-src *; report-uri " + uri_valid_relative2, URI(self)); 1.719 + parsedURIs = cspr.getReportURIs().split(/\s+/); 1.720 + dump(parsedURIs.length); 1.721 + do_check_in_array(parsedURIs, uri_valid_relative2_expanded); 1.722 + do_check_eq(parsedURIs.length, 1); 1.723 + 1.724 + // make sure cross-scheme reporting works 1.725 + cspr = CSPRep.fromStringSpecCompliant("default-src *; report-uri " + uri_other_scheme_absolute, URI(self)); 1.726 + parsedURIs = cspr.getReportURIs().split(/\s+/); 1.727 + dump(parsedURIs.length); 1.728 + do_check_in_array(parsedURIs, uri_other_scheme_absolute); 1.729 + do_check_eq(parsedURIs.length, 1); 1.730 + 1.731 + // make sure cross-scheme, cross-host reporting works 1.732 + cspr = CSPRep.fromStringSpecCompliant("default-src *; report-uri " + uri_other_scheme_and_host_absolute, URI(self)); 1.733 + parsedURIs = cspr.getReportURIs().split(/\s+/); 1.734 + dump(parsedURIs.length); 1.735 + do_check_in_array(parsedURIs, uri_other_scheme_and_host_absolute); 1.736 + do_check_eq(parsedURIs.length, 1); 1.737 + 1.738 + // combination! 1.739 + cspr = CSPRep.fromStringSpecCompliant("default-src *; report-uri " + 1.740 + uri_valid_relative2 + " " + 1.741 + uri_valid_absolute, URI(self)); 1.742 + parsedURIs = cspr.getReportURIs().split(/\s+/); 1.743 + do_check_in_array(parsedURIs, uri_valid_relative2_expanded); 1.744 + do_check_in_array(parsedURIs, uri_valid_absolute); 1.745 + do_check_eq(parsedURIs.length, 2); 1.746 + 1.747 + cspr = CSPRep.fromStringSpecCompliant("default-src *; report-uri " + 1.748 + uri_valid_relative2 + " " + 1.749 + uri_other_host_absolute + " " + 1.750 + uri_valid_absolute, URI(self)); 1.751 + parsedURIs = cspr.getReportURIs().split(/\s+/); 1.752 + do_check_in_array(parsedURIs, uri_valid_relative2_expanded); 1.753 + do_check_in_array(parsedURIs, uri_other_host_absolute); 1.754 + do_check_in_array(parsedURIs, uri_valid_absolute); 1.755 + do_check_eq(parsedURIs.length, 3); 1.756 + }); 1.757 + 1.758 +test( 1.759 + function test_bug634778_duplicateDirective_Detection() { 1.760 + var cspr; 1.761 + var SD = CSPRep.SRC_DIRECTIVES_OLD; 1.762 + var self = "http://self.com:34"; 1.763 + var firstDomain = "http://first.com"; 1.764 + var secondDomain = "http://second.com"; 1.765 + var thirdDomain = "http://third.com"; 1.766 + 1.767 + // check for duplicate "default-src" directives 1.768 + cspr = CSPRep.fromString("default-src " + self + "; default-src " + 1.769 + firstDomain, URI(self)); 1.770 + do_check_true(cspr.permits(self, SD.DEFAULT_SRC)); 1.771 + do_check_false(cspr.permits(firstDomain, SD.DEFAULT_SRC)); 1.772 + 1.773 + // check for duplicate "allow" directives 1.774 + cspr = CSPRep.fromString("allow " + self + "; allow " + firstDomain, 1.775 + URI(self)); 1.776 + do_check_true(cspr.permits(self, SD.DEFAULT_SRC)); 1.777 + do_check_false(cspr.permits(firstDomain, SD.DEFAULT_SRC)); 1.778 + 1.779 + // check for duplicate "allow" + "default-src" directives 1.780 + cspr = CSPRep.fromString("allow " + self + "; default-src " + firstDomain, 1.781 + URI(self)); 1.782 + do_check_true(cspr.permits(self, SD.DEFAULT_SRC)); 1.783 + do_check_false(cspr.permits(firstDomain, SD.DEFAULT_SRC)); 1.784 + 1.785 + // check for duplicate report-uri directives 1.786 + cspr = CSPRep.fromString("allow *; report-uri " + self + "/report.py; report-uri " 1.787 + + firstDomain + "/report.py", URI(self)); 1.788 + parsedURIs = cspr.getReportURIs().split(/\s+/); 1.789 + do_check_in_array(parsedURIs, self + "/report.py"); 1.790 + do_check_eq(parsedURIs.length, 1); 1.791 + 1.792 + // check for three directives with duplicates 1.793 + cspr = CSPRep.fromString("img-src " + firstDomain + "; default-src " + self 1.794 + + "; img-src " + secondDomain, URI(self)); 1.795 + do_check_true(cspr.permits(firstDomain, SD.IMG_SRC)); 1.796 + do_check_false(cspr.permits(secondDomain, SD.IMG_SRC)); 1.797 + do_check_true(cspr.permits(self, SD.DEFAULT_SRC)); 1.798 + 1.799 + // check for three directives with duplicates 1.800 + cspr = CSPRep.fromString("img-src " + firstDomain + "; default-src " + self 1.801 + + "; img-src " + secondDomain, URI(self)); 1.802 + do_check_true(cspr.permits(firstDomain, SD.IMG_SRC)); 1.803 + do_check_false(cspr.permits(secondDomain, SD.IMG_SRC)); 1.804 + 1.805 + // check for three directives with duplicates 1.806 + cspr = CSPRep.fromString("default-src " + self + "; img-src " + firstDomain 1.807 + + "; img-src " + secondDomain, URI(self)); 1.808 + do_check_true(cspr.permits(firstDomain, SD.IMG_SRC)); 1.809 + do_check_false(cspr.permits(secondDomain, SD.IMG_SRC)); 1.810 + 1.811 + // check for four directives with duplicates 1.812 + cspr = CSPRep.fromString("default-src " + self + "; img-src " + firstDomain 1.813 + + "; img-src " + secondDomain + "; img-src " 1.814 + + thirdDomain, URI(self)); 1.815 + do_check_true(cspr.permits(firstDomain, SD.IMG_SRC)); 1.816 + do_check_false(cspr.permits(secondDomain, SD.IMG_SRC)); 1.817 + do_check_false(cspr.permits(thirdDomain, SD.IMG_SRC)); 1.818 + 1.819 + // check for four directives with two duplicates 1.820 + cspr = CSPRep.fromString("default-src " + self + "; style-src " 1.821 + + firstDomain + "; media-src " + firstDomain 1.822 + + "; media-src " + secondDomain + "; style-src " 1.823 + + thirdDomain, URI(self)); 1.824 + do_check_true(cspr.permits(self, SD.DEFAULT_SRC)); 1.825 + do_check_true(cspr.permits(firstDomain, SD.STYLE_SRC)); 1.826 + do_check_true(cspr.permits(firstDomain, SD.MEDIA_SRC)); 1.827 + do_check_false(cspr.permits(secondDomain, SD.MEDIA_SRC)); 1.828 + do_check_false(cspr.permits(thirdDomain, SD.STYLE_SRC)); 1.829 + }); 1.830 + 1.831 +test( 1.832 + function test_bug672961_withNonstandardSelfPort() { 1.833 + /** 1.834 + * When a protected document has a non-standard port, other host names 1.835 + * listed as sources should inherit the scheme of the protected document 1.836 + * but NOT the port. Other hosts should use the default port for the 1.837 + * inherited scheme. For example, since 443 is default for HTTPS: 1.838 + * 1.839 + * Document with CSP: https://foobar.com:4443 1.840 + * Transmitted policy: 1.841 + * "allow 'self' a.com" 1.842 + * Explicit policy: 1.843 + * "allow https://foobar.com:4443 https://a.com:443" 1.844 + * 1.845 + * This test examines scheme and nonstandard port inheritance. 1.846 + */ 1.847 + 1.848 + var src; 1.849 + src = CSPSource.create("a.com", undefined, "https://foobar.com:4443"); 1.850 + //"src should inherit and require https scheme 1.851 + do_check_false(src.permits("http://a.com")); 1.852 + //"src should inherit scheme 'https'" 1.853 + do_check_true(src.permits("https://a.com")); 1.854 + //"src should get default port 1.855 + do_check_true(src.permits("https://a.com:443")); 1.856 + 1.857 + src = CSPSource.create("http://a.com", undefined, "https://foobar.com:4443"); 1.858 + //"src should require http scheme" 1.859 + do_check_false(src.permits("https://a.com")); 1.860 + //"src should keep scheme 'http'" 1.861 + do_check_true(src.permits("http://a.com")); 1.862 + //"src should inherit default port for 'http'" 1.863 + do_check_true(src.permits("http://a.com:80")); 1.864 + 1.865 + src = CSPSource.create("'self'", undefined, "https://foobar.com:4443"); 1.866 + //"src should inherit nonstandard port from self 1.867 + do_check_true(src.permits("https://foobar.com:4443")); 1.868 + do_check_false(src.permits("https://foobar.com")); 1.869 + do_check_false(src.permits("https://foobar.com:443")); 1.870 + 1.871 + //"src should inherit and require https scheme from self 1.872 + do_check_false(src.permits("http://foobar.com:4443")); 1.873 + do_check_false(src.permits("http://foobar.com")); 1.874 + 1.875 + }); 1.876 + 1.877 +test( 1.878 + function test_bug634773_noneAndStarAreDifferent() { 1.879 + /** 1.880 + * Bug 634773 is that allow * and allow 'none' end up "equal" via 1.881 + * CSPSourceList.prototype.equals(), which is wrong. This tests that 1.882 + * doesn't happen. 1.883 + */ 1.884 + 1.885 + var p_none = CSPSourceList.fromString("'none'", undefined, "http://foo.com", false); 1.886 + var p_all = CSPSourceList.fromString("*", undefined, "http://foo.com", false); 1.887 + var p_one = CSPSourceList.fromString("bar.com", undefined, "http://foo.com", false); 1.888 + 1.889 + do_check_false(p_none.equals(p_all)); 1.890 + do_check_false(p_none.equals(p_one)); 1.891 + do_check_false(p_all.equals(p_none)); 1.892 + do_check_false(p_all.equals(p_one)); 1.893 + 1.894 + do_check_true(p_all.permits("http://bar.com")); 1.895 + do_check_true(p_one.permits("http://bar.com")); 1.896 + do_check_false(p_none.permits("http://bar.com")); 1.897 + }); 1.898 + 1.899 + 1.900 +test( 1.901 + function test_bug764937_defaultSrcMissing() { 1.902 + var cspObjSpecCompliant = Cc["@mozilla.org/contentsecuritypolicy;1"] 1.903 + .createInstance(Ci.nsIContentSecurityPolicy); 1.904 + var cspObjOld = Cc["@mozilla.org/contentsecuritypolicy;1"] 1.905 + .createInstance(Ci.nsIContentSecurityPolicy); 1.906 + var selfURI = URI("http://self.com/"); 1.907 + 1.908 + function testPermits(cspObj, aUri, aContentType) { 1.909 + return cspObj.shouldLoad(aContentType, aUri, null, null, null, null) 1.910 + == Ci.nsIContentPolicy.ACCEPT; 1.911 + }; 1.912 + 1.913 + const policy = "script-src 'self'"; 1.914 + cspObjSpecCompliant.appendPolicy(policy, selfURI, false, true); 1.915 + 1.916 + // Spec-Compliant policy default-src defaults to *. 1.917 + // This means all images are allowed, and only 'self' 1.918 + // script is allowed. 1.919 + do_check_true(testPermits(cspObjSpecCompliant, 1.920 + URI("http://bar.com/foo.png"), 1.921 + Ci.nsIContentPolicy.TYPE_IMAGE)); 1.922 + do_check_true(testPermits(cspObjSpecCompliant, 1.923 + URI("http://self.com/foo.png"), 1.924 + Ci.nsIContentPolicy.TYPE_IMAGE)); 1.925 + do_check_true(testPermits(cspObjSpecCompliant, 1.926 + URI("http://self.com/foo.js"), 1.927 + Ci.nsIContentPolicy.TYPE_SCRIPT)); 1.928 + do_check_false(testPermits(cspObjSpecCompliant, 1.929 + URI("http://bar.com/foo.js"), 1.930 + Ci.nsIContentPolicy.TYPE_SCRIPT)); 1.931 + 1.932 + cspObjOld.appendPolicy(policy, selfURI, false, false); 1.933 + 1.934 + // non-Spec-Compliant policy default-src defaults to 'none' 1.935 + // This means all images are blocked, and so are all scripts (because the 1.936 + // policy is ignored and fails closed). 1.937 + do_check_false(testPermits(cspObjOld, 1.938 + URI("http://bar.com/foo.png"), 1.939 + Ci.nsIContentPolicy.TYPE_IMAGE)); 1.940 + do_check_false(testPermits(cspObjOld, 1.941 + URI("http://self.com/foo.png"), 1.942 + Ci.nsIContentPolicy.TYPE_IMAGE)); 1.943 + do_check_false(testPermits(cspObjOld, 1.944 + URI("http://self.com/foo.js"), 1.945 + Ci.nsIContentPolicy.TYPE_SCRIPT)); 1.946 + do_check_false(testPermits(cspObjOld, 1.947 + URI("http://bar.com/foo.js"), 1.948 + Ci.nsIContentPolicy.TYPE_SCRIPT)); 1.949 + 1.950 + }); 1.951 + 1.952 +test(function test_equals_does_case_insensitive_comparison() { 1.953 + // NOTE: For scheme, host and keyword-host: 1.954 + // (1) compare the same lower-case in two distinct objects 1.955 + // (2) compare upper-case with lower-case inputs 1.956 + // to test case insensitivity. 1.957 + 1.958 + // CSPSource equals ignores case 1.959 + var upperCaseHost = "http://FOO.COM"; 1.960 + var lowerCaseHost = "http://foo.com"; 1.961 + src1 = CSPSource.fromString(lowerCaseHost); 1.962 + src2 = CSPSource.fromString(lowerCaseHost); 1.963 + do_check_true(src1.equals(src2)) 1.964 + src3 = CSPSource.fromString(upperCaseHost); 1.965 + do_check_true(src1.equals(src3)) 1.966 + 1.967 + // CSPHost equals ignores case 1.968 + var upperCaseScheme = "HTTP"; 1.969 + var lowerCaseScheme = "http"; 1.970 + src1 = CSPHost.fromString(lowerCaseScheme); 1.971 + src2 = CSPHost.fromString(lowerCaseScheme); 1.972 + do_check_true(src1.equals(src2)); 1.973 + src3 = CSPHost.fromString(upperCaseScheme); 1.974 + do_check_true(src1.equals(src3)); 1.975 + 1.976 + // CSPSourceList equals (mainly for testing keywords) 1.977 + var upperCaseKeywords = "'SELF'"; 1.978 + var lowerCaseKeywords = "'self'"; 1.979 + src1 = CSPSourceList.fromString(lowerCaseKeywords); 1.980 + src2 = CSPSourceList.fromString(lowerCaseKeywords); 1.981 + do_check_true(src1.equals(src2)) 1.982 + src3 = CSPSourceList.fromString(upperCaseKeywords); 1.983 + do_check_true(src1.equals(src3)) 1.984 + 1.985 + }); 1.986 + 1.987 +test(function test_csp_permits_case_insensitive() { 1.988 + var cspr; 1.989 + var SD = CSPRep.SRC_DIRECTIVES_NEW; 1.990 + 1.991 + // checks directives can be case-insensitive 1.992 + var selfHost = "http://self.com"; 1.993 + var testPolicy1 = "DEFAULT-src 'self';"; 1.994 + cspr = CSPRep.fromString(testPolicy1, URI(selfHost)); 1.995 + do_check_true(cspr.permits(URI("http://self.com"), SD.DEFAULT_SRC)); 1.996 + 1.997 + // checks hosts can be case-insensitive 1.998 + var testPolicy2 = "default-src 'self' http://FOO.COM"; 1.999 + cspr = CSPRep.fromString(testPolicy2, URI(selfHost)); 1.1000 + do_check_true(cspr.permits(URI("http://foo.com"), SD.DEFAULT_SRC)); 1.1001 + 1.1002 + // checks schemes can be case-insensitive 1.1003 + var testPolicy3 = "default-src 'self' HTTP://foo.com"; 1.1004 + cspr = CSPRep.fromString(testPolicy3, URI(selfHost)); 1.1005 + do_check_true(cspr.permits(URI("http://foo.com"), SD.DEFAULT_SRC)); 1.1006 + 1.1007 + // checks keywords can be case-insensitive 1.1008 + var testPolicy4 = "default-src 'NONE'"; 1.1009 + cspr = CSPRep.fromString(testPolicy4, URI(selfHost)); 1.1010 + do_check_false(cspr.permits(URI("http://foo.com"), SD.DEFAULT_SRC)); 1.1011 + }); 1.1012 +/* 1.1013 + 1.1014 +test(function test_CSPRep_fromPolicyURI_failswhenmixed() { 1.1015 + var cspr; 1.1016 + var self = "http://localhost:" + POLICY_PORT; 1.1017 + var closed_policy = CSPRep.fromString("allow 'none'"); 1.1018 + var my_uri_policy = "policy-uri " + POLICY_URI; 1.1019 + 1.1020 + //print(" --- Ignore the following two errors if they print ---"); 1.1021 + cspr = CSPRep.fromString("allow *; " + my_uri_policy, URI(self)); 1.1022 + 1.1023 + //"Parsing should fail when 'policy-uri' is mixed with allow directive" 1.1024 + do_check_equivalent(cspr, closed_policy); 1.1025 + cspr = CSPRep.fromString("img-src 'self'; " + my_uri_policy, URI(self)); 1.1026 + 1.1027 + //"Parsing should fail when 'policy-uri' is mixed with other directives" 1.1028 + do_check_equivalent(cspr, closed_policy); 1.1029 + //print(" --- Stop ignoring errors that print ---\n"); 1.1030 + 1.1031 + }); 1.1032 +*/ 1.1033 + 1.1034 +// TODO: test reporting 1.1035 +// TODO: test refinements (?) 1.1036 +// TODO: test 'eval' and 'inline' keywords 1.1037 + 1.1038 +function run_test() { 1.1039 + function policyresponder(request,response) { 1.1040 + response.setStatusLine(request.httpVersion, 200, "OK"); 1.1041 + response.setHeader("Content-Type", "text/csp", false); 1.1042 + response.bodyOutputStream.write(POLICY_FROM_URI, POLICY_FROM_URI.length); 1.1043 + } 1.1044 + //server.registerDirectory("/", nsILocalFileForBasePath); 1.1045 + httpServer.registerPathHandler("/policy", policyresponder); 1.1046 + 1.1047 + for(let i in tests) { 1.1048 + tests[i](); 1.1049 + } 1.1050 + 1.1051 + //teardown 1.1052 + httpServer.stop(function() { }); 1.1053 + do_test_finished(); 1.1054 +} 1.1055 + 1.1056 + 1.1057 +