How to render special characters like ™ in HTML with Angular JS - angularjs

I have some special characters to show in various screens of my application so i wanted to have some way where i can handle special characters like "special char - æ ™ &amp" in controller/service instead of HTML.
I know i can use
ng-bind-html
to show special characters for the example string above. However i need to show same string in multiple screens so it would make more sense for me to do it in JS. Any alternative or equivalent JS side snippet for ng-bind-html?
Note: If you have come across these kind of strings you might be knowing that they can be rendered directly with HTML but if you are using Angular JS with
{{some scope value}}
then it doesn't format special characters on it's own.

You can use $sce like so:
function myCtrl($scope,$sce){
$scope.html = $sce.trustAsHtml('HTML_CODE;');
}
And then in your HTML you use ng-bind-html to bind the content to an element.
<span ng-bind-html="html"></span>

Related

HTML escaping does not behave the same if angular-translate is used as directive (instead of as a filter)

angular-translate - version: 2.8, angular-version 1.3.5
Translation-key MyKey contains <i>Text</i>
Given snippet:
<p translate="MyKey"></p>
<p translate="{{'MyKey'}}"></p>
<p><translate>MyKey</translate></p>
<p>{{'MyKey' | translate}}</p>
Results in:
Text --> italic, why is it not escaped?
Text --> italic, why is it not escaped?
Text --> italic, why is it not escaped?
<i>Text</i> --> I expect it that way
Why does the translate-filter escapes as expected, but as directive it fails to escape anything?
I also tampered around with $translateProvider.useSanitizeValueStrategy('sanitize');, doesn't do any difference to the above example.
In AngularJS applications, the filter's output will be escaped always. This is done automatically and is not under control of the filter function itself. In the opposite, the directive has the complete control about which and how information will be appended/ removed/ and so on.
// ensure angular-sanitize.js is present
$translateProvider.useSanitizeValueStrategy('sanitize');
Sanitization is not escaping! Instead of escaping everything, it checks for valid (and secure) string (html, javascript, css). If it is valid, it will use the actual input. Otherwise it will be rejected.
I've made an overview matrix of directive, filter and escape/sanitization settings in angular-translate. The case is an ongoing issue with UTF-8 characters, but I think you will get it: http://plnkr.co/edit/8BHONOjhsxBxxO9oVYOK?p=preview
Disclaimer: I'm co-maintaining angular-translate.

Angular render markup that is nested

I get JSON like this
{
"lots of":"keys"
"description" : {
"key":"Some sample key",
"value":"This is the markup™"
}
}
from server and I ultimately iterate the description objects and populate table rows with two columns: one for the key and one for the value.
I have tried putting on my <td> tag ng-bind-html as well as injecting $sce into my controller and using trustAsHtml but so far the string always displays as it is in the JSON. Not every value will be HTML but I can easily detect based on the key if HTML is a possibility. It seemed when I put in the directive on the td it did not display anything if no HTML was present. I am interested in using something that can allow HTML in the value but not require it so I can display either
HTML fragment
<tr ng-repeat="(key, val) in record.description">
<td>{{key}}:</td>
<td>{{val}}</td>
</tr>
I created a quick fiddle here:
https://jsfiddle.net/frishi/mvw97s3q/6/
I used angular-sanitize, which I am not sure you mentioned injecting in your module dependency list. Either way, the example works simply by using ng-bind-html
Relevant docs page: https://docs.angularjs.org/api/ng/directive/ngBindHtml
It works by using the directive ng-bind-html on the element you want to display the HTML string in. You use it like so:
<p ng-bind-html="data.firstName"></p>
assuming that data.firstName = "<strong>FeeFee</strong>" or something like that.
I would also like to add that Angular does not allow this natively because of legitimate security concerns. That and the fact that allowing arbitrary HTML to be rendered might not always produce desirable results. Your page layout could quite possibly break because of some HTML you allowed to be passed through.
Angular was designed with security in mind, and will prevent you from displaying HTML from raw strings whenever possible - to prevent various injection attacks.
Here is workarround for your problem: AngularJS: Insert HTML from a string. Generally you should use ng-bind-html insted of ng-bind (this is used by curly braces).

Can the `linky` filter be used with text containing html tags?

From the linky docs it seems it should work with ng-bind-html. However, if the text contains html tags, then linky overrides the actual html interpretation to transform URLs into links.
This can be seen by for instance writing
Pretty text with some links:<br/><img src="http://something.com/lol.gif">
http://angularjs.org/,
mailto:us#somewhere.org,
another#somewhere.org,
and one more: ftp://127.0.0.1/.
in the example at the bottom of the linky docs page.
Is there a way to firstly sanitise and interpret html using ng-bind-html and only later parse the resulting text to add clickable links?

How to change valid HTML tags that get rendered in ng-bind-html?

I have a text editor (textAngular) that I've modified to limit the number of valid HTML tags I can generate using that tool. Now, I want to only support a limited number of HTML elements (h3, h4, h5, h6, ol, ul) to produce a news story but I want to disable some of the valid HTML rendered by ng-bind-html. Namely, I want to remove , tags as a valid tags because they could have disastrous results for this user generated content.
Is it possible to remove and tags as something rendered by ng-bind-html?
Unfortunately no, it isn't possible to config the valid HTML tags.
The ng-bind-html use the $sanitize service to strip invalid tags/attributes, and you can see in the source code that all the configurations are private.
// Safe Block Elements - HTML5
var blockElements = angular.extend({}, optionalEndTagBlockElements, makeMap("address,article," +
"aside,blockquote,caption,center,del,dir,div,dl,figure,figcaption,footer,h1,h2,h3,h4,h5," +
"h6,header,hgroup,hr,ins,map,menu,nav,ol,pre,script,section,table,ul"));
// Inline Elements - HTML5
var inlineElements = angular.extend({}, optionalEndTagInlineElements, makeMap("a,abbr,acronym,b," +
"bdi,bdo,big,br,cite,code,del,dfn,em,font,i,img,ins,kbd,label,map,mark,q,ruby,rp,rt,s," +
"samp,small,span,strike,strong,sub,sup,time,tt,u,var"));
If you really want it, one way you could do is to copy the angular-sanitize.js and modify the valid HTML tags configuration directly.
Please note that if you do it that way, all the ng-bind-html in your entire application will be also affected. If that is undesired, you have to write your own custom directive and inject/use your modified version of $sanitize instead.
If you're into modifying textAngular already, you could modify something around the taCustomRenderers Section of the code and use ta-bind instead of ng-bind-html. They do nearly the same thing except ta-bind runs all the extra renderers.
Custom Renderers Code: textAngularSetup, textAngular - probably in this one you can do your stripping out of unwanted code.

angularjs + cross-site scripting preventing

Is Angularjs takes care of XSS attack. I have read that ng-bind takes care. But When i try to do a sample to test that, it allows me to insert html tags in input type with ng-model...it didn't escape the Html tags.
I have lot of input element in our page, which binds with ng-model, what should I do to make sure if I input a html tags ,angular ignores the html/scrip tags.
ex.
<input id="name" ng-model="name"></input>
if I input as
'Hello, <b>World</b>!'
$scope.name contains the same what I entered ,didn't exclude the tags. i.e
var val = $scope.name;
console.log(val);
prints as same
'Hello, <b>World</b>!'
Please let me know how to solve this in angularjs.
thank
Look at here : http://docs.angularjs.org/api/ngSanitize/service/$sanitize
If you want escape use ng-bind, it ll render the tag without interpretation like that :
Hello <b>World</b> not like Hello World !
Do you understand ? so ng-bind is safe because it doesn't care about HTML tags.
If you want that your HTML tags be interpreted but safely just use ng-bind-html !
For example if you want to display this string :
'Hello <b>World</b><input type="text" />'
The result will be : Hello World but without the input because AngularJS compiler uses $sanitize service and check a whitelist of HTML elements and an iput is not authorized.
Maybe ng-bind-html is what you're looking for.
If you just want be sure that the user can't put html tags in your input just use the directive ng-pattern on your inputs !
http://docs.angularjs.org/api/ng/directive/input
It takes a regex for allowed characters in your input !
Hope it helps !
I don't believe that AngularJS has default whitelist input validation, which is what your test exercises. So a user can pretty much input anything they like. This is not surprising - whitelists are very domain specific, and Angular is a framework designed for a wide range of domains.
The main defense against XSS is to properly encode all untrusted data (see https://www.owasp.org/index.php/Top_10_2013-A3-Cross-Site_Scripting_(XSS)). This, Angular does by default.
Bottom line is that AngularJS is intended to be secure from XSS by default, no special action required. You can verify some basic scenarios by trying to output what you input into a view using the normal {{scopevariable}} notation.
I did find a detailed analysis of AngularJS XSS vulnerability: https://code.google.com/p/mustache-security/wiki/AngularJS. At the end of the comments, there is a link to a google doc with further discussion and response from the angular team.

Resources