content/base/test/unit/test_csputils.js

changeset 0
6474c204b198
     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 +

mercurial