refactor(SanitizeUriProvider): remove usages of whitelist

Changes aHrefSanitizationWhitelist to aHrefSanitizationTrustedUri and imgSrcSanitizationWhitelist
to imgSrcSanitizationTrustedUri updating references to use the new symbols.

For the purposes of backward compatibility, the previous symbols are aliased to
the new symbols.
This commit is contained in:
Joey Perrott
2020-09-23 10:53:24 -07:00
committed by Pete Bacon Darwin
parent c953af6b8c
commit 767381020d
6 changed files with 69 additions and 66 deletions
+2 -2
View File
@@ -283,8 +283,8 @@ break.
To fix this you need to ensure that the values used for binding to the affected
`xlink:href` contexts are considered safe URLs, e.g. by whitelisting them in
`$compileProvider`'s `aHrefSanitizationWhitelist` (for `<a>` elements) or
`imgSrcSanitizationWhitelist` (for `<image>` elements).
`$compileProvider`'s `aHrefSanitizationTrustedUri` (for `<a>` elements) or
`imgSrcSanitizationTrustedUri` (for `<image>` elements).
<hr />
+17 -15
View File
@@ -1116,7 +1116,7 @@
* By default, `$sce` will throw an error if it detects untrusted HTML content, and will not bind the
* content.
* However, if you include the {@link ngSanitize ngSanitize module}, it will try to sanitize the
* potentially dangerous HTML, e.g. strip non-whitelisted tags and attributes when binding to
* potentially dangerous HTML, e.g. strip non-trusted tags and attributes when binding to
* `innerHTML`.
*
* @example
@@ -1698,62 +1698,64 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
/**
* @ngdoc method
* @name $compileProvider#aHrefSanitizationWhitelist
* @name $compileProvider#aHrefSanitizationTrustedUri
* @kind function
*
* @description
* Retrieves or overrides the default regular expression that is used for whitelisting of safe
* Retrieves or overrides the default regular expression that is used for determining trusted safe
* urls during a[href] sanitization.
*
* The sanitization is a security measure aimed at preventing XSS attacks via html links.
*
* Any url about to be assigned to a[href] via data-binding is first normalized and turned into
* an absolute url. Afterwards, the url is matched against the `aHrefSanitizationWhitelist`
* an absolute url. Afterwards, the url is matched against the `aHrefSanitizationTrustedUri`
* regular expression. If a match is found, the original url is written into the dom. Otherwise,
* the absolute url is prefixed with `'unsafe:'` string and only then is it written into the DOM.
*
* @param {RegExp=} regexp New regexp to whitelist urls with.
* @param {RegExp=} regexp New regexp to trust urls with.
* @returns {RegExp|ng.$compileProvider} Current RegExp if called without value or self for
* chaining otherwise.
*/
this.aHrefSanitizationWhitelist = function(regexp) {
this.aHrefSanitizationTrustedUri = function(regexp) {
if (isDefined(regexp)) {
$$sanitizeUriProvider.aHrefSanitizationWhitelist(regexp);
$$sanitizeUriProvider.aHrefSanitizationTrustedUri(regexp);
return this;
} else {
return $$sanitizeUriProvider.aHrefSanitizationWhitelist();
return $$sanitizeUriProvider.aHrefSanitizationTrustedUri();
}
};
this.aHrefSanitizationWhitelist = this.aHrefSanitizationTrustedUri;
/**
* @ngdoc method
* @name $compileProvider#imgSrcSanitizationWhitelist
* @name $compileProvider#imgSrcSanitizationTrustedUri
* @kind function
*
* @description
* Retrieves or overrides the default regular expression that is used for whitelisting of safe
* Retrieves or overrides the default regular expression that is used for determining trusted safe
* urls during img[src] sanitization.
*
* The sanitization is a security measure aimed at prevent XSS attacks via html links.
*
* Any url about to be assigned to img[src] via data-binding is first normalized and turned into
* an absolute url. Afterwards, the url is matched against the `imgSrcSanitizationWhitelist`
* an absolute url. Afterwards, the url is matched against the `imgSrcSanitizationTrustedUri`
* regular expression. If a match is found, the original url is written into the dom. Otherwise,
* the absolute url is prefixed with `'unsafe:'` string and only then is it written into the DOM.
*
* @param {RegExp=} regexp New regexp to whitelist urls with.
* @param {RegExp=} regexp New regexp to trust urls with.
* @returns {RegExp|ng.$compileProvider} Current RegExp if called without value or self for
* chaining otherwise.
*/
this.imgSrcSanitizationWhitelist = function(regexp) {
this.imgSrcSanitizationTrustedUri = function(regexp) {
if (isDefined(regexp)) {
$$sanitizeUriProvider.imgSrcSanitizationWhitelist(regexp);
$$sanitizeUriProvider.imgSrcSanitizationTrustedUri(regexp);
return this;
} else {
return $$sanitizeUriProvider.imgSrcSanitizationWhitelist();
return $$sanitizeUriProvider.imgSrcSanitizationTrustedUri();
}
};
this.imgSrcSanitizationWhitelist = this.imgSrcSanitizationTrustedUri;
/**
* @ngdoc method
+16 -15
View File
@@ -7,12 +7,12 @@
*/
function $$SanitizeUriProvider() {
var aHrefSanitizationWhitelist = /^\s*(https?|s?ftp|mailto|tel|file):/,
imgSrcSanitizationWhitelist = /^\s*((https?|ftp|file|blob):|data:image\/)/;
var aHrefSanitizationTrustedUri = /^\s*(https?|s?ftp|mailto|tel|file):/,
imgSrcSanitizationTrustedUri = /^\s*((https?|ftp|file|blob):|data:image\/)/;
/**
* @description
* Retrieves or overrides the default regular expression that is used for whitelisting of safe
* Retrieves or overrides the default regular expression that is used for determining trusted safe
* urls during a[href] sanitization.
*
* The sanitization is a security measure aimed at prevent XSS attacks via HTML anchor links.
@@ -21,27 +21,27 @@ function $$SanitizeUriProvider() {
* the $sce.URL security context. When interpolation occurs a call is made to `$sce.trustAsUrl(url)`
* which in turn may call `$$sanitizeUri(url, isMedia)` to sanitize the potentially malicious URL.
*
* If the URL matches the `aHrefSanitizationWhitelist` regular expression, it is returned unchanged.
* If the URL matches the `aHrefSanitizationTrustedUri` regular expression, it is returned unchanged.
*
* If there is no match the URL is returned prefixed with `'unsafe:'` to ensure that when it is written
* to the DOM it is inactive and potentially malicious code will not be executed.
*
* @param {RegExp=} regexp New regexp to whitelist urls with.
* @param {RegExp=} regexp New regexp to trust urls with.
* @returns {RegExp|ng.$compileProvider} Current RegExp if called without value or self for
* chaining otherwise.
*/
this.aHrefSanitizationWhitelist = function(regexp) {
this.aHrefSanitizationTrustedUri = function(regexp) {
if (isDefined(regexp)) {
aHrefSanitizationWhitelist = regexp;
aHrefSanitizationTrustedUri = regexp;
return this;
}
return aHrefSanitizationWhitelist;
return aHrefSanitizationTrustedUri;
};
/**
* @description
* Retrieves or overrides the default regular expression that is used for whitelisting of safe
* Retrieves or overrides the default regular expression that is used for determining trusted safe
* urls during img[src] sanitization.
*
* The sanitization is a security measure aimed at prevent XSS attacks via HTML image src links.
@@ -51,27 +51,28 @@ function $$SanitizeUriProvider() {
* `$sce.trustAsMediaUrl(url)` which in turn may call `$$sanitizeUri(url, isMedia)` to sanitize
* the potentially malicious URL.
*
* If the URL matches the `aImgSanitizationWhitelist` regular expression, it is returned unchanged.
* If the URL matches the `imgSrcSanitizationTrustedUrlList` regular expression, it is returned
* unchanged.
*
* If there is no match the URL is returned prefixed with `'unsafe:'` to ensure that when it is written
* to the DOM it is inactive and potentially malicious code will not be executed.
*
* @param {RegExp=} regexp New regexp to whitelist urls with.
* @param {RegExp=} regexp New regexp to trust urls with.
* @returns {RegExp|ng.$compileProvider} Current RegExp if called without value or self for
* chaining otherwise.
*/
this.imgSrcSanitizationWhitelist = function(regexp) {
this.imgSrcSanitizationTrustedUri = function(regexp) {
if (isDefined(regexp)) {
imgSrcSanitizationWhitelist = regexp;
imgSrcSanitizationTrustedUri = regexp;
return this;
}
return imgSrcSanitizationWhitelist;
return imgSrcSanitizationTrustedUri;
};
this.$get = function() {
return function sanitizeUri(uri, isMediaUrl) {
// if (!uri) return uri;
var regex = isMediaUrl ? imgSrcSanitizationWhitelist : aHrefSanitizationWhitelist;
var regex = isMediaUrl ? imgSrcSanitizationTrustedUri : aHrefSanitizationTrustedUri;
var normalizedVal = urlResolve(uri && uri.trim()).href;
if (normalizedVal !== '' && !normalizedVal.match(regex)) {
return 'unsafe:' + normalizedVal;
+3 -3
View File
@@ -46,7 +46,7 @@ var htmlSanitizeWriter;
* it into the returned string.
*
* The whitelist for URL sanitization of attribute values is configured using the functions
* `aHrefSanitizationWhitelist` and `imgSrcSanitizationWhitelist` of {@link $compileProvider}.
* `aHrefSanitizationTrustedUri` and `imgSrcSanitizationTrustedUri` of {@link $compileProvider}.
*
* The input may also contain SVG markup if this is enabled via {@link $sanitizeProvider}.
*
@@ -277,8 +277,8 @@ function $SanitizeProvider() {
* **Note**:
* The new attributes will not be treated as URI attributes, which means their values will not be
* sanitized as URIs using `$compileProvider`'s
* {@link ng.$compileProvider#aHrefSanitizationWhitelist aHrefSanitizationWhitelist} and
* {@link ng.$compileProvider#imgSrcSanitizationWhitelist imgSrcSanitizationWhitelist}.
* {@link ng.$compileProvider#aHrefSanitizationTrustedUri aHrefSanitizationTrustedUri} and
* {@link ng.$compileProvider#imgSrcSanitizationTrustedUri imgSrcSanitizationTrustedUri}.
*
* <div class="alert alert-info">
* This method must be called during the {@link angular.Module#config config} phase. Once the
+25 -25
View File
@@ -151,30 +151,30 @@ describe('$compile', function() {
describe('configuration', function() {
it('should use $$sanitizeUriProvider for reconfiguration of the `aHrefSanitizationWhitelist`', function() {
it('should use $$sanitizeUriProvider for reconfiguration of the `aHrefSanitizationTrustedUri`', function() {
module(function($compileProvider, $$sanitizeUriProvider) {
var newRe = /safe:/, returnVal;
expect($compileProvider.aHrefSanitizationWhitelist()).toBe($$sanitizeUriProvider.aHrefSanitizationWhitelist());
returnVal = $compileProvider.aHrefSanitizationWhitelist(newRe);
expect($compileProvider.aHrefSanitizationTrustedUri()).toBe($$sanitizeUriProvider.aHrefSanitizationTrustedUri());
returnVal = $compileProvider.aHrefSanitizationTrustedUri(newRe);
expect(returnVal).toBe($compileProvider);
expect($$sanitizeUriProvider.aHrefSanitizationWhitelist()).toBe(newRe);
expect($compileProvider.aHrefSanitizationWhitelist()).toBe(newRe);
expect($$sanitizeUriProvider.aHrefSanitizationTrustedUri()).toBe(newRe);
expect($compileProvider.aHrefSanitizationTrustedUri()).toBe(newRe);
});
inject(function() {
// needed to the module definition above is run...
});
});
it('should use $$sanitizeUriProvider for reconfiguration of the `imgSrcSanitizationWhitelist`', function() {
it('should use $$sanitizeUriProvider for reconfiguration of the `imgSrcSanitizationTrustedUri`', function() {
module(function($compileProvider, $$sanitizeUriProvider) {
var newRe = /safe:/, returnVal;
expect($compileProvider.imgSrcSanitizationWhitelist()).toBe($$sanitizeUriProvider.imgSrcSanitizationWhitelist());
returnVal = $compileProvider.imgSrcSanitizationWhitelist(newRe);
expect($compileProvider.imgSrcSanitizationTrustedUri()).toBe($$sanitizeUriProvider.imgSrcSanitizationTrustedUri());
returnVal = $compileProvider.imgSrcSanitizationTrustedUri(newRe);
expect(returnVal).toBe($compileProvider);
expect($$sanitizeUriProvider.imgSrcSanitizationWhitelist()).toBe(newRe);
expect($compileProvider.imgSrcSanitizationWhitelist()).toBe(newRe);
expect($$sanitizeUriProvider.imgSrcSanitizationTrustedUri()).toBe(newRe);
expect($compileProvider.imgSrcSanitizationTrustedUri()).toBe(newRe);
});
inject(function() {
// needed to the module definition above is run...
@@ -11334,9 +11334,9 @@ describe('$compile', function() {
// IE9 rejects the `video` / `audio` tags with "Error: Not implemented"
if (msie !== 9 || tag === 'img') {
describe(tag + '[src] context requirement', function() {
it('should NOT require trusted values for whitelisted URIs', inject(function($rootScope, $compile) {
it('should NOT require trusted values for trusted URIs', inject(function($rootScope, $compile) {
element = $compile('<' + tag + ' src="{{testUrl}}"></' + tag + '>')($rootScope);
$rootScope.testUrl = 'http://example.com/image.mp4'; // `http` is whitelisted
$rootScope.testUrl = 'http://example.com/image.mp4'; // `http` is trusted
$rootScope.$digest();
expect(element.attr('src')).toEqual('http://example.com/image.mp4');
}));
@@ -11372,9 +11372,9 @@ describe('$compile', function() {
if (msie !== 9) {
['source', 'track'].forEach(function(tag) {
describe(tag + '[src]', function() {
it('should NOT require trusted values for whitelisted URIs', inject(function($rootScope, $compile) {
it('should NOT require trusted values for trusted URIs', inject(function($rootScope, $compile) {
element = $compile('<video><' + tag + ' src="{{testUrl}}"></' + tag + '></video>')($rootScope);
$rootScope.testUrl = 'http://example.com/image.mp4'; // `http` is whitelisted
$rootScope.testUrl = 'http://example.com/image.mp4'; // `http` is trusted
$rootScope.$digest();
expect(element.find(tag).attr('src')).toEqual('http://example.com/image.mp4');
}));
@@ -11509,14 +11509,14 @@ describe('$compile', function() {
});
});
it('should NOT require trusted values for whitelisted values', inject(function($rootScope, $compile, $sce) {
it('should NOT require trusted values for trusted URI values', inject(function($rootScope, $compile, $sce) {
element = $compile('<img srcset="{{testUrl}}"></img>')($rootScope);
$rootScope.testUrl = 'http://example.com/image.png'; // `http` is whitelisted
$rootScope.testUrl = 'http://example.com/image.png'; // `http` is trusted
$rootScope.$digest();
expect(element.attr('srcset')).toEqual('http://example.com/image.png');
}));
it('should accept trusted values, if they are also whitelisted', inject(function($rootScope, $compile, $sce) {
it('should accept trusted values, if they are also trusted URIs', inject(function($rootScope, $compile, $sce) {
element = $compile('<img srcset="{{testUrl}}"></img>')($rootScope);
$rootScope.testUrl = $sce.trustAsUrl('http://example.com');
$rootScope.$digest();
@@ -11602,8 +11602,8 @@ describe('$compile', function() {
});
describe('a[href] sanitization', function() {
it('should NOT require trusted values for whitelisted values', inject(function($rootScope, $compile) {
$rootScope.testUrl = 'http://example.com/image.png'; // `http` is whitelisted
it('should NOT require trusted values for trusted URI values', inject(function($rootScope, $compile) {
$rootScope.testUrl = 'http://example.com/image.png'; // `http` is trusted
element = $compile('<a href="{{testUrl}}"></a>')($rootScope);
$rootScope.$digest();
expect(element.attr('href')).toEqual('http://example.com/image.png');
@@ -11613,8 +11613,8 @@ describe('$compile', function() {
expect(element.attr('ng-href')).toEqual('http://example.com/image.png');
}));
it('should accept trusted values for non-whitelisted values', inject(function($rootScope, $compile, $sce) {
$rootScope.testUrl = $sce.trustAsUrl('javascript:foo()'); // `javascript` is not whitelisted
it('should accept trusted values for non-trusted URI values', inject(function($rootScope, $compile, $sce) {
$rootScope.testUrl = $sce.trustAsUrl('javascript:foo()'); // `javascript` is not trusted
element = $compile('<a href="{{testUrl}}"></a>')($rootScope);
$rootScope.$digest();
expect(element.attr('href')).toEqual('javascript:foo()');
@@ -11624,8 +11624,8 @@ describe('$compile', function() {
expect(element.attr('ng-href')).toEqual('javascript:foo()');
}));
it('should sanitize non-whitelisted values', inject(function($rootScope, $compile) {
$rootScope.testUrl = 'javascript:foo()'; // `javascript` is not whitelisted
it('should sanitize non-trusted values', inject(function($rootScope, $compile) {
$rootScope.testUrl = 'javascript:foo()'; // `javascript` is not trusted
element = $compile('<a href="{{testUrl}}"></a>')($rootScope);
$rootScope.$digest();
expect(element.attr('href')).toEqual('unsafe:javascript:foo()');
@@ -11678,7 +11678,7 @@ describe('$compile', function() {
$provide.value('$$sanitizeUri', $$sanitizeUri);
});
inject(function($compile, $rootScope) {
// This URL would fail the RESOURCE_URL whitelist, but that test shouldn't be run
// This URL would fail the RESOURCE_URL trusted list, but that test shouldn't be run
// because these interpolations will be resolved against the URL context instead
$rootScope.testUrl = 'https://bad.example.org';
@@ -11700,7 +11700,7 @@ describe('$compile', function() {
$provide.value('$$sanitizeUri', $$sanitizeUri);
});
inject(function($compile, $rootScope) {
// This URL would fail the RESOURCE_URL whitelist, but that test shouldn't be run
// This URL would fail the RESOURCE_URL trusted list, but that test shouldn't be run
// because these interpolations will be resolved against the URL context instead
$rootScope.testUrl = 'https://bad.example.org';
+6 -6
View File
@@ -125,10 +125,10 @@ describe('sanitizeUri', function() {
expect(sanitizeImg(testUrl)).toBe('data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==');
});
it('should allow reconfiguration of the src whitelist', function() {
it('should allow reconfiguration of the src trusted URIs', function() {
var returnVal;
expect(sanitizeUriProvider.imgSrcSanitizationWhitelist() instanceof RegExp).toBe(true);
returnVal = sanitizeUriProvider.imgSrcSanitizationWhitelist(/javascript:/);
expect(sanitizeUriProvider.imgSrcSanitizationTrustedUri() instanceof RegExp).toBe(true);
returnVal = sanitizeUriProvider.imgSrcSanitizationTrustedUri(/javascript:/);
expect(returnVal).toBe(sanitizeUriProvider);
testUrl = 'javascript:doEvilStuff()';
@@ -226,10 +226,10 @@ describe('sanitizeUri', function() {
expect(sanitizeHref(testUrl)).toBe('file:///foo/bar.html');
}));
it('should allow reconfiguration of the href whitelist', function() {
it('should allow reconfiguration of the href trusted URIs', function() {
var returnVal;
expect(sanitizeUriProvider.aHrefSanitizationWhitelist() instanceof RegExp).toBe(true);
returnVal = sanitizeUriProvider.aHrefSanitizationWhitelist(/javascript:/);
expect(sanitizeUriProvider.aHrefSanitizationTrustedUri() instanceof RegExp).toBe(true);
returnVal = sanitizeUriProvider.aHrefSanitizationTrustedUri(/javascript:/);
expect(returnVal).toBe(sanitizeUriProvider);
testUrl = 'javascript:doEvilStuff()';