From fb38f433f61a26fdd25847c7b83d1cbc0a246159 Mon Sep 17 00:00:00 2001 From: Shahar Talmi Date: Tue, 21 Oct 2014 21:53:10 +0300 Subject: [PATCH 1/2] feat($templateRequest): move sce check into templateRequest BREAKING CHANGE: untrusted urls are now blocked by $templateCache --- src/ng/compile.js | 2 +- src/ng/directive/ngInclude.js | 2 +- src/ng/templateRequest.js | 4 ++-- test/ng/templateRequestSpec.js | 9 +++++++++ 4 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/ng/compile.js b/src/ng/compile.js index 4d89e8795e2d..b6316752e144 100644 --- a/src/ng/compile.js +++ b/src/ng/compile.js @@ -2144,7 +2144,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { $compileNode.empty(); - $templateRequest($sce.getTrustedResourceUrl(templateUrl)) + $templateRequest(templateUrl) .then(function(content) { var compileNode, tempTemplateAttrs, $template, childBoundTranscludeFn; diff --git a/src/ng/directive/ngInclude.js b/src/ng/directive/ngInclude.js index e8634993c440..3875d1cb9916 100644 --- a/src/ng/directive/ngInclude.js +++ b/src/ng/directive/ngInclude.js @@ -215,7 +215,7 @@ var ngIncludeDirective = ['$templateRequest', '$anchorScroll', '$animate', '$sce } }; - scope.$watch($sce.parseAsResourceUrl(srcExp), function ngIncludeWatchAction(src) { + scope.$watch(srcExp, function ngIncludeWatchAction(src) { var afterAnimation = function() { if (isDefined(autoScrollExp) && (!autoScrollExp || scope.$eval(autoScrollExp))) { $anchorScroll(); diff --git a/src/ng/templateRequest.js b/src/ng/templateRequest.js index bacf30e1742d..613dfa17287b 100644 --- a/src/ng/templateRequest.js +++ b/src/ng/templateRequest.js @@ -20,7 +20,7 @@ var $compileMinErr = minErr('$compile'); * @property {number} totalPendingRequests total amount of pending template requests being downloaded. */ function $TemplateRequestProvider() { - this.$get = ['$templateCache', '$http', '$q', function($templateCache, $http, $q) { + this.$get = ['$templateCache', '$http', '$q', '$sce', function($templateCache, $http, $q, $sce) { function handleRequestFn(tpl, ignoreRequestError) { var self = handleRequestFn; self.totalPendingRequests++; @@ -40,7 +40,7 @@ function $TemplateRequestProvider() { transformResponse: transformResponse }; - return $http.get(tpl, httpOptions) + return $http.get($sce.getTrustedResourceUrl(tpl), httpOptions) .then(function(response) { self.totalPendingRequests--; return response.data; diff --git a/test/ng/templateRequestSpec.js b/test/ng/templateRequestSpec.js index 2b695d6ab300..834c4dadd339 100644 --- a/test/ng/templateRequestSpec.js +++ b/test/ng/templateRequestSpec.js @@ -16,6 +16,15 @@ describe('$templateRequest', function() { expect(content).toBe('
abc
'); })); + it('should not download templates from untrusted urls', + inject(function($templateRequest) { + expect(function() { + $templateRequest('http://example.com/tpl.html'); + }).toThrowMinErr( + '$sce', 'insecurl', + /Blocked loading resource from url not allowed by \$sceDelegate policy. URL: http:\/\/example.com\/tpl\.html.*/); + })); + it('should cache the request to prevent extra downloads', inject(function($rootScope, $templateRequest, $httpBackend) { From 616bd1eecdee6e9048bb487764b75c44c2bee184 Mon Sep 17 00:00:00 2001 From: Shahar Talmi Date: Wed, 22 Oct 2014 14:41:58 +0200 Subject: [PATCH 2/2] feat($templateRequest): trust url if it is already in cache --- src/ng/templateRequest.js | 6 +++++- test/ng/compileSpec.js | 9 --------- test/ng/templateRequestSpec.js | 13 +++++++++++++ 3 files changed, 18 insertions(+), 10 deletions(-) diff --git a/src/ng/templateRequest.js b/src/ng/templateRequest.js index 613dfa17287b..04250a833bd6 100644 --- a/src/ng/templateRequest.js +++ b/src/ng/templateRequest.js @@ -40,7 +40,11 @@ function $TemplateRequestProvider() { transformResponse: transformResponse }; - return $http.get($sce.getTrustedResourceUrl(tpl), httpOptions) + if (!isDefined($templateCache.get(tpl))) { + tpl = $sce.getTrustedResourceUrl(tpl); + } + + return $http.get(tpl, httpOptions) .then(function(response) { self.totalPendingRequests--; return response.data; diff --git a/test/ng/compileSpec.js b/test/ng/compileSpec.js index 9509e90b6202..6eb9424ed6c9 100755 --- a/test/ng/compileSpec.js +++ b/test/ng/compileSpec.js @@ -1242,15 +1242,6 @@ describe('$compile', function() { } )); - it('should not load cross domain templates by default', inject( - function($compile, $rootScope, $templateCache, $sce) { - expect(function() { - $templateCache.put('http://example.com/should-not-load.html', 'Should not load even if in cache.'); - $compile('
')($rootScope); - }).toThrowMinErr('$sce', 'insecurl', 'Blocked loading resource from url not allowed by $sceDelegate policy. URL: http://example.com/should-not-load.html'); - } - )); - it('should load cross domain templates when trusted', inject( function($compile, $httpBackend, $rootScope, $sce) { $httpBackend.expect('GET', 'http://example.com/trusted-template.html').respond('example.com/trusted_template_contents'); diff --git a/test/ng/templateRequestSpec.js b/test/ng/templateRequestSpec.js index 834c4dadd339..ee50652f7ddd 100644 --- a/test/ng/templateRequestSpec.js +++ b/test/ng/templateRequestSpec.js @@ -25,6 +25,19 @@ describe('$templateRequest', function() { /Blocked loading resource from url not allowed by \$sceDelegate policy. URL: http:\/\/example.com\/tpl\.html.*/); })); + it('should fetch templates from cache even if url is untrusted', + inject(function($rootScope, $templateRequest, $httpBackend, $templateCache) { + + $templateCache.put('http://example.com/tpl.html', '
abc
'); + + var content; + $templateRequest('http://example.com/tpl.html').then(function(html) { content = html; }); + + $rootScope.$digest(); + + expect(content).toBe('
abc
'); + })); + it('should cache the request to prevent extra downloads', inject(function($rootScope, $templateRequest, $httpBackend) {