@@ -2536,7 +2536,156 @@ describe('$compile', function() {
25362536 } ) ;
25372537
25382538
2539- describe ( 'href sanitization' , function ( ) {
2539+ describe ( 'img[src] sanitization' , function ( ) {
2540+ it ( 'should NOT require trusted values for img src' , inject ( function ( $rootScope , $compile ) {
2541+ element = $compile ( '<img src="{{testUrl}}"></img>' ) ( $rootScope ) ;
2542+ $rootScope . testUrl = 'http://example.com/image.png' ;
2543+ $rootScope . $digest ( ) ;
2544+ expect ( element . attr ( 'src' ) ) . toEqual ( 'http://example.com/image.png' ) ;
2545+ } ) ) ;
2546+
2547+ it ( 'should sanitize javascript: urls' , inject ( function ( $compile , $rootScope ) {
2548+ element = $compile ( '<img src="{{testUrl}}"></a>' ) ( $rootScope ) ;
2549+ $rootScope . testUrl = "javascript:doEvilStuff()" ;
2550+ $rootScope . $apply ( ) ;
2551+ expect ( element . attr ( 'src' ) ) . toBe ( 'unsafe:javascript:doEvilStuff()' ) ;
2552+ } ) ) ;
2553+
2554+ it ( 'should sanitize data: urls' , inject ( function ( $compile , $rootScope ) {
2555+ element = $compile ( '<img src="{{testUrl}}"></a>' ) ( $rootScope ) ;
2556+ $rootScope . testUrl = "data:evilPayload" ;
2557+ $rootScope . $apply ( ) ;
2558+
2559+ expect ( element . attr ( 'src' ) ) . toBe ( 'unsafe:data:evilPayload' ) ;
2560+ } ) ) ;
2561+
2562+
2563+ it ( 'should sanitize obfuscated javascript: urls' , inject ( function ( $compile , $rootScope ) {
2564+ element = $compile ( '<img src="{{testUrl}}"></img>' ) ( $rootScope ) ;
2565+
2566+ // case-sensitive
2567+ $rootScope . testUrl = "JaVaScRiPt:doEvilStuff()" ;
2568+ $rootScope . $apply ( ) ;
2569+ expect ( element [ 0 ] . src ) . toBe ( 'unsafe:javascript:doEvilStuff()' ) ;
2570+
2571+ // tab in protocol
2572+ $rootScope . testUrl = "java\u0009script:doEvilStuff()" ;
2573+ $rootScope . $apply ( ) ;
2574+ expect ( element [ 0 ] . src ) . toMatch ( / ( h t t p : \/ \/ | u n s a f e : j a v a s c r i p t : d o E v i l S t u f f \( \) ) / ) ;
2575+
2576+ // space before
2577+ $rootScope . testUrl = " javascript:doEvilStuff()" ;
2578+ $rootScope . $apply ( ) ;
2579+ expect ( element [ 0 ] . src ) . toBe ( 'unsafe:javascript:doEvilStuff()' ) ;
2580+
2581+ // ws chars before
2582+ $rootScope . testUrl = " \u000e javascript:doEvilStuff()" ;
2583+ $rootScope . $apply ( ) ;
2584+ expect ( element [ 0 ] . src ) . toMatch ( / ( h t t p : \/ \/ | u n s a f e : j a v a s c r i p t : d o E v i l S t u f f \( \) ) / ) ;
2585+
2586+ // post-fixed with proper url
2587+ $rootScope . testUrl = "javascript:doEvilStuff(); http://make.me/look/good" ;
2588+ $rootScope . $apply ( ) ;
2589+ expect ( element [ 0 ] . src ) . toBeOneOf (
2590+ 'unsafe:javascript:doEvilStuff(); http://make.me/look/good' ,
2591+ 'unsafe:javascript:doEvilStuff();%20http://make.me/look/good'
2592+ ) ;
2593+ } ) ) ;
2594+
2595+ it ( 'should sanitize ng-src bindings as well' , inject ( function ( $compile , $rootScope ) {
2596+ element = $compile ( '<img ng-src="{{testUrl}}"></img>' ) ( $rootScope ) ;
2597+ $rootScope . testUrl = "javascript:doEvilStuff()" ;
2598+ $rootScope . $apply ( ) ;
2599+
2600+ expect ( element [ 0 ] . src ) . toBe ( 'unsafe:javascript:doEvilStuff()' ) ;
2601+ } ) ) ;
2602+
2603+
2604+ it ( 'should not sanitize valid urls' , inject ( function ( $compile , $rootScope ) {
2605+ element = $compile ( '<img src="{{testUrl}}"></img>' ) ( $rootScope ) ;
2606+
2607+ $rootScope . testUrl = "foo/bar" ;
2608+ $rootScope . $apply ( ) ;
2609+ expect ( element . attr ( 'src' ) ) . toBe ( 'foo/bar' ) ;
2610+
2611+ $rootScope . testUrl = "/foo/bar" ;
2612+ $rootScope . $apply ( ) ;
2613+ expect ( element . attr ( 'src' ) ) . toBe ( '/foo/bar' ) ;
2614+
2615+ $rootScope . testUrl = "../foo/bar" ;
2616+ $rootScope . $apply ( ) ;
2617+ expect ( element . attr ( 'src' ) ) . toBe ( '../foo/bar' ) ;
2618+
2619+ $rootScope . testUrl = "#foo" ;
2620+ $rootScope . $apply ( ) ;
2621+ expect ( element . attr ( 'src' ) ) . toBe ( '#foo' ) ;
2622+
2623+ $rootScope . testUrl = "http://foo/bar" ;
2624+ $rootScope . $apply ( ) ;
2625+ expect ( element . attr ( 'src' ) ) . toBe ( 'http://foo/bar' ) ;
2626+
2627+ $rootScope . testUrl = " http://foo/bar" ;
2628+ $rootScope . $apply ( ) ;
2629+ expect ( element . attr ( 'src' ) ) . toBe ( ' http://foo/bar' ) ;
2630+
2631+ $rootScope . testUrl = "https://foo/bar" ;
2632+ $rootScope . $apply ( ) ;
2633+ expect ( element . attr ( 'src' ) ) . toBe ( 'https://foo/bar' ) ;
2634+
2635+ $rootScope . testUrl = "ftp://foo/bar" ;
2636+ $rootScope . $apply ( ) ;
2637+ expect ( element . attr ( 'src' ) ) . toBe ( 'ftp://foo/bar' ) ;
2638+
2639+ // Fails on IE < 10 with "TypeError: Access is denied" when trying to set img[src]
2640+ if ( ! msie || msie > 10 ) {
2641+ $rootScope . testUrl = "mailto:[email protected] " ; 2642+ $rootScope . $apply ( ) ;
2643+ expect ( element . attr ( 'src' ) ) . toBe ( 'mailto:[email protected] ' ) ; 2644+ }
2645+
2646+ $rootScope . testUrl = "file:///foo/bar.html" ;
2647+ $rootScope . $apply ( ) ;
2648+ expect ( element . attr ( 'src' ) ) . toBe ( 'file:///foo/bar.html' ) ;
2649+ } ) ) ;
2650+
2651+
2652+ it ( 'should not sanitize attributes other than src' , inject ( function ( $compile , $rootScope ) {
2653+ element = $compile ( '<img title="{{testUrl}}"></img>' ) ( $rootScope ) ;
2654+ $rootScope . testUrl = "javascript:doEvilStuff()" ;
2655+ $rootScope . $apply ( ) ;
2656+
2657+ expect ( element . attr ( 'title' ) ) . toBe ( 'javascript:doEvilStuff()' ) ;
2658+ } ) ) ;
2659+
2660+
2661+ it ( 'should allow reconfiguration of the src whitelist' , function ( ) {
2662+ module ( function ( $compileProvider ) {
2663+ expect ( $compileProvider . urlSanitizationWhitelist ( ) instanceof RegExp ) . toBe ( true ) ;
2664+ var returnVal = $compileProvider . urlSanitizationWhitelist ( / j a v a s c r i p t : / ) ;
2665+ expect ( returnVal ) . toBe ( $compileProvider ) ;
2666+ } ) ;
2667+
2668+ inject ( function ( $compile , $rootScope ) {
2669+ element = $compile ( '<img src="{{testUrl}}"></img>' ) ( $rootScope ) ;
2670+
2671+ // Fails on IE < 10 with "TypeError: Object doesn't support this property or method" when
2672+ // trying to set img[src]
2673+ if ( ! msie || msie > 10 ) {
2674+ $rootScope . testUrl = "javascript:doEvilStuff()" ;
2675+ $rootScope . $apply ( ) ;
2676+ expect ( element . attr ( 'src' ) ) . toBe ( 'javascript:doEvilStuff()' ) ;
2677+ }
2678+
2679+ $rootScope . testUrl = "http://recon/figured" ;
2680+ $rootScope . $apply ( ) ;
2681+ expect ( element . attr ( 'src' ) ) . toBe ( 'unsafe:http://recon/figured' ) ;
2682+ } ) ;
2683+ } ) ;
2684+
2685+ } ) ;
2686+
2687+
2688+ describe ( 'a[href] sanitization' , function ( ) {
25402689
25412690 it ( 'should sanitize javascript: urls' , inject ( function ( $compile , $rootScope ) {
25422691 element = $compile ( '<a href="{{testUrl}}"></a>' ) ( $rootScope ) ;
0 commit comments