diff options
| author | Igor Minar | 2013-02-19 09:55:05 -0800 | 
|---|---|---|
| committer | Igor Minar | 2013-02-20 00:06:26 -0800 | 
| commit | 9532234bf1c408af9a6fd2c4743fdb585b920531 (patch) | |
| tree | e4b6a910b3097007e38bde6f4511e74e621b0a2b /test/ng/compileSpec.js | |
| parent | 5f5d4feadbfa9d8ecc8150041dfd2bca2b2e9fea (diff) | |
| download | angular.js-9532234bf1c408af9a6fd2c4743fdb585b920531.tar.bz2 | |
fix($compile): sanitize values bound to a[href]
Diffstat (limited to 'test/ng/compileSpec.js')
| -rw-r--r-- | test/ng/compileSpec.js | 141 | 
1 files changed, 141 insertions, 0 deletions
| diff --git a/test/ng/compileSpec.js b/test/ng/compileSpec.js index 6fbf99c3..d2eddafc 100644 --- a/test/ng/compileSpec.js +++ b/test/ng/compileSpec.js @@ -2354,7 +2354,148 @@ describe('$compile', function() {          expect(jqLite(element.find('span')[1]).text()).toEqual('T:true');        });      }); +  }); + + +  describe('href sanitization', function() { + +    it('should sanitize javascript: urls', inject(function($compile, $rootScope) { +      element = $compile('<a href="{{testUrl}}"></a>')($rootScope); +      $rootScope.testUrl = "javascript:doEvilStuff()"; +      $rootScope.$apply(); + +      expect(element.attr('href')).toBe('unsafe:javascript:doEvilStuff()'); +    })); + + +    it('should sanitize data: urls', inject(function($compile, $rootScope) { +      element = $compile('<a href="{{testUrl}}"></a>')($rootScope); +      $rootScope.testUrl = "data:evilPayload"; +      $rootScope.$apply(); + +      expect(element.attr('href')).toBe('unsafe:data:evilPayload'); +    })); + + +    it('should sanitize obfuscated javascript: urls', inject(function($compile, $rootScope) { +      element = $compile('<a href="{{testUrl}}"></a>')($rootScope); + +      // case-sensitive +      $rootScope.testUrl = "JaVaScRiPt:doEvilStuff()"; +      $rootScope.$apply(); +      expect(element[0].href).toBe('unsafe:javascript:doEvilStuff()'); + +      // tab in protocol +      $rootScope.testUrl = "java\u0009script:doEvilStuff()"; +      $rootScope.$apply(); +      expect(element[0].href).toMatch(/(http:\/\/|unsafe:javascript:doEvilStuff\(\))/); + +      // space before +      $rootScope.testUrl = " javascript:doEvilStuff()"; +      $rootScope.$apply(); +      expect(element[0].href).toBe('unsafe:javascript:doEvilStuff()'); + +      // ws chars before +      $rootScope.testUrl = " \u000e javascript:doEvilStuff()"; +      $rootScope.$apply(); +      expect(element[0].href).toMatch(/(http:\/\/|unsafe:javascript:doEvilStuff\(\))/); + +      // post-fixed with proper url +      $rootScope.testUrl = "javascript:doEvilStuff(); http://make.me/look/good"; +      $rootScope.$apply(); +      expect(element[0].href).toBeOneOf( +          'unsafe:javascript:doEvilStuff(); http://make.me/look/good', +          'unsafe:javascript:doEvilStuff();%20http://make.me/look/good' +      ); +    })); + + +    it('should sanitize ngHref bindings as well', inject(function($compile, $rootScope) { +      element = $compile('<a ng-href="{{testUrl}}"></a>')($rootScope); +      $rootScope.testUrl = "javascript:doEvilStuff()"; +      $rootScope.$apply(); + +      expect(element[0].href).toBe('unsafe:javascript:doEvilStuff()'); +    })); + + +    it('should not sanitize valid urls', inject(function($compile, $rootScope) { +      element = $compile('<a href="{{testUrl}}"></a>')($rootScope); + +      $rootScope.testUrl = "foo/bar"; +      $rootScope.$apply(); +      expect(element.attr('href')).toBe('foo/bar'); + +      $rootScope.testUrl = "/foo/bar"; +      $rootScope.$apply(); +      expect(element.attr('href')).toBe('/foo/bar'); + +      $rootScope.testUrl = "../foo/bar"; +      $rootScope.$apply(); +      expect(element.attr('href')).toBe('../foo/bar'); + +      $rootScope.testUrl = "#foo"; +      $rootScope.$apply(); +      expect(element.attr('href')).toBe('#foo'); +      $rootScope.testUrl = "http://foo/bar"; +      $rootScope.$apply(); +      expect(element.attr('href')).toBe('http://foo/bar'); +      $rootScope.testUrl = " http://foo/bar"; +      $rootScope.$apply(); +      expect(element.attr('href')).toBe(' http://foo/bar'); + +      $rootScope.testUrl = "https://foo/bar"; +      $rootScope.$apply(); +      expect(element.attr('href')).toBe('https://foo/bar'); + +      $rootScope.testUrl = "ftp://foo/bar"; +      $rootScope.$apply(); +      expect(element.attr('href')).toBe('ftp://foo/bar'); + +      $rootScope.testUrl = "mailto:foo@bar.com"; +      $rootScope.$apply(); +      expect(element.attr('href')).toBe('mailto:foo@bar.com'); +    })); + + +    it('should not sanitize href on elements other than anchor', inject(function($compile, $rootScope) { +      element = $compile('<div href="{{testUrl}}"></div>')($rootScope); +      $rootScope.testUrl = "javascript:doEvilStuff()"; +      $rootScope.$apply(); + +      expect(element.attr('href')).toBe('javascript:doEvilStuff()'); +    })); + + +    it('should not sanitize attributes other than href', inject(function($compile, $rootScope) { +      element = $compile('<a title="{{testUrl}}"></a>')($rootScope); +      $rootScope.testUrl = "javascript:doEvilStuff()"; +      $rootScope.$apply(); + +      expect(element.attr('title')).toBe('javascript:doEvilStuff()'); +    })); + + +    it('should allow reconfiguration of the href whitelist', function() { +      module(function($compileProvider) { +        expect($compileProvider.urlSanitizationWhitelist() instanceof RegExp).toBe(true); +        var returnVal = $compileProvider.urlSanitizationWhitelist(/javascript:/); +        expect(returnVal).toBe($compileProvider); +      }); + +      inject(function($compile, $rootScope) { +        element = $compile('<a href="{{testUrl}}"></a>')($rootScope); + +        $rootScope.testUrl = "javascript:doEvilStuff()"; +        $rootScope.$apply(); +        expect(element.attr('href')).toBe('javascript:doEvilStuff()'); + +        $rootScope.testUrl = "http://recon/figured"; +        $rootScope.$apply(); +        expect(element.attr('href')).toBe('unsafe:http://recon/figured'); +      }); +    });    });  }); | 
