fix($compile): lower the $sce context for src on video, audio, source, and track
Previously, video, audio, source, and track sources were $sce.RESOURCE_URL. This is not justified as no attacks (script execution) are possible through these attributes as far as we can tell. Angular2 also uses the same categorization. This change is not breaking, and uses of $sce.trustAsResourceUrl before assigning to src or ng-src attributes will just be silently ignored. This has also been given a LGTM by @mprobst via email. PR (#15039) Closes #14019
This commit is contained in:
+9
-4
@@ -3180,13 +3180,18 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
||||
return $sce.HTML;
|
||||
}
|
||||
var tag = nodeName_(node);
|
||||
// All tags with src attributes require a RESOURCE_URL value, except for
|
||||
// img and various html5 media tags.
|
||||
if (attrNormalizedName === 'src' || attrNormalizedName === 'ngSrc') {
|
||||
if (['img', 'video', 'audio', 'source', 'track'].indexOf(tag) === -1) {
|
||||
return $sce.RESOURCE_URL;
|
||||
}
|
||||
// maction[xlink:href] can source SVG. It's not limited to <maction>.
|
||||
if (attrNormalizedName === 'xlinkHref' ||
|
||||
} else if (attrNormalizedName === 'xlinkHref' ||
|
||||
(tag === 'form' && attrNormalizedName === 'action') ||
|
||||
// links can be stylesheets or imports, which can run script in the current origin
|
||||
(tag === 'link' && attrNormalizedName === 'href') ||
|
||||
(tag !== 'img' && (attrNormalizedName === 'src' ||
|
||||
attrNormalizedName === 'ngSrc'))) {
|
||||
(tag === 'link' && attrNormalizedName === 'href')
|
||||
) {
|
||||
return $sce.RESOURCE_URL;
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -537,7 +537,7 @@ function $SceDelegateProvider() {
|
||||
* | `$sce.HTML` | For HTML that's safe to source into the application. The {@link ng.directive:ngBindHtml ngBindHtml} directive uses this context for bindings. If an unsafe value is encountered and the {@link ngSanitize $sanitize} module is present this will sanitize the value instead of throwing an error. |
|
||||
* | `$sce.CSS` | For CSS that's safe to source into the application. Currently unused. Feel free to use it in your own directives. |
|
||||
* | `$sce.URL` | For URLs that are safe to follow as links. Currently unused (`<a href=` and `<img src=` sanitize their urls and don't constitute an SCE context. |
|
||||
* | `$sce.RESOURCE_URL` | For URLs that are not only safe to follow as links, but whose contents are also safe to include in your application. Examples include `ng-include`, `src` / `ngSrc` bindings for tags other than `IMG` (e.g. `IFRAME`, `OBJECT`, etc.) <br><br>Note that `$sce.RESOURCE_URL` makes a stronger statement about the URL than `$sce.URL` does and therefore contexts requiring values trusted for `$sce.RESOURCE_URL` can be used anywhere that values trusted for `$sce.URL` are required. |
|
||||
* | `$sce.RESOURCE_URL` | For URLs that are not only safe to follow as links, but whose contents are also safe to include in your application. Examples include `ng-include`, `src` / `ngSrc` bindings for tags other than `IMG`, `VIDEO`, `AUDIO` and `SOURCE` (e.g. `IFRAME`, `OBJECT`, etc.) <br><br>Note that `$sce.RESOURCE_URL` makes a stronger statement about the URL than `$sce.URL` does and therefore contexts requiring values trusted for `$sce.RESOURCE_URL` can be used anywhere that values trusted for `$sce.URL` are required. |
|
||||
* | `$sce.JS` | For JavaScript that is safe to execute in your application's context. Currently unused. Feel free to use it in your own directives. |
|
||||
*
|
||||
* ## Format of items in {@link ng.$sceDelegateProvider#resourceUrlWhitelist resourceUrlWhitelist}/{@link ng.$sceDelegateProvider#resourceUrlBlacklist Blacklist} <a name="resourceUrlPatternItem"></a>
|
||||
|
||||
+48
-2
@@ -10219,8 +10219,7 @@ describe('$compile', function() {
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
describe('img[src] sanitization', function() {
|
||||
describe('*[src] context requirement', function() {
|
||||
|
||||
it('should NOT require trusted values for img src', inject(function($rootScope, $compile, $sce) {
|
||||
element = $compile('<img src="{{testUrl}}"></img>')($rootScope);
|
||||
@@ -10233,6 +10232,53 @@ describe('$compile', function() {
|
||||
expect(element.attr('src')).toEqual('http://example.com/image2.png');
|
||||
}));
|
||||
|
||||
// IE9 rejects the video / audio tag with "Error: Not implemented" and the source tag with
|
||||
// "Unable to get value of the property 'childNodes': object is null or undefined"
|
||||
if (!msie || msie > 9) {
|
||||
they('should NOT require trusted values for $prop src', ['video', 'audio'],
|
||||
function(tag) {
|
||||
inject(function($rootScope, $compile, $sce) {
|
||||
element = $compile('<' + tag + ' src="{{testUrl}}"></' + tag + '>')($rootScope);
|
||||
$rootScope.testUrl = 'http://example.com/image.mp4';
|
||||
$rootScope.$digest();
|
||||
expect(element.attr('src')).toEqual('http://example.com/image.mp4');
|
||||
|
||||
// But it should accept trusted values anyway.
|
||||
$rootScope.testUrl = $sce.trustAsUrl('http://example.com/image2.mp4');
|
||||
$rootScope.$digest();
|
||||
expect(element.attr('src')).toEqual('http://example.com/image2.mp4');
|
||||
|
||||
// and trustedResourceUrls for retrocompatibility
|
||||
$rootScope.testUrl = $sce.trustAsResourceUrl('http://example.com/image3.mp4');
|
||||
$rootScope.$digest();
|
||||
expect(element.attr('src')).toEqual('http://example.com/image3.mp4');
|
||||
});
|
||||
});
|
||||
|
||||
they('should NOT require trusted values for $prop src', ['source', 'track'],
|
||||
function(tag) {
|
||||
inject(function($rootScope, $compile, $sce) {
|
||||
element = $compile('<video><' + tag + ' src="{{testUrl}}"></' + tag + '></video>')($rootScope);
|
||||
$rootScope.testUrl = 'http://example.com/image.mp4';
|
||||
$rootScope.$digest();
|
||||
expect(element.find(tag).attr('src')).toEqual('http://example.com/image.mp4');
|
||||
|
||||
// But it should accept trusted values anyway.
|
||||
$rootScope.testUrl = $sce.trustAsUrl('http://example.com/image2.mp4');
|
||||
$rootScope.$digest();
|
||||
expect(element.find(tag).attr('src')).toEqual('http://example.com/image2.mp4');
|
||||
|
||||
// and trustedResourceUrls for retrocompatibility
|
||||
$rootScope.testUrl = $sce.trustAsResourceUrl('http://example.com/image3.mp4');
|
||||
$rootScope.$digest();
|
||||
expect(element.find(tag).attr('src')).toEqual('http://example.com/image3.mp4');
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
describe('img[src] sanitization', function() {
|
||||
|
||||
it('should not sanitize attributes other than src', inject(function($compile, $rootScope) {
|
||||
element = $compile('<img title="{{testUrl}}"></img>')($rootScope);
|
||||
$rootScope.testUrl = 'javascript:doEvilStuff()';
|
||||
|
||||
Reference in New Issue
Block a user