| 
									
										
										
										
											2016-06-23 09:47:54 -07:00
										 |  |  | /** | 
					
						
							|  |  |  |  * @license | 
					
						
							|  |  |  |  * Copyright Google Inc. All Rights Reserved. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Use of this source code is governed by an MIT-style license that can be | 
					
						
							|  |  |  |  * found in the LICENSE file at https://angular.io/license
 | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-03 18:41:31 -07:00
										 |  |  | import * as t from '@angular/core/testing/testing_internal'; | 
					
						
							| 
									
										
										
										
											2016-05-09 16:46:31 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | import {getDOM} from '../../src/dom/dom_adapter'; | 
					
						
							| 
									
										
										
										
											2016-06-24 16:54:11 +02:00
										 |  |  | import {sanitizeSrcset, sanitizeUrl} from '../../src/security/url_sanitizer'; | 
					
						
							| 
									
										
										
										
											2016-05-03 18:41:31 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | export function main() { | 
					
						
							|  |  |  |   t.describe('URL sanitizer', () => { | 
					
						
							| 
									
										
										
										
											2016-05-09 16:46:31 +02:00
										 |  |  |     let logMsgs: string[]; | 
					
						
							|  |  |  |     let originalLog: (msg: any) => any; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     t.beforeEach(() => { | 
					
						
							|  |  |  |       logMsgs = []; | 
					
						
							|  |  |  |       originalLog = getDOM().log;  // Monkey patch DOM.log.
 | 
					
						
							|  |  |  |       getDOM().log = (msg) => logMsgs.push(msg); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |     t.afterEach(() => { getDOM().log = originalLog; }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     t.it('reports unsafe URLs', () => { | 
					
						
							|  |  |  |       t.expect(sanitizeUrl('javascript:evil()')).toBe('unsafe:javascript:evil()'); | 
					
						
							|  |  |  |       t.expect(logMsgs.join('\n')).toMatch(/sanitizing unsafe URL value/); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-03 18:41:31 -07:00
										 |  |  |     t.describe('valid URLs', () => { | 
					
						
							|  |  |  |       const validUrls = [ | 
					
						
							|  |  |  |         '', | 
					
						
							|  |  |  |         'http://abc', | 
					
						
							|  |  |  |         'HTTP://abc', | 
					
						
							|  |  |  |         'https://abc', | 
					
						
							|  |  |  |         'HTTPS://abc', | 
					
						
							|  |  |  |         'ftp://abc', | 
					
						
							|  |  |  |         'FTP://abc', | 
					
						
							|  |  |  |         'mailto:me@example.com', | 
					
						
							|  |  |  |         'MAILTO:me@example.com', | 
					
						
							|  |  |  |         'tel:123-123-1234', | 
					
						
							|  |  |  |         'TEL:123-123-1234', | 
					
						
							|  |  |  |         '#anchor', | 
					
						
							|  |  |  |         '/page1.md', | 
					
						
							| 
									
										
										
										
											2016-05-15 11:44:52 +02:00
										 |  |  |         'http://JavaScript/my.js', | 
					
						
							|  |  |  |         'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/',  // Truncated.
 | 
					
						
							|  |  |  |         'data:video/webm;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/', | 
					
						
							| 
									
										
										
										
											2016-06-24 16:54:11 +02:00
										 |  |  |         'data:audio/opus;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/', | 
					
						
							| 
									
										
										
										
											2016-05-03 18:41:31 -07:00
										 |  |  |       ]; | 
					
						
							| 
									
										
										
										
											2016-11-12 14:08:58 +01:00
										 |  |  |       for (const url of validUrls) { | 
					
						
							| 
									
										
										
										
											2016-05-03 18:41:31 -07:00
										 |  |  |         t.it(`valid ${url}`, () => t.expect(sanitizeUrl(url)).toEqual(url)); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     t.describe('invalid URLs', () => { | 
					
						
							|  |  |  |       const invalidUrls = [ | 
					
						
							|  |  |  |         'javascript:evil()', | 
					
						
							|  |  |  |         'JavaScript:abc', | 
					
						
							|  |  |  |         'evilNewProtocol:abc', | 
					
						
							|  |  |  |         ' \n Java\n Script:abc', | 
					
						
							|  |  |  |         'javascript:', | 
					
						
							|  |  |  |         'javascript:', | 
					
						
							|  |  |  |         'j avascript:', | 
					
						
							|  |  |  |         'javascript:', | 
					
						
							|  |  |  |         'javascript:', | 
					
						
							|  |  |  |         'jav	ascript:alert();', | 
					
						
							|  |  |  |         'jav\u0000ascript:alert();', | 
					
						
							| 
									
										
										
										
											2016-05-15 11:44:52 +02:00
										 |  |  |         'data:;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/', | 
					
						
							|  |  |  |         'data:,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/', | 
					
						
							|  |  |  |         'data:iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/', | 
					
						
							|  |  |  |         'data:text/javascript;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/', | 
					
						
							|  |  |  |         'data:application/x-msdownload;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/', | 
					
						
							| 
									
										
										
										
											2016-05-03 18:41:31 -07:00
										 |  |  |       ]; | 
					
						
							| 
									
										
										
										
											2016-11-12 14:08:58 +01:00
										 |  |  |       for (const url of invalidUrls) { | 
					
						
							| 
									
										
										
										
											2016-05-03 18:41:31 -07:00
										 |  |  |         t.it(`valid ${url}`, () => t.expect(sanitizeUrl(url)).toMatch(/^unsafe:/)); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     }); | 
					
						
							| 
									
										
										
										
											2016-06-24 16:54:11 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     t.describe('valid srcsets', () => { | 
					
						
							|  |  |  |       const validSrcsets = [ | 
					
						
							|  |  |  |         '', | 
					
						
							|  |  |  |         'http://angular.io/images/test.png', | 
					
						
							|  |  |  |         'http://angular.io/images/test.png, http://angular.io/images/test.png', | 
					
						
							|  |  |  |         'http://angular.io/images/test.png, http://angular.io/images/test.png, http://angular.io/images/test.png', | 
					
						
							|  |  |  |         'http://angular.io/images/test.png 2x', | 
					
						
							|  |  |  |         'http://angular.io/images/test.png 2x, http://angular.io/images/test.png 3x', | 
					
						
							|  |  |  |         'http://angular.io/images/test.png 1.5x', | 
					
						
							|  |  |  |         'http://angular.io/images/test.png 1.25x', | 
					
						
							|  |  |  |         'http://angular.io/images/test.png 200w, http://angular.io/images/test.png 300w', | 
					
						
							|  |  |  |         'https://angular.io/images/test.png, http://angular.io/images/test.png', | 
					
						
							|  |  |  |         'http://angular.io:80/images/test.png, http://angular.io:8080/images/test.png', | 
					
						
							|  |  |  |         'http://www.angular.io:80/images/test.png, http://www.angular.io:8080/images/test.png', | 
					
						
							|  |  |  |         'https://angular.io/images/test.png, https://angular.io/images/test.png', | 
					
						
							|  |  |  |         '//angular.io/images/test.png, //angular.io/images/test.png', | 
					
						
							|  |  |  |         '/images/test.png, /images/test.png', | 
					
						
							|  |  |  |         'images/test.png, images/test.png', | 
					
						
							|  |  |  |         'http://angular.io/images/test.png?12345, http://angular.io/images/test.png?12345', | 
					
						
							|  |  |  |         'http://angular.io/images/test.png?maxage, http://angular.io/images/test.png?maxage', | 
					
						
							|  |  |  |         'http://angular.io/images/test.png?maxage=234, http://angular.io/images/test.png?maxage=234', | 
					
						
							|  |  |  |       ]; | 
					
						
							| 
									
										
										
										
											2016-11-12 14:08:58 +01:00
										 |  |  |       for (const srcset of validSrcsets) { | 
					
						
							| 
									
										
										
										
											2016-06-24 16:54:11 +02:00
										 |  |  |         t.it(`valid ${srcset}`, () => t.expect(sanitizeSrcset(srcset)).toEqual(srcset)); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     t.describe('invalid srcsets', () => { | 
					
						
							|  |  |  |       const invalidSrcsets = [ | 
					
						
							|  |  |  |         'ht:tp://angular.io/images/test.png', | 
					
						
							|  |  |  |         'http://angular.io/images/test.png, ht:tp://angular.io/images/test.png', | 
					
						
							|  |  |  |       ]; | 
					
						
							| 
									
										
										
										
											2016-11-12 14:08:58 +01:00
										 |  |  |       for (const srcset of invalidSrcsets) { | 
					
						
							| 
									
										
										
										
											2016-06-24 16:54:11 +02:00
										 |  |  |         t.it(`valid ${srcset}`, () => t.expect(sanitizeSrcset(srcset)).toMatch(/unsafe:/)); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-03 18:41:31 -07:00
										 |  |  |   }); | 
					
						
							|  |  |  | } |