Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular: Can I completely disable sanitizing?

Is it possible to completely disable sanitizingof HTML?

What I want to achieve is to have in my controller:

$scope.greeting = '<h2>Hello World</h2>'

And in my view

{{greeting}}

I cannot (and dont want to) use ng-bind-html and such, I want to disable sanitizing all together.

Just to give some more context - I am preparing simple "framework wrap around" for developing a template for specific system.

When you develop template for this system, they have pre-defined snippets that you can place on your page by writing "{{something}}" but it is not running on angular (probably mustache or something).

Now the template can be developed only online and it is VERY user-unfriendly proccess. Therefore I setup simple project in angular with corresponding routes etc, so everyone can develop the template on their machine and then simply copy it over to the system.

That is why in the template files it shouldnt be noticable that its done in angular, it just be as close to their system as possible.

One last note - I did try:

myApp.config(['$sceProvider',function($sceProvider){
    $sceProvider.enabled(false);
}]);

Didn't do anything for me

like image 720
Tomas Avatar asked Jun 08 '15 14:06

Tomas


People also ask

What is the goal of angular sanitize?

If you include the angular-sanitize script, inputs are sanitized by parsing the HTML into tokens. All safe tokens (from a whitelist) are then serialized back to properly escaped html string. This means that no unsafe input can make it into the returned string.

What is sanitizing in angular?

Sanitization is the inspection of an untrusted value, turning it into a value that's safe to insert into the DOM. In many cases, sanitization doesn't change a value at all. Sanitization depends on context: A value that's harmless in CSS is potentially dangerous in a URL.

Does angular sanitize user input?

Angular treats all values as untrusted by default. When a value is inserted into the DOM from a template, via property, attribute, style, class binding, or interpolation, Angular sanitizes and escapes untrusted values. Sanitization modifies the input, turning it into a value that is safe to insert into the DOM.


2 Answers

Yes you can turn off SCE but this will not cause your strings to be interpolated into HTML

Using your scenario:

  $scope.movie = {title:"<h1>Egghead.io AngularJS, Binding</h1>",
 src:"http://www.youtube.com/embed/Lx7ycjC8qjE"};

and interpolating the title directly without use of ng-bind-html="movie.title"

<p>{{movie.title}}</p>

will produce this

<h1>Egghead.io AngularJS Binding</h1>

Straight interpolation seems to be sanitized, but it is actually not compiled.

An interpolated string with HTML is treated as a string unless compiled within a directive.

Other frameworks tend to be "string based" (they feed the browser directly), whereas AngularJS is "DOM based", it compiles your HTML and manages it aggressively with scopes and watch events. Martin Fowler refers to this as Template View vs Transform View.

HTML can be compiled within Directives, but can only be interpolated in markup and controllers


I've created 2 Plunkers trying to access an "insecure url" which just means I interpolated a url in ng-src without using $sce.trustAs

Exhibit 1: Plunker 1 SCE disabled during config

Markup interpolates "insecure url":

    <p>{{movie.title}}</p>
    <iframe class="youtube-player" type="text/html" width="640" height="385" ng-src="{{movie.src}}" allowfullscreen frameborder="0">
</iframe>

App disables $sceProvider

var app = angular.module('plunker', ['ngSanitize']);
app.config(['$sceProvider',function($sceProvider){
    $sceProvider.enabled(false);
}]);
app.controller('MainCtrl', function($scope, $sce) {

  $scope.movie = {src:"http://www.youtube.com/embed/Lx7ycjC8qjE", title:"Egghead.io AngularJS Binding"};
});

The "unsafe" URL is interpolated without error. The Video is displayed.


Exhibit 2: Plunker 2 app.config commented out, ergo, using Default SCE settings

var app = angular.module('plunker', ['ngSanitize']);
//app.config(['$sceProvider',function($sceProvider){
//    $sceProvider.enabled(false);
//}]);
app.controller('MainCtrl', function($scope, $sce) {

  $scope.movie = {src:"http://www.youtube.com/embed/Lx7ycjC8qjE", title:"Egghead.io AngularJS Binding"};
});

Error:

Error: [$interpolate:interr] Can't interpolate: {{movie.src}} Error: [$sce:insecurl] Blocked loading resource from url not allowed by $sceDelegate policy. URL: http://www.youtube.com/embed/Lx7ycjC8qjE

like image 77
Dave Alperovich Avatar answered Oct 18 '22 12:10

Dave Alperovich


A while ago I managed to render some HTML returned from a service like this:

$scope.greeting = $sce.trustAsHtml('<h2>Hello World</h2>');

And in your HTML

<div ng-bind-html="htmlGreeting"></div>

Don't forget to inject the $sce service in the controller.

EDIT here's a example fiddle: https://jsfiddle.net/b78hkssn/2/

like image 42
davguij Avatar answered Oct 18 '22 14:10

davguij