25

In AngularJS, in the following scenario, Firefox puts unsafe: in front of urls that are generated in the following fashion. It then display an error-page saying "The address wasn't understood". This is a file request on my local PC.

Link:

<li ng-repeat="fruit in fruits">
    <a href="{{ fruit.link }}">{{ fruit.title }}</a>
</li>

Array:

$scope.fruits = [
    {   "title"     :   "Orange",
        "link"      :   "fruits_orange.html"  }
];
Ben
  • 15,938
  • 19
  • 92
  • 138

5 Answers5

46

You are seeing side-effect of this commit: https://github.com/angular/angular.js/commit/9532234bf1c408af9a6fd2c4743fdb585b920531 that aims at addressing some security hazards.

This commit introduced a non-backward compatible change for urls starting with file:// (it was subsequently relaxed in https://github.com/angular/angular.js/commit/7b236b29aa3a6f6dfe722815e0a2667d9b7f0899

I assume that you are using one of 1.0.5 or 1.1.3 AngularJS versions. If so you can re-enable support for the file:// URLs by configuring $compileProvider like so:

angular.module('myModule', [], function ($compileProvider) {

  $compileProvider.urlSanitizationWhitelist(/^\s*(https?|ftp|mailto|file):/);

});

Or in Angular 1.2.8 and above:

angular.module('myModule', [], function ($compileProvider) {

  $compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|ftp|mailto|file):/);

});
zbrunson
  • 1,587
  • 1
  • 12
  • 13
pkozlowski.opensource
  • 117,202
  • 60
  • 326
  • 286
  • 1
    Thanks, but where do I need to put this code? If I just put it into my controller (and add $compileProvider to the argument list), it says `Error: Unknown provider: $compileProviderProvider`. I am using 1.0.5 (latest from google developers). – Ben Mar 26 '13 at 13:13
  • Btw, a quick fix is just using 1.0.4. – Ben Mar 26 '13 at 13:21
  • 1
    @Ben you need to put this code in your module's configuration block as noted in my response (and the source code that goes with it). You can read about modules here: http://docs.angularjs.org/guide/module And of course reverting to 1.0.4 will make issue go away as only 1.0.5 and 1.1.3 are affected. – pkozlowski.opensource Mar 26 '13 at 13:25
  • 1
    As of Angular 1.2.8, please use `$compileProvider.aHrefSanitizationWhitelist` for `ng-href`, and other specialized functions for `src` and the like. – Interarticle Jan 08 '14 at 01:33
  • I could not get your answer to work, and until I found that the whitelist you provided did not satisfy the "#" character: from this GitHub issue: (https://github.com/angular/angular.js/issues/2901#issuecomment-24157693) came this whitelist regex: `(/^\s*((https?|ftp|mailto|file|chrome-extension|tel):)|#/)` – Eric Steinborn Oct 17 '14 at 19:02
5

Add a white list to your controller.

For Angular.js 1.2:

app.config(['$compileProvider', function($compileProvider) {
    $compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|file|tel):/);
}]);

For Angular 1.1.x and 1.0.x, use urlSanitizationWhitelist. See reference.

qqz
  • 51
  • 1
  • 3
4
    angular.module('somemodule').config(['$compileProvider' , function ($compileProvider)
    {
          $compileProvider.urlSanitizationWhitelist(/^\s*(https?|ftp|mailto):/);
    }]);
acpmasquerade
  • 1,880
  • 1
  • 18
  • 15
  • For Angular 1.2+ I used a similar solution from this thread: http://stackoverflow.com/questions/15606751/angular-changes-urls-to-unsafe-in-extension-page – Ryan Knell Apr 25 '14 at 02:38
1

I'm using angular 1.4.0 and the following format worked:

ng-href="http://{{baseURLHref}}{{baseURLPort}}/routingPathName"

Adding http:// in the beginning of ng-href helped in getting rid of the unsafe appended by ng-Sanitize

  • If you're on https, then it shouldn't be a problem to hard code everything.
  • But if you've a system that has to work on both environments, you might want to use a protocol detection from location.protocol

I'm setting the variables in $rootScope (they help with issues with proxy servers that consume css from my site)

angular.module('myApp').run(function ($route, $rootScope, $location) {
    $rootScope.baseURLHref = '';
    $rootScope.baseURLPort = '';
    if($location.host() != 'localhost'){
      $rootScope.baseURLHref = $location.host();
      $rootScope.baseURLPort = ':' + $location.port();
    }
    ...
DDM
  • 1,099
  • 15
  • 21
0
<a href="{{applicant.resume}}" download> download resume</a>


var app = angular.module("myApp", []);

    app.config(['$compileProvider', function($compileProvider) {
         $compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|local|data|chrome-extension):/);
        $compileProvider.imgSrcSanitizationWhitelist(/^\s*(https?|local|data|chrome-extension):/);

        }]);
D C
  • 708
  • 1
  • 6
  • 17