Reputation: 369
I was interested to know how AngularJS prevents inline <script>
tags from executing when they are included via the ng-include directive.
After a template is included and the DOM is inspected, the script tags certainly exist, but they have not been executed. How are they being disarmed?
I have begun reviewing the source code but any attempt I have made to include a script tag into the DOM myself (appendChild, innerHTML, innerText, document.write, etc.) always results in it being executed.
Thank You.
Upvotes: 4
Views: 1148
Reputation: 48968
That is an artifact of the way jqLite is implemented.
To make script tags work, simply ensure that the jQuery library is loaded before the angular.js
file.
<head>
<script src="//unpkg.com/jquery"></script>
<script src="//unpkg.com/angular/angular.js"></script>
<link rel="stylesheet" href="style.css">
<script src="script.js"></script>
</head>
The DEMO on PLNKR.
if you explain more that innerHTML is enough to prevent the script tags from executing I will select your answer as correct
HTML5 specifies that a <script>
tag inserted with innerHTML
should not execute.
However, there are ways to execute JavaScript without using <script>
elements, so there is still a security risk whenever you use innerHTML
to set strings over which you have no control. For example:
const name = "<img src='x' onerror='alert(1)'>";
el.innerHTML = name; // shows the alert
For that reason, it is recommended you not use innerHTML
when inserting plain text; instead, use Node.textContent
. This doesn't parse the passed content as HTML, but instead inserts it as raw text.
For more information, see MDN Web API Reference - Element.innerHTML.
Upvotes: 2
Reputation: 369
It looks like ng-include calls $element.html(ctrl.template);
See source on GitHub
The html function of jqLite then uses element.innerHTML = value;
to insert the content. See source on GitHub
And after testing - it looks like that is enough to not execute <script>
tags.
I've created a jsFiddle here. - #3 is the equivalent of what AngularJS is doing and it does not execute the script tags.
Upvotes: 0