diff --git a/modules/@angular/platform-browser/src/security/url_sanitizer.ts b/modules/@angular/platform-browser/src/security/url_sanitizer.ts index 7d496f9b3e..970340bd06 100644 --- a/modules/@angular/platform-browser/src/security/url_sanitizer.ts +++ b/modules/@angular/platform-browser/src/security/url_sanitizer.ts @@ -29,12 +29,14 @@ import {assertionsEnabled} from '../../src/facade/lang'; */ 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 { 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; } diff --git a/modules/@angular/platform-browser/test/security/url_sanitizer_spec.ts b/modules/@angular/platform-browser/test/security/url_sanitizer_spec.ts index 7ae27d1f45..2e8443aa2d 100644 --- a/modules/@angular/platform-browser/test/security/url_sanitizer_spec.ts +++ b/modules/@angular/platform-browser/test/security/url_sanitizer_spec.ts @@ -36,7 +36,9 @@ export function main() { 'TEL:123-123-1234', '#anchor', '/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) { t.it(`valid ${url}`, () => t.expect(sanitizeUrl(url)).toEqual(url)); @@ -56,6 +58,11 @@ export function main() { 'javascript:', 'jav ascript: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) { t.it(`valid ${url}`, () => t.expect(sanitizeUrl(url)).toMatch(/^unsafe:/));