2

I'm trying to compile a HTML that has style and script tags inside it. The HTML is compiled properly and the code is added to the DOM, the style also works, but the script is not executed.

Anyone knows why?

See the code below. The "Hello World" is shown in bold, but the window.alert is not raised.

<html>
    <body>
        <div ng-app="myModule">
            <div ng-controller="myController">
                <div compile="html"></div>
            </div>
        </div>

        <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.10/angular.min.js"></script>

        <script type="text/javascript">
        <!--
            var module = angular.module("myModule", []);

            module.controller("myController", function ($scope) {
                $scope.message = "World";

                var html = "<div class='hello'>Hello {{ message }}</div>";
                var style = "<style type='text/css'>.hello { font-weight: bold; }</style>";
                var script = "<script type='text/javascript'>window.alert('Hello from JS!');</script>";

                $scope.html = html + style + script;
            });

            module.directive("compile", function ($compile) {
                return function (scope, element, attrs) {
                    scope.$watch(
                        function (scope) {
                            return scope.$eval(attrs.compile);
                        },
                        function (value) {
                            element.html(value);
                            $compile(element.contents())(scope);
                        }
                    );
                };
            });
        //-->
        </script>
    </body>
</html>
TDT
  • 514
  • 5
  • 7
  • I would say for XSS Protection but i can't give you a source for that. But from the view of a developer you shouldn't do that anyway. This is way to confusing if someone want to maintain your code so please don't do that – MrWook May 22 '18 at 06:20
  • @MrWook Thank you for your comment. I'm aware of that! This is a specific case that I asked my customer when he wants to ship the change and he answered "Yesterday!" :P So we tried to handle the solution only on back-end (html variable is filled by an AJAX request), without changes on the front-end. But I got stuck on this "problem". It could really be XSS but Chrome does not give any error on console. It's really annoying. – TDT May 22 '18 at 17:37
  • There is no need for an error. It will be escaped by angular. Even if you customer said that. Please find a better solution before you create a security hole inside your code – MrWook May 23 '18 at 05:23
  • @MrWook well.. I disagree that this may be called a security hole. I think that it is not a XSS in fact once it runs on the same domain. It is just an AJAX request that loads a javascript code. IMHO if it is/was a XSS, Chrome really needs to show at least a warn to let me (at least, again) decide to continue or not to use that website. I can not also guarantee that is AngularJS escaping it, could be Chrome. About the specific security case, no one can exploit this, except by the same way all web applications are exposed, like client-side scripting, for example. Please correct me if I'm wrong. – TDT May 23 '18 at 21:18
  • Do what you want. You don't need to compile it just use plain old JavaScript. var script = document.createElement('script'); script.type = 'text/javascript'; script.innerHTML = 'window.alert(\'Hello from JS!\');'; document.getElementsByTagName('head')[0].appendChild(script); – MrWook May 24 '18 at 09:13
  • @MrWook Yeah! The new solution do this way but it requires a little modification on the front-end. The only difference is where we appended the new script element. Is our case we append to the element itself instead of head's tag, so it gets removed when the view changes. – TDT May 24 '18 at 18:38

0 Answers0