diff --git a/src/components/tooltip/tooltip.js b/src/components/tooltip/tooltip.js index 1fd0d775cd6..690680f06f0 100644 --- a/src/components/tooltip/tooltip.js +++ b/src/components/tooltip/tooltip.js @@ -104,8 +104,9 @@ function MdTooltipDirective($timeout, $window, $$rAF, $document, $interpolate, function addAriaLabel(override) { if (override || !parent.attr('aria-label')) { - var rawText = override || element.text().trim(); - var interpolatedText = $interpolate(rawText)(parent.scope()); + // Only interpolate the text from the HTML element because otherwise the custom text + // could be interpolated twice and cause XSS violations. + var interpolatedText = override || $interpolate(element.text().trim())(parent.scope); parent.attr('aria-label', interpolatedText); } } diff --git a/src/components/tooltip/tooltip.spec.js b/src/components/tooltip/tooltip.spec.js index 6b9cf6bf0d7..ee4b3b635bc 100644 --- a/src/components/tooltip/tooltip.spec.js +++ b/src/components/tooltip/tooltip.spec.js @@ -102,6 +102,26 @@ describe('MdTooltip Component', function() { expect(element.attr('aria-label')).toBe('test 2'); }); + + it('should not interpolate interpolated values', function() { + buildTooltip( + '' + + '{{ testModel.ariaTest }}' + + '' + ); + + $rootScope.$apply(function() { + $rootScope.testModel.ariaTest = 'test {{1+1}}'; + }); + + expect(element.attr('aria-label')).toBe('test {{1+1}}'); + + $rootScope.$apply(function() { + $rootScope.testModel.ariaTest = 'test {{1+1336}}'; + }); + + expect(element.attr('aria-label')).toBe('test {{1+1336}}'); + }); it('should not set parent to items with no pointer events', inject(function($window) {