Loading content/base/src/CSPUtils.jsm +24 −22 Original line number Diff line number Diff line Loading @@ -886,20 +886,18 @@ CSPSource.fromURI = function(aURI, self, enforceSelfChecks) { // for port. In fact, there's no way to represent "*" differently than // a blank port in an nsURI, since "*" turns into -1, and so does an // absence of port declaration. // port is never inherited from self -- this gets too confusing. // Instead, whatever scheme is used (an explicit one or the inherited // one) dictates the port if no port is explicitly stated. // Set it to undefined here and the default port will be resolved in the // getter for .port. sObj._port = undefined; try { // if there's no port, an exception will get thrown // (NS_ERROR_FAILURE) if (aURI.port > 0) { sObj._port = aURI.port; } else { // port is never inherited from self -- this gets too confusing. // Instead, whatever scheme is used (an explicit one or the inherited // one) dictates the port if no port is explicitly stated. if (sObj._scheme) { sObj._port = gIoService.getProtocolHandler(sObj._scheme).defaultPort; if (sObj._port < 1) sObj._port = undefined; } } } catch(e) { sObj._port = undefined; Loading Loading @@ -948,8 +946,8 @@ CSPSource.fromString = function(aStr, self, enforceSelfChecks) { CSPError("self keyword used, but no self data specified"); return null; } sObj._isSelf = true; sObj._self = self.clone(); sObj._isSelf = true; return sObj; } Loading Loading @@ -1079,35 +1077,39 @@ CSPSource.validSchemeName = function(aStr) { CSPSource.prototype = { get scheme () { if (this._isSelf && this._self) return this._self.scheme; if (!this._scheme && this._self) return this._self.scheme; return this._scheme; }, get host () { if (this._isSelf && this._self) return this._self.host; if (!this._host && this._self) return this._self.host; return this._host; }, /** * If 'self' has port hard-defined, and this doesn't have a port * hard-defined, use the self's port. Otherwise, if both are implicit, * resolve default port for this scheme. * If this doesn't have a nonstandard port (hard-defined), use the default * port for this source's scheme. Should never inherit port from 'self'. */ get port () { if (this._isSelf && this._self) return this._self.port; if (this._port) return this._port; // if no port, get the default port for the scheme. if (this._scheme) { // if no port, get the default port for the scheme // (which may be inherited from 'self') if (this.scheme) { try { var port = gIoService.getProtocolHandler(this._scheme).defaultPort; var port = gIoService.getProtocolHandler(this.scheme).defaultPort; if (port > 0) return port; } catch(e) { // if any errors happen, fail gracefully. } } // if there was no scheme (and thus no default scheme), return self.port if (this._self && this._self.port) return this._self.port; return undefined; }, Loading @@ -1121,12 +1123,12 @@ CSPSource.prototype = { return this._self.toString(); var s = ""; if (this._scheme) s = s + this._scheme + "://"; if (this.scheme) s = s + this.scheme + "://"; if (this._host) s = s + this._host; if (this._port) s = s + ":" + this._port; if (this.port) s = s + ":" + this.port; return s; }, Loading content/base/test/unit/test_csputils.js +47 −2 Original line number Diff line number Diff line Loading @@ -271,7 +271,7 @@ test( test( function test_CSPSourceList_fromString_twohost() { var str = "foo.bar:21 https://ras.bar"; var parsed = "foo.bar:21 https://ras.bar"; var parsed = "http://foo.bar:21 https://ras.bar:443"; var sd = CSPSourceList.fromString(str, "http://self.com:80"); //"two-host list should parse" do_check_neq(null,sd); Loading Loading @@ -482,7 +482,6 @@ test(function test_CSPRep_fromString_withself() { //"img-src does not enforce default rule, 'self'. do_check_false(cspr.permits("https://foo.com:400", SD.IMG_SRC)); //"img-src does not allow self CSPdebug(cspr); do_check_true(cspr.permits(self, SD.IMG_SRC)); //"script-src is too relaxed do_check_false(cspr.permits("http://evil.com", SD.SCRIPT_SRC)); Loading Loading @@ -577,6 +576,52 @@ test(function test_CSP_ReportURI_parsing() { do_check_eq(parsedURIs.length, 2); }); test( function test_bug672961_withNonstandardSelfPort() { /** * When a protected document has a non-standard port, other host names * listed as sources should inherit the scheme of the protected document * but NOT the port. Other hosts should use the default port for the * inherited scheme. For example, since 443 is default for HTTPS: * * Document with CSP: https://foobar.com:4443 * Transmitted policy: * "allow 'self' a.com" * Explicit policy: * "allow https://foobar.com:4443 https://a.com:443" * * This test examines scheme and nonstandard port inheritance. */ var src; src = CSPSource.create("a.com", "https://foobar.com:4443"); //"src should inherit and require https scheme do_check_false(src.permits("http://a.com")); //"src should inherit scheme 'https'" do_check_true(src.permits("https://a.com")); //"src should get default port do_check_true(src.permits("https://a.com:443")); src = CSPSource.create("http://a.com", "https://foobar.com:4443"); //"src should require http scheme" do_check_false(src.permits("https://a.com")); //"src should keep scheme 'http'" do_check_true(src.permits("http://a.com")); //"src should inherit default port for 'http'" do_check_true(src.permits("http://a.com:80")); src = CSPSource.create("'self'", "https://foobar.com:4443"); //"src should inherit nonstandard port from self do_check_true(src.permits("https://foobar.com:4443")); do_check_false(src.permits("https://foobar.com")); do_check_false(src.permits("https://foobar.com:443")); //"src should inherit and require https scheme from self do_check_false(src.permits("http://foobar.com:4443")); do_check_false(src.permits("http://foobar.com")); }); /* test(function test_CSPRep_fromPolicyURI_failswhenmixed() { Loading Loading
content/base/src/CSPUtils.jsm +24 −22 Original line number Diff line number Diff line Loading @@ -886,20 +886,18 @@ CSPSource.fromURI = function(aURI, self, enforceSelfChecks) { // for port. In fact, there's no way to represent "*" differently than // a blank port in an nsURI, since "*" turns into -1, and so does an // absence of port declaration. // port is never inherited from self -- this gets too confusing. // Instead, whatever scheme is used (an explicit one or the inherited // one) dictates the port if no port is explicitly stated. // Set it to undefined here and the default port will be resolved in the // getter for .port. sObj._port = undefined; try { // if there's no port, an exception will get thrown // (NS_ERROR_FAILURE) if (aURI.port > 0) { sObj._port = aURI.port; } else { // port is never inherited from self -- this gets too confusing. // Instead, whatever scheme is used (an explicit one or the inherited // one) dictates the port if no port is explicitly stated. if (sObj._scheme) { sObj._port = gIoService.getProtocolHandler(sObj._scheme).defaultPort; if (sObj._port < 1) sObj._port = undefined; } } } catch(e) { sObj._port = undefined; Loading Loading @@ -948,8 +946,8 @@ CSPSource.fromString = function(aStr, self, enforceSelfChecks) { CSPError("self keyword used, but no self data specified"); return null; } sObj._isSelf = true; sObj._self = self.clone(); sObj._isSelf = true; return sObj; } Loading Loading @@ -1079,35 +1077,39 @@ CSPSource.validSchemeName = function(aStr) { CSPSource.prototype = { get scheme () { if (this._isSelf && this._self) return this._self.scheme; if (!this._scheme && this._self) return this._self.scheme; return this._scheme; }, get host () { if (this._isSelf && this._self) return this._self.host; if (!this._host && this._self) return this._self.host; return this._host; }, /** * If 'self' has port hard-defined, and this doesn't have a port * hard-defined, use the self's port. Otherwise, if both are implicit, * resolve default port for this scheme. * If this doesn't have a nonstandard port (hard-defined), use the default * port for this source's scheme. Should never inherit port from 'self'. */ get port () { if (this._isSelf && this._self) return this._self.port; if (this._port) return this._port; // if no port, get the default port for the scheme. if (this._scheme) { // if no port, get the default port for the scheme // (which may be inherited from 'self') if (this.scheme) { try { var port = gIoService.getProtocolHandler(this._scheme).defaultPort; var port = gIoService.getProtocolHandler(this.scheme).defaultPort; if (port > 0) return port; } catch(e) { // if any errors happen, fail gracefully. } } // if there was no scheme (and thus no default scheme), return self.port if (this._self && this._self.port) return this._self.port; return undefined; }, Loading @@ -1121,12 +1123,12 @@ CSPSource.prototype = { return this._self.toString(); var s = ""; if (this._scheme) s = s + this._scheme + "://"; if (this.scheme) s = s + this.scheme + "://"; if (this._host) s = s + this._host; if (this._port) s = s + ":" + this._port; if (this.port) s = s + ":" + this.port; return s; }, Loading
content/base/test/unit/test_csputils.js +47 −2 Original line number Diff line number Diff line Loading @@ -271,7 +271,7 @@ test( test( function test_CSPSourceList_fromString_twohost() { var str = "foo.bar:21 https://ras.bar"; var parsed = "foo.bar:21 https://ras.bar"; var parsed = "http://foo.bar:21 https://ras.bar:443"; var sd = CSPSourceList.fromString(str, "http://self.com:80"); //"two-host list should parse" do_check_neq(null,sd); Loading Loading @@ -482,7 +482,6 @@ test(function test_CSPRep_fromString_withself() { //"img-src does not enforce default rule, 'self'. do_check_false(cspr.permits("https://foo.com:400", SD.IMG_SRC)); //"img-src does not allow self CSPdebug(cspr); do_check_true(cspr.permits(self, SD.IMG_SRC)); //"script-src is too relaxed do_check_false(cspr.permits("http://evil.com", SD.SCRIPT_SRC)); Loading Loading @@ -577,6 +576,52 @@ test(function test_CSP_ReportURI_parsing() { do_check_eq(parsedURIs.length, 2); }); test( function test_bug672961_withNonstandardSelfPort() { /** * When a protected document has a non-standard port, other host names * listed as sources should inherit the scheme of the protected document * but NOT the port. Other hosts should use the default port for the * inherited scheme. For example, since 443 is default for HTTPS: * * Document with CSP: https://foobar.com:4443 * Transmitted policy: * "allow 'self' a.com" * Explicit policy: * "allow https://foobar.com:4443 https://a.com:443" * * This test examines scheme and nonstandard port inheritance. */ var src; src = CSPSource.create("a.com", "https://foobar.com:4443"); //"src should inherit and require https scheme do_check_false(src.permits("http://a.com")); //"src should inherit scheme 'https'" do_check_true(src.permits("https://a.com")); //"src should get default port do_check_true(src.permits("https://a.com:443")); src = CSPSource.create("http://a.com", "https://foobar.com:4443"); //"src should require http scheme" do_check_false(src.permits("https://a.com")); //"src should keep scheme 'http'" do_check_true(src.permits("http://a.com")); //"src should inherit default port for 'http'" do_check_true(src.permits("http://a.com:80")); src = CSPSource.create("'self'", "https://foobar.com:4443"); //"src should inherit nonstandard port from self do_check_true(src.permits("https://foobar.com:4443")); do_check_false(src.permits("https://foobar.com")); do_check_false(src.permits("https://foobar.com:443")); //"src should inherit and require https scheme from self do_check_false(src.permits("http://foobar.com:4443")); do_check_false(src.permits("http://foobar.com")); }); /* test(function test_CSPRep_fromPolicyURI_failswhenmixed() { Loading