/** * @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 */ import {SECURITY_SCHEMA} from '@angular/compiler/src/schema/dom_security_schema'; import {HEADER_OFFSET, LView} from '@angular/core/src/render3/interfaces/view'; import {setTNodeAndViewData} from '@angular/core/src/render3/state'; import {bypassSanitizationTrustHtml, bypassSanitizationTrustResourceUrl, bypassSanitizationTrustScript, bypassSanitizationTrustStyle, bypassSanitizationTrustUrl} from '../../src/sanitization/bypass'; import {getUrlSanitizer, ΔsanitizeHtml, ΔsanitizeResourceUrl, ΔsanitizeScript, ΔsanitizeStyle, ΔsanitizeUrl, ΔsanitizeUrlOrResourceUrl} from '../../src/sanitization/sanitization'; import {SecurityContext} from '../../src/sanitization/security'; function fakeLView(): LView { return [null, {}] as LView; } describe('sanitization', () => { beforeEach(() => setTNodeAndViewData(null !, fakeLView())); afterEach(() => setTNodeAndViewData(null !, null !)); class Wrap { constructor(private value: string) {} toString() { return this.value; } } it('should sanitize html', () => { expect(ΔsanitizeHtml('
')).toEqual(''); expect(ΔsanitizeHtml(new Wrap(''))).toEqual(''); expect(ΔsanitizeHtml('')) .toEqual(''); expect(ΔsanitizeHtml(new Wrap(''))) .toEqual(''); expect(ΔsanitizeHtml(bypassSanitizationTrustUrl(''))) .toEqual(''); expect(ΔsanitizeHtml(bypassSanitizationTrustHtml(''))) .toEqual(''); }); it('should sanitize url', () => { expect(ΔsanitizeUrl('http://server')).toEqual('http://server'); expect(ΔsanitizeUrl(new Wrap('http://server'))).toEqual('http://server'); expect(ΔsanitizeUrl('javascript:true')).toEqual('unsafe:javascript:true'); expect(ΔsanitizeUrl(new Wrap('javascript:true'))).toEqual('unsafe:javascript:true'); expect(ΔsanitizeUrl(bypassSanitizationTrustHtml('javascript:true'))) .toEqual('unsafe:javascript:true'); expect(ΔsanitizeUrl(bypassSanitizationTrustUrl('javascript:true'))).toEqual('javascript:true'); }); it('should sanitize resourceUrl', () => { const ERROR = 'unsafe value used in a resource URL context (see http://g.co/ng/security#xss)'; expect(() => ΔsanitizeResourceUrl('http://server')).toThrowError(ERROR); expect(() => ΔsanitizeResourceUrl('javascript:true')).toThrowError(ERROR); expect(() => ΔsanitizeResourceUrl(bypassSanitizationTrustHtml('javascript:true'))) .toThrowError(ERROR); expect(ΔsanitizeResourceUrl(bypassSanitizationTrustResourceUrl('javascript:true'))) .toEqual('javascript:true'); }); it('should sanitize style', () => { expect(ΔsanitizeStyle('red')).toEqual('red'); expect(ΔsanitizeStyle(new Wrap('red'))).toEqual('red'); expect(ΔsanitizeStyle('url("http://server")')).toEqual('unsafe'); expect(ΔsanitizeStyle(new Wrap('url("http://server")'))).toEqual('unsafe'); expect(ΔsanitizeStyle(bypassSanitizationTrustHtml('url("http://server")'))).toEqual('unsafe'); expect(ΔsanitizeStyle(bypassSanitizationTrustStyle('url("http://server")'))) .toEqual('url("http://server")'); }); it('should sanitize script', () => { const ERROR = 'unsafe value used in a script context'; expect(() => ΔsanitizeScript('true')).toThrowError(ERROR); expect(() => ΔsanitizeScript('true')).toThrowError(ERROR); expect(() => ΔsanitizeScript(bypassSanitizationTrustHtml('true'))).toThrowError(ERROR); expect(ΔsanitizeScript(bypassSanitizationTrustScript('true'))).toEqual('true'); }); it('should select correct sanitizer for URL props', () => { // making sure security schema we have on compiler side is in sync with the `getUrlSanitizer` // runtime function definition const schema = SECURITY_SCHEMA(); const contextsByProp: Map