From 93ce5923e92f6d2db831d8715ec62734821c70ce Mon Sep 17 00:00:00 2001 From: Chirayu Krishnappa Date: Tue, 24 Sep 2013 18:47:45 -0700 Subject: feat($sce): simpler patterns for $sceDelegateProviders white/blacklists Closes #4006 --- test/ng/sceSpecs.js | 169 ++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 144 insertions(+), 25 deletions(-) (limited to 'test/ng/sceSpecs.js') diff --git a/test/ng/sceSpecs.js b/test/ng/sceSpecs.js index 1eb382f6..7a309f95 100644 --- a/test/ng/sceSpecs.js +++ b/test/ng/sceSpecs.js @@ -288,32 +288,151 @@ describe('SCE', function() { '$sce', 'insecurl', 'Blocked loading resource from url not allowed by $sceDelegate policy. URL: foo'); })); - it('should support custom regex', runTest( - { - whiteList: [/^http:\/\/example\.com.*/], - blackList: [] - }, function($sce) { - expect($sce.getTrustedResourceUrl('http://example.com/foo')).toEqual('http://example.com/foo'); - expect(function() { $sce.getTrustedResourceUrl('https://example.com/foo'); }).toThrowMinErr( - '$sce', 'insecurl', 'Blocked loading resource from url not allowed by $sceDelegate policy. URL: https://example.com/foo'); - })); + if (!msie || msie > 8) { + it('should not accept unknown matcher type', function() { + expect(function() { + runTest({whiteList: [{}]}, null)(); + }).toThrowMinErr('$injector', 'modulerr', new RegExp( + /Failed to instantiate module function ?\(\$sceDelegateProvider\) due to:\n/.source + + /[^[]*\[\$sce:imatcher\] Matchers may only be "self", string patterns or RegExp objects/.source)); + }); + } - it('should support the special string "self" in whitelist', runTest( - { - whiteList: ['self'], - blackList: [] - }, function($sce) { - expect($sce.getTrustedResourceUrl('foo')).toEqual('foo'); - })); + describe('adjustMatcher', function() { + it('should rewrite regex into regex and add ^ & $ on either end', function() { + expect(adjustMatcher(/a.*b/).exec('a.b')).not.toBeNull(); + expect(adjustMatcher(/a.*b/).exec('-a.b-')).toBeNull(); + // Adding ^ & $ onto a regex that already had them should also work. + expect(adjustMatcher(/^a.*b$/).exec('a.b')).not.toBeNull(); + expect(adjustMatcher(/^a.*b$/).exec('-a.b-')).toBeNull(); + }); + }); - it('should support the special string "self" in blacklist', runTest( - { - whiteList: [/.*/], - blackList: ['self'] - }, function($sce) { - expect(function() { $sce.getTrustedResourceUrl('foo'); }).toThrowMinErr( - '$sce', 'insecurl', 'Blocked loading resource from url not allowed by $sceDelegate policy. URL: foo'); - })); + describe('regex matcher', function() { + it('should support custom regex', runTest( + { + whiteList: [/^http:\/\/example\.com\/.*/], + blackList: [] + }, function($sce) { + expect($sce.getTrustedResourceUrl('http://example.com/foo')).toEqual('http://example.com/foo'); + // must match entire regex + expect(function() { $sce.getTrustedResourceUrl('https://example.com/foo'); }).toThrowMinErr( + '$sce', 'insecurl', 'Blocked loading resource from url not allowed by $sceDelegate policy. URL: https://example.com/foo'); + // https doesn't match (mismatched protocol.) + expect(function() { $sce.getTrustedResourceUrl('https://example.com/foo'); }).toThrowMinErr( + '$sce', 'insecurl', 'Blocked loading resource from url not allowed by $sceDelegate policy. URL: https://example.com/foo'); + })); + + it('should match entire regex', runTest( + { + whiteList: [/https?:\/\/example\.com\/foo/], + blackList: [] + }, function($sce) { + expect($sce.getTrustedResourceUrl('http://example.com/foo')).toEqual('http://example.com/foo'); + expect($sce.getTrustedResourceUrl('https://example.com/foo')).toEqual('https://example.com/foo'); + expect(function() { $sce.getTrustedResourceUrl('http://example.com/fo'); }).toThrowMinErr( + '$sce', 'insecurl', 'Blocked loading resource from url not allowed by $sceDelegate policy. URL: http://example.com/fo'); + // Suffix not allowed even though original regex does not contain an ending $. + expect(function() { $sce.getTrustedResourceUrl('http://example.com/foo2'); }).toThrowMinErr( + '$sce', 'insecurl', 'Blocked loading resource from url not allowed by $sceDelegate policy. URL: http://example.com/foo2'); + // Prefix not allowed even though original regex does not contain a leading ^. + expect(function() { $sce.getTrustedResourceUrl('xhttp://example.com/foo'); }).toThrowMinErr( + '$sce', 'insecurl', 'Blocked loading resource from url not allowed by $sceDelegate policy. URL: xhttp://example.com/foo'); + })); + }); + + describe('string matchers', function() { + it('should support strings as matchers', runTest( + { + whiteList: ['http://example.com/foo'], + blackList: [] + }, function($sce) { + expect($sce.getTrustedResourceUrl('http://example.com/foo')).toEqual('http://example.com/foo'); + // "." is not a special character like in a regex. + expect(function() { $sce.getTrustedResourceUrl('http://example-com/foo'); }).toThrowMinErr( + '$sce', 'insecurl', 'Blocked loading resource from url not allowed by $sceDelegate policy. URL: http://example-com/foo'); + // You can match a prefix. + expect(function() { $sce.getTrustedResourceUrl('http://example.com/foo2'); }).toThrowMinErr( + '$sce', 'insecurl', 'Blocked loading resource from url not allowed by $sceDelegate policy. URL: http://example.com/foo2'); + // You can match a suffix. + expect(function() { $sce.getTrustedResourceUrl('xhttp://example.com/foo'); }).toThrowMinErr( + '$sce', 'insecurl', 'Blocked loading resource from url not allowed by $sceDelegate policy. URL: xhttp://example.com/foo'); + })); + + it('should support the * wildcard', runTest( + { + whiteList: ['http://example.com/foo*'], + blackList: [] + }, function($sce) { + expect($sce.getTrustedResourceUrl('http://example.com/foo')).toEqual('http://example.com/foo'); + // The * wildcard should match extra characters. + expect($sce.getTrustedResourceUrl('http://example.com/foo-bar')).toEqual('http://example.com/foo-bar'); + // The * wildcard does not match ':' + expect(function() { $sce.getTrustedResourceUrl('http://example-com/foo:bar'); }).toThrowMinErr( + '$sce', 'insecurl', 'Blocked loading resource from url not allowed by $sceDelegate policy. URL: http://example-com/foo:bar'); + // The * wildcard does not match '/' + expect(function() { $sce.getTrustedResourceUrl('http://example-com/foo/bar'); }).toThrowMinErr( + '$sce', 'insecurl', 'Blocked loading resource from url not allowed by $sceDelegate policy. URL: http://example-com/foo/bar'); + // The * wildcard does not match '.' + expect(function() { $sce.getTrustedResourceUrl('http://example-com/foo.bar'); }).toThrowMinErr( + '$sce', 'insecurl', 'Blocked loading resource from url not allowed by $sceDelegate policy. URL: http://example-com/foo.bar'); + // The * wildcard does not match '?' + expect(function() { $sce.getTrustedResourceUrl('http://example-com/foo?bar'); }).toThrowMinErr( + '$sce', 'insecurl', 'Blocked loading resource from url not allowed by $sceDelegate policy. URL: http://example-com/foo?bar'); + // The * wildcard does not match '&' + expect(function() { $sce.getTrustedResourceUrl('http://example-com/foo&bar'); }).toThrowMinErr( + '$sce', 'insecurl', 'Blocked loading resource from url not allowed by $sceDelegate policy. URL: http://example-com/foo&bar'); + // The * wildcard does not match ';' + expect(function() { $sce.getTrustedResourceUrl('http://example-com/foo;bar'); }).toThrowMinErr( + '$sce', 'insecurl', 'Blocked loading resource from url not allowed by $sceDelegate policy. URL: http://example-com/foo;bar'); + })); + + it('should support the ** wildcard', runTest( + { + whiteList: ['http://example.com/foo**'], + blackList: [] + }, function($sce) { + expect($sce.getTrustedResourceUrl('http://example.com/foo')).toEqual('http://example.com/foo'); + // The ** wildcard should match extra characters. + expect($sce.getTrustedResourceUrl('http://example.com/foo-bar')).toEqual('http://example.com/foo-bar'); + // The ** wildcard accepts the ':/.?&' characters. + expect($sce.getTrustedResourceUrl('http://example.com/foo:1/2.3?4&5-6')).toEqual('http://example.com/foo:1/2.3?4&5-6'); + })); + + // TODO(chirayu): This throws a very helpful TypeError exception - "Object doesn't support + // this property or method". Tracing using the debugger on IE8 developer tools shows me one + // catch(e) block where the exception is correct, but jumping up to the parent catch block has + // the TypeError exception. I've been unable to repro this outside this snippet or figure out + // why this is happening. Until then, this test doesn't run on IE8. + if (!msie || msie > 8) { + it('should not accept *** in the string', function() { + expect(function() { + runTest({whiteList: ['http://***']}, null)(); + }).toThrowMinErr('$injector', 'modulerr', new RegExp( + /Failed to instantiate module function ?\(\$sceDelegateProvider\) due to:\n/.source + + /[^[]*\[\$sce:iwcard\] Illegal sequence \*\*\* in string matcher\. String: http:\/\/\*\*\*/.source)); + }); + } + }); + + describe('"self" matcher', function() { + it('should support the special string "self" in whitelist', runTest( + { + whiteList: ['self'], + blackList: [] + }, function($sce) { + expect($sce.getTrustedResourceUrl('foo')).toEqual('foo'); + })); + + it('should support the special string "self" in blacklist', runTest( + { + whiteList: [/.*/], + blackList: ['self'] + }, function($sce) { + expect(function() { $sce.getTrustedResourceUrl('foo'); }).toThrowMinErr( + '$sce', 'insecurl', 'Blocked loading resource from url not allowed by $sceDelegate policy. URL: foo'); + })); + }); it('should have blacklist override the whitelist', runTest( { @@ -327,7 +446,7 @@ describe('SCE', function() { it('should support multiple items in both lists', runTest( { whiteList: [/^http:\/\/example.com\/1$/, /^http:\/\/example.com\/2$/, /^http:\/\/example.com\/3$/, 'self'], - blackList: [/^http:\/\/example.com\/3$/, /open_redirect/], + blackList: [/^http:\/\/example.com\/3$/, /.*\/open_redirect/], }, function($sce) { expect($sce.getTrustedResourceUrl('same_domain')).toEqual('same_domain'); expect($sce.getTrustedResourceUrl('http://example.com/1')).toEqual('http://example.com/1'); -- cgit v1.2.3