1

I have a problem with ng-bind-html directive.

I get the email HTML data from external services (not trusted), so it may happen that I receive <script> tag inside message body. However I don't want to execute this JS code on my page. I am using ng-bind-html directive for this.

I created an example for this and my problem is that alert() function is executed. How to deny to do this?

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

app.controller('MainCtrl', function ($sce, $scope) {
    $scope.text = " <script>alert(222)</script> <script>alert(222)</script>";
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="MainCtrl">
    <div ng-bind-html="text"></div>
</div>

https://jsfiddle.net/Suvroc/0c0ee472/8/

2
  • If you write alert then it will execute. if you dont want alert box then use console. $scope.text = " <script>console.log(222)</script> <script>console.log(222)</script>"; Commented Mar 17, 2016 at 8:35
  • My problem is not with just alert function. The source of html is not trusted so it might be anything in the script tags. My intention is to not execute this kind of code at all. I use alert only as an example Commented Mar 17, 2016 at 9:04

4 Answers 4

1

Since you have referenced to an old version of AngularJS, you are prevented from getting proper errors, so it was difficult to interpret. I tried in a similar fashion and found out errors, which showed there is some problem with the text which has been bind containing <script>.

Actually, when one terminates the script tag, like -> </script>, the compiler generates error, showing as invalid.

This has happened with me while I was working for a project, where, the developers deliberately removed the </script> to prevent any run-time errors. Otherwise the whole code breaks.

I don't know the actual reason behind it, but it has done the trick for us in the past.

So in my code demo, the script doesn't runs itself; so for your case, just removing or preventing the ending/closing of the script tag, might just do the trick.

Meanwhile, you can have the code below:

HTML:

<div ng-app="app" ng-controller="test">
  Run time binding of HTML
  <div ng-bind-html="text"></div>
</div>

JS:

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

app.controller('test', function($scope, $sce, $timeout) {
  $scope.bindHTML = "<script>alert(123);";
  $scope.text = $sce.trustAsHtml($scope.bindHTML);
});
Sign up to request clarification or add additional context in comments.

2 Comments

This doesn't stop untrusted code from running. Trivially bypassed by emails containing other XSS vectors like <img src=x onerror=alert(1)>
@Erlend, good point, however the author didn't mentioned that case in his question. Anyways, new learning are always welcome.
1

Use DOMPurify to sanitize the data before rendering it. It is the best HTML sanitizer out there. Another alternative is to escape the whole thing, but I guess there might be other HTML tags that you want to keep?

Comments

0

You are injecting the $sce service into your controller, so it seems you are half way there. You can run the $sce.trustAsHtml(text) function on your text and that will sanitize it accordingly.

See the docs for more info: https://docs.angularjs.org/api/ng/service/$sce

Edit: Alternatively, look into using the $sanitize service in tandem with $sce, https://docs.angularjs.org/api/ngSanitize/service/$sanitize

$sanitize(text);

3 Comments

I already tired to do this in your way, but it doesn't help. Still the same behaviour jsfiddle.net/Suvroc/0c0ee472/9
Updated my answer for you.
Have you actually tried $sce.trustAsHtml(text) in your angular application? and what version of Angular are you using? The JS fiddle is still rendering the JS alert, but I have tested that code locally with angular 1.4.8 and it works, the JS does not execute and is cleaned by the $sce service.
0

I can't see any :

<script src="angular-sanitize.js">

in your code, since sanitize is not included in the AngularJS Core.

Here is a link that explains the proper way to implement it : http://blog.timsommer.be/using-ngsanitize-to-render-html-strings-in-angular/

1 Comment

angular-sanitize.js is included in JS fiddle (in External Resources). Also I can repeat this regular file. I don't wan't to skip validation. I want to make sure that <script> tag won't execute JS code

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.