Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

Fix sce context #15039

Merged
merged 8 commits into from
Aug 26, 2016
14 changes: 10 additions & 4 deletions src/ng/compile.js
Original file line number Diff line number Diff line change
Expand Up @@ -3151,13 +3151,19 @@ 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. Note that track src allows files
// containing CSS, so leave that to RESOURCE_URL level.
if (attrNormalizedName === 'src' || attrNormalizedName === 'ngSrc') {
if (['img', 'video', 'audio', 'source'].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;
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/ng/sce.js
Original file line number Diff line number Diff line change
Expand Up @@ -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. |
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

<a href= and <img src= sanitize their urls and don't constitute an SCE context

Is the same true for <audio/video/source src=?
/cc @rjamet

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess that depends on what "sanitize" means. The important part seems to be that in the src attribute, no script execution is possible, that's why we can remove the url context. But Idk if that means sanitization

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These three won't be sanitized, but as far as we know there's no browser that both supports these tags, and runs javascript: URLs there.

* | `$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>
Expand Down
30 changes: 28 additions & 2 deletions test/ng/compileSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -10138,8 +10138,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);
Expand All @@ -10152,6 +10151,33 @@ 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"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is that so? IE 9 supports video & audio elements.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But not if we try to do it like we do in the test. It's possible that we need different HTML for it to work: http://stackoverflow.com/questions/7358689/audio-tag-not-working-in-ie9

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The OP answered that adding a DOCTYPE helped. Do our test cases not have a DOCTYPE? If that's the case we should definitely add them, we should make sure all our tests are running in standards mode, not quirks mode that we don't even officially support AFAIK.

All IE versions older than 10 in quirks mode invoke a separate engine simulating IE 5.5 and, as a consequence, missing features from newer versions (including <video> and <audio>, obviously).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've looked at a couple of pages used for e2e tests and they all have a DOCTYPE. The template used by Karma also specifies a DOCTYPE. So this shouldn't be a problem.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe it's because of this? videojs/video.js#290 (comment)

if (!msie || msie > 9) {
they('should NOT require trusted values for $prop src', ['video', 'audio', 'source'],
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');
});
});
}
});

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()';
Expand Down