зеркало из https://github.com/mozilla/gecko-dev.git
Bug 938652 - CSP directives and source expressions should do case-insensitive matching and comparison. r=geekboy
This commit is contained in:
Родитель
1ac93c7ad5
Коммит
618394c4a6
|
@ -306,7 +306,7 @@ CSPRep.fromString = function(aStr, self, reportOnly, docRequest, csp) {
|
|||
dir = dir.trim();
|
||||
if (dir.length < 1) continue;
|
||||
|
||||
var dirname = dir.split(/\s+/)[0];
|
||||
var dirname = dir.split(/\s+/)[0].toLowerCase();
|
||||
var dirvalue = dir.substring(dirname.length).trim();
|
||||
|
||||
if (aCSPR._directives.hasOwnProperty(dirname)) {
|
||||
|
@ -564,7 +564,7 @@ CSPRep.fromStringSpecCompliant = function(aStr, self, reportOnly, docRequest, cs
|
|||
dir = dir.trim();
|
||||
if (dir.length < 1) continue;
|
||||
|
||||
var dirname = dir.split(/\s+/)[0];
|
||||
var dirname = dir.split(/\s+/)[0].toLowerCase();
|
||||
var dirvalue = dir.substring(dirname.length).trim();
|
||||
dirs[dirname] = dirvalue;
|
||||
}
|
||||
|
@ -1003,7 +1003,7 @@ CSPSourceList.fromString = function(aStr, aCSPRep, self, enforceSelfChecks) {
|
|||
slObj._CSPRep = aCSPRep;
|
||||
aStr = aStr.trim();
|
||||
// w3 specifies case insensitive equality
|
||||
if (aStr.toUpperCase() === "'NONE'") {
|
||||
if (aStr.toLowerCase() === "'none'") {
|
||||
slObj._permitAllSources = false;
|
||||
return slObj;
|
||||
}
|
||||
|
@ -1071,7 +1071,7 @@ CSPSourceList.prototype = {
|
|||
// sort both arrays and compare like a zipper
|
||||
// XXX (sid): I think we can make this more efficient
|
||||
var sortfn = function(a,b) {
|
||||
return a.toString() > b.toString();
|
||||
return a.toString.toLowerCase() > b.toString.toLowerCase();
|
||||
};
|
||||
var a_sorted = this._sources.sort(sortfn);
|
||||
var b_sorted = that._sources.sort(sortfn);
|
||||
|
@ -1418,7 +1418,7 @@ CSPSource.fromString = function(aStr, aCSPRep, self, enforceSelfChecks) {
|
|||
return CSPHashSource.fromString(aStr, aCSPRep);
|
||||
|
||||
// check for 'self' (case insensitive)
|
||||
if (aStr.toUpperCase() === "'SELF'") {
|
||||
if (aStr.toLowerCase() === "'self'") {
|
||||
if (!self) {
|
||||
cspError(aCSPRep, CSPLocalizer.getStr("selfKeywordNoSelfData"));
|
||||
return null;
|
||||
|
@ -1429,13 +1429,13 @@ CSPSource.fromString = function(aStr, aCSPRep, self, enforceSelfChecks) {
|
|||
}
|
||||
|
||||
// check for 'unsafe-inline' (case insensitive)
|
||||
if (aStr.toUpperCase() === "'UNSAFE-INLINE'"){
|
||||
if (aStr.toLowerCase() === "'unsafe-inline'"){
|
||||
sObj._allowUnsafeInline = true;
|
||||
return sObj;
|
||||
}
|
||||
|
||||
// check for 'unsafe-eval' (case insensitive)
|
||||
if (aStr.toUpperCase() === "'UNSAFE-EVAL'"){
|
||||
if (aStr.toLowerCase() === "'unsafe-eval'"){
|
||||
sObj._allowUnsafeEval = true;
|
||||
return sObj;
|
||||
}
|
||||
|
@ -1556,7 +1556,7 @@ CSPSource.prototype = {
|
|||
aSource = CSPSource.create(aSource, this._CSPRep);
|
||||
|
||||
// verify scheme
|
||||
if (this.scheme != aSource.scheme)
|
||||
if (this.scheme.toLowerCase() != aSource.scheme.toLowerCase())
|
||||
return false;
|
||||
|
||||
// port is defined in 'this' (undefined means it may not be relevant
|
||||
|
@ -1592,13 +1592,13 @@ CSPSource.prototype = {
|
|||
// 2. ports match
|
||||
// 3. either both hosts are undefined, or one equals the other.
|
||||
if (resolveSelf)
|
||||
return this.scheme === that.scheme
|
||||
return this.scheme.toLowerCase() === that.scheme.toLowerCase()
|
||||
&& this.port === that.port
|
||||
&& (!(this.host || that.host) ||
|
||||
(this.host && this.host.equals(that.host)));
|
||||
|
||||
// otherwise, compare raw (non-self-resolved values)
|
||||
return this._scheme === that._scheme
|
||||
return this._scheme.toLowerCase() === that._scheme.toLowerCase()
|
||||
&& this._port === that._port
|
||||
&& (!(this._host || that._host) ||
|
||||
(this._host && this._host.equals(that._host)));
|
||||
|
@ -1688,7 +1688,9 @@ CSPHost.prototype = {
|
|||
*/
|
||||
permits:
|
||||
function(aHost) {
|
||||
if (!aHost) aHost = CSPHost.fromString("*");
|
||||
if (!aHost) {
|
||||
aHost = CSPHost.fromString("*");
|
||||
}
|
||||
|
||||
if (!(aHost instanceof CSPHost)) {
|
||||
// -- compare CSPHost to String
|
||||
|
@ -1714,7 +1716,8 @@ CSPHost.prototype = {
|
|||
// * Compare from right to left.
|
||||
for (var i=1; i <= thislen; i++) {
|
||||
if (this._segments[thislen-i] != "*" &&
|
||||
(this._segments[thislen-i] != aHost._segments[thatlen-i])) {
|
||||
(this._segments[thislen-i].toLowerCase() !=
|
||||
aHost._segments[thatlen-i].toLowerCase())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -1737,9 +1740,11 @@ CSPHost.prototype = {
|
|||
return false;
|
||||
|
||||
for (var i=0; i<this._segments.length; i++) {
|
||||
if (this._segments[i] != that._segments[i])
|
||||
if (this._segments[i].toLowerCase() !=
|
||||
that._segments[i].toLowerCase()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -916,6 +916,66 @@ test(
|
|||
|
||||
});
|
||||
|
||||
test(function test_equals_does_case_insensitive_comparison() {
|
||||
// NOTE: For scheme, host and keyword-host:
|
||||
// (1) compare the same lower-case in two distinct objects
|
||||
// (2) compare upper-case with lower-case inputs
|
||||
// to test case insensitivity.
|
||||
|
||||
// CSPSource equals ignores case
|
||||
var upperCaseHost = "http://FOO.COM";
|
||||
var lowerCaseHost = "http://foo.com";
|
||||
src1 = CSPSource.fromString(lowerCaseHost);
|
||||
src2 = CSPSource.fromString(lowerCaseHost);
|
||||
do_check_true(src1.equals(src2))
|
||||
src3 = CSPSource.fromString(upperCaseHost);
|
||||
do_check_true(src1.equals(src3))
|
||||
|
||||
// CSPHost equals ignores case
|
||||
var upperCaseScheme = "HTTP";
|
||||
var lowerCaseScheme = "http";
|
||||
src1 = CSPHost.fromString(lowerCaseScheme);
|
||||
src2 = CSPHost.fromString(lowerCaseScheme);
|
||||
do_check_true(src1.equals(src2));
|
||||
src3 = CSPHost.fromString(upperCaseScheme);
|
||||
do_check_true(src1.equals(src3));
|
||||
|
||||
// CSPSourceList equals (mainly for testing keywords)
|
||||
var upperCaseKeywords = "'SELF'";
|
||||
var lowerCaseKeywords = "'self'";
|
||||
src1 = CSPSourceList.fromString(lowerCaseKeywords);
|
||||
src2 = CSPSourceList.fromString(lowerCaseKeywords);
|
||||
do_check_true(src1.equals(src2))
|
||||
src3 = CSPSourceList.fromString(upperCaseKeywords);
|
||||
do_check_true(src1.equals(src3))
|
||||
|
||||
});
|
||||
|
||||
test(function test_csp_permits_case_insensitive() {
|
||||
var cspr;
|
||||
var SD = CSPRep.SRC_DIRECTIVES_NEW;
|
||||
|
||||
// checks directives can be case-insensitive
|
||||
var selfHost = "http://self.com";
|
||||
var testPolicy1 = "DEFAULT-src 'self';";
|
||||
cspr = CSPRep.fromString(testPolicy1, URI(selfHost));
|
||||
do_check_true(cspr.permits(URI("http://self.com"), SD.DEFAULT_SRC));
|
||||
|
||||
// checks hosts can be case-insensitive
|
||||
var testPolicy2 = "default-src 'self' http://FOO.COM";
|
||||
cspr = CSPRep.fromString(testPolicy2, URI(selfHost));
|
||||
do_check_true(cspr.permits(URI("http://foo.com"), SD.DEFAULT_SRC));
|
||||
|
||||
// checks schemes can be case-insensitive
|
||||
var testPolicy3 = "default-src 'self' HTTP://foo.com";
|
||||
cspr = CSPRep.fromString(testPolicy3, URI(selfHost));
|
||||
do_check_true(cspr.permits(URI("http://foo.com"), SD.DEFAULT_SRC));
|
||||
|
||||
// checks keywords can be case-insensitive
|
||||
var testPolicy4 = "default-src 'NONE'";
|
||||
cspr = CSPRep.fromString(testPolicy4, URI(selfHost));
|
||||
do_check_false(cspr.permits(URI("http://foo.com"), SD.DEFAULT_SRC));
|
||||
});
|
||||
/*
|
||||
|
||||
test(function test_CSPRep_fromPolicyURI_failswhenmixed() {
|
||||
|
|
Загрузка…
Ссылка в новой задаче