feat(security): allow data: URLs for images and videos.
Allows known-to-be-safe media types in data URIs. Part of #8511.
This commit is contained in:
parent
ff36b0384a
commit
dd50124254
|
@ -29,12 +29,14 @@ import {assertionsEnabled} from '../../src/facade/lang';
|
||||||
*/
|
*/
|
||||||
const SAFE_URL_PATTERN = /^(?:(?:https?|mailto|ftp|tel|file):|[^&:/?#]*(?:[/?#]|$))/gi;
|
const SAFE_URL_PATTERN = /^(?:(?:https?|mailto|ftp|tel|file):|[^&:/?#]*(?:[/?#]|$))/gi;
|
||||||
|
|
||||||
|
/** A pattern that matches safe data URLs. Only matches image and video types. */
|
||||||
|
const DATA_URL_PATTERN = /^data:(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm));base64,[a-z0-9+\/]+=*$/i;
|
||||||
|
|
||||||
export function sanitizeUrl(url: string): string {
|
export function sanitizeUrl(url: string): string {
|
||||||
url = String(url);
|
url = String(url);
|
||||||
if (url.match(SAFE_URL_PATTERN)) return url;
|
if (url.match(SAFE_URL_PATTERN) || url.match(DATA_URL_PATTERN)) return url;
|
||||||
|
|
||||||
|
if (assertionsEnabled()) getDOM().log('WARNING: sanitizing unsafe URL value ' + url);
|
||||||
|
|
||||||
if (assertionsEnabled()) {
|
|
||||||
getDOM().log('WARNING: sanitizing unsafe URL value ' + url);
|
|
||||||
}
|
|
||||||
return 'unsafe:' + url;
|
return 'unsafe:' + url;
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,7 +36,9 @@ export function main() {
|
||||||
'TEL:123-123-1234',
|
'TEL:123-123-1234',
|
||||||
'#anchor',
|
'#anchor',
|
||||||
'/page1.md',
|
'/page1.md',
|
||||||
'http://JavaScript/my.js'
|
'http://JavaScript/my.js',
|
||||||
|
'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/', // Truncated.
|
||||||
|
'data:video/webm;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/',
|
||||||
];
|
];
|
||||||
for (let url of validUrls) {
|
for (let url of validUrls) {
|
||||||
t.it(`valid ${url}`, () => t.expect(sanitizeUrl(url)).toEqual(url));
|
t.it(`valid ${url}`, () => t.expect(sanitizeUrl(url)).toEqual(url));
|
||||||
|
@ -56,6 +58,11 @@ export function main() {
|
||||||
'javascript:',
|
'javascript:',
|
||||||
'jav	ascript:alert();',
|
'jav	ascript:alert();',
|
||||||
'jav\u0000ascript:alert();',
|
'jav\u0000ascript:alert();',
|
||||||
|
'data:;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/',
|
||||||
|
'data:,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/',
|
||||||
|
'data:iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/',
|
||||||
|
'data:text/javascript;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/',
|
||||||
|
'data:application/x-msdownload;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/',
|
||||||
];
|
];
|
||||||
for (let url of invalidUrls) {
|
for (let url of invalidUrls) {
|
||||||
t.it(`valid ${url}`, () => t.expect(sanitizeUrl(url)).toMatch(/^unsafe:/));
|
t.it(`valid ${url}`, () => t.expect(sanitizeUrl(url)).toMatch(/^unsafe:/));
|
||||||
|
|
Loading…
Reference in New Issue