diff --git a/modules/@angular/core/test/linker/security_integration_spec.ts b/modules/@angular/core/test/linker/security_integration_spec.ts index 12a103fdc6..6456faf07f 100644 --- a/modules/@angular/core/test/linker/security_integration_spec.ts +++ b/modules/@angular/core/test/linker/security_integration_spec.ts @@ -4,6 +4,8 @@ import { expect, inject, beforeEachProviders, + beforeEach, + afterEach, it, } from '@angular/core/testing/testing_internal'; import {TestComponentBuilder} from '@angular/compiler/testing'; @@ -63,39 +65,27 @@ function declareTests(isJit: boolean) { beforeEachProviders(() => [provide(ANCHOR_ELEMENT, {useValue: el('
')})]); + let originalLog: (msg: any) => any; + beforeEach(() => { + originalLog = getDOM().log; + getDOM().log = (msg) => { /* disable logging */ }; + }); + afterEach(() => { getDOM().log = originalLog; }); + + + itAsync('should disallow binding on*', (tcb: TestComponentBuilder, async) => { + let tpl = ``; + tcb = tcb.overrideView(SecuredComponent, new ViewMetadata({template: tpl})); + PromiseWrapper.catchError(tcb.createAsync(SecuredComponent), (e) => { + expect(e.message).toContain(`Template parse errors:\n` + + `Binding to event attribute 'onclick' is disallowed ` + + `for security reasons, please use (click)=... `); + async.done(); + return null; + }); + }); + describe('safe HTML values', function() { - itAsync('should disallow binding on*', (tcb: TestComponentBuilder, async) => { - let tpl = ``; - tcb = tcb.overrideView(SecuredComponent, new ViewMetadata({template: tpl})); - PromiseWrapper.catchError(tcb.createAsync(SecuredComponent), (e) => { - expect(e.message).toContain(`Template parse errors:\n` + - `Binding to event attribute 'onclick' is disallowed ` + - `for security reasons, please use (click)=... `); - async.done(); - return null; - }); - }); - - itAsync('should escape unsafe attributes', (tcb: TestComponentBuilder, async) => { - let tpl = `Link Title`; - tcb.overrideView(SecuredComponent, new ViewMetadata({template: tpl, directives: []})) - .createAsync(SecuredComponent) - .then((fixture) => { - let e = fixture.debugElement.children[0].nativeElement; - fixture.debugElement.componentInstance.ctxProp = 'hello'; - fixture.detectChanges(); - // In the browser, reading href returns an absolute URL. On the server side, - // it just echoes back the property. - expect(getDOM().getProperty(e, 'href')).toMatch(/.*\/?hello$/); - - fixture.debugElement.componentInstance.ctxProp = 'javascript:alert(1)'; - fixture.detectChanges(); - expect(getDOM().getProperty(e, 'href')).toEqual('unsafe:javascript:alert(1)'); - - async.done(); - }); - }); - itAsync('should not escape values marked as trusted', [TestComponentBuilder, AsyncTestCompleter, DomSanitizationService], (tcb: TestComponentBuilder, async, sanitizer: DomSanitizationService) => { @@ -105,8 +95,9 @@ function declareTests(isJit: boolean) { .createAsync(SecuredComponent) .then((fixture) => { let e = fixture.debugElement.children[0].nativeElement; + let ci = fixture.debugElement.componentInstance; let trusted = sanitizer.bypassSecurityTrustUrl('javascript:alert(1)'); - fixture.debugElement.componentInstance.ctxProp = trusted; + ci.ctxProp = trusted; fixture.detectChanges(); expect(getDOM().getProperty(e, 'href')).toEqual('javascript:alert(1)'); @@ -123,13 +114,37 @@ function declareTests(isJit: boolean) { .createAsync(SecuredComponent) .then((fixture) => { let trusted = sanitizer.bypassSecurityTrustScript('javascript:alert(1)'); - fixture.debugElement.componentInstance.ctxProp = trusted; + let ci = fixture.debugElement.componentInstance; + ci.ctxProp = trusted; expect(() => fixture.detectChanges()) .toThrowErrorWith('Required a safe URL, got a Script'); async.done(); }); }); + }); + + describe('sanitizing', () => { + itAsync('should escape unsafe attributes', (tcb: TestComponentBuilder, async) => { + let tpl = `Link Title`; + tcb.overrideView(SecuredComponent, new ViewMetadata({template: tpl, directives: []})) + .createAsync(SecuredComponent) + .then((fixture) => { + let e = fixture.debugElement.children[0].nativeElement; + let ci = fixture.debugElement.componentInstance; + ci.ctxProp = 'hello'; + fixture.detectChanges(); + // In the browser, reading href returns an absolute URL. On the server side, + // it just echoes back the property. + expect(getDOM().getProperty(e, 'href')).toMatch(/.*\/?hello$/); + + ci.ctxProp = 'javascript:alert(1)'; + fixture.detectChanges(); + expect(getDOM().getProperty(e, 'href')).toEqual('unsafe:javascript:alert(1)'); + + async.done(); + }); + }); itAsync('should escape unsafe style values', (tcb: TestComponentBuilder, async) => { let tpl = `text
'; + fixture.detectChanges(); + expect(getDOM().getInnerHTML(e)).toEqual('sometext
'); + + ci.ctxProp = 'ha '; + fixture.detectChanges(); + expect(getDOM().getInnerHTML(e)).toEqual('ha evil()'); + + ci.ctxProp = 'also