6

I have a simple presentation like this

<div id="{{item.id}}" ng-repeat="item in itemList">
        <div ng-bind-html="item.html"></div>
</div>

The item.html contains html like this:

<a href="http://www.youtube.com"><img src="icons/youtube.png" alt="Youtube"/></a> 

However, the resulting html does not load the image:

<a href="http://www.youtube.com"><img alt="Youtube"/></a>

After some searching, looks like angularjs does this to avoid cross-site scripting, but i was able to load an image from youtube directly.

<a href="http://www.youtube.com"><img src="http://img.youtube.com/vi/9bZkp7q19f0/0.jpg" alt="Youtube"/></a>

Further more, I was able to load all the images by using ng-bind-html-unsafe.

    <div id="{{item.id}}" ng-repeat="item in itemList">
        <div ng-bind-html-unsafe="item.html"></div>
    </div>

If I use ng-bind-html-unsafe, I don't need the ngSanitize module anymore, meaning my code is less secure? I do have use cases where I load images from external sources.

Coming to my questions:

  1. What is the difference between ng-bind-html and ng-bind-html-unsafe apart from what I have mentioned above. Is there any documentation about this? I could not find any.

  2. How do I accomplish loading images from the host server and external servers, and not having to use the unsafe directive?

Thanks!

pkrish
  • 2,229
  • 7
  • 22
  • 29

2 Answers2

4
  1. There isn't much more to add to what you said.

    ng-bind-html allows you to load HTML content into your angular app after it has been sanitized (using the $sanitise service). On the other hand, ng-bind-html-unsafe allows you to load any HTML content without being sanitized.

    The sanitise process consists on checking each element of the provided HTML content with a list of well known HTML tags/elements. Any tag/element that isn't on the list is then removed. Apart from that there are a few more validations on specific HTML attributes (such as the src).

    In your case the element <img src="icons/youtube.png" alt="Youtube"/> doesn't have a valid src attribute because it doesn't match AngularJS' URI regexp: /^((ftp|https?):\/\/|mailto:|tel:|#)/

    For more information check ngBindHtml, ngBindHtmlUnsafe and $sanitize (and AngularJS source code)

  2. I believe there isn't... especially if you don't control the HTML you are loading in. As stated on the ngBindHtmlUnsafe documentation:

    You should use this directive only if ngBindHtml directive is too restrictive and when you absolutely trust the source of the content you are binding to.

    So, it's all about trusting the source of the HTML content you're loading. In last case you can always process/'sanitise' the HTML content yourself, however that doesn't seem to be easy to accomplish, specially if the content is dynamic.

bmleite
  • 26,850
  • 4
  • 71
  • 46
  • I replaced the URI from icons/youtube.png to the full URL http://localhost/test/icons/youtube.png and I was able to use ng-bind-html. Now I am noticing another weird side effect. Using the sanitized version removes inline style information from the div contained in item.html. – pkrish Jan 17 '13 at 21:29
  • 1
    Looked through the $sanitize docs, and looks like this is by design. But I don't understand why. – pkrish Jan 17 '13 at 21:36
0

Nenad answered a question like this recently. By invoking $sce.trustAsHtml($scope.html) you will be able to mark the HTML as valid so that ng-bind-html will accept it. Even when the img src is relative and would therefore otherwise be marked as invalid.

You can find his post here

Community
  • 1
  • 1
Arnoud Sietsema
  • 558
  • 5
  • 11