Reputation: 2207
My question is similar to a previous one, except I would like to retain the ability to use directives.
The problem:
I have a page with mixed legacy server rendered content and AngularJS content. The server rendered content is rendered to escape all HTML, but not curly braces. So there could be user generated content containing "{{ }}". This is mixed in with Angular content. So the template on our server may have something like:
Hello <<$username>>, the current temperature is {{ current_temp }}
And someone sets $username to something with angular code, so it's rendered to the client like
Hello {{ object.dangerousfunction() }}, the current temperature is {{ current_temp }}
And now Angular evaluates the content that wasn't intended for angular.
The Only Solution I Can Find:
I can use ngNonBindable around all server generated content:
Hello <span ng-non-bindable><<$username>></span>, the current temperature is {{ current_temp }}.
And then angular will ignore what it should. Except this is a legacy app and there's a large code base with a lot of possibly dangerous points.
The Solution I Want But Can't Find a Way to Do:
I'd rather just disable curly braces altogether (Not just replace them with something else via $interpolateProvider config), and only process directives. So instead my server side template becomes:
Hello <<$username>>, the current temperature is <span ng-bind="current_temp"></span>.
Now, legacy code base is safe and needs to adjustments, and angular only operates on ng-* directives, which are safe because user generated content is already protected against arbitrary html. Is there any way to do that?
Upvotes: 1
Views: 815
Reputation: 46
One way to solve the problem would be to configure your server to escape interpolation in user-generated content. This can be done with the \
character.
{{something}}
becomes \{\{something\}\}
You can read more about that here: https://docs.angularjs.org/api/ng/service/$interpolate
If this solution doesn't suit you, you could use a simple decorator to override the $interpolateProvider
service like so:
.config(['$provide', function($provide) {
$provide.decorator('$interpolate', function() {
return angular.extend(function() {}, {
startSymbol: angular.noop,
endSymbol: angular.noop
});
})
}])
Here's a fiddle that demonstrates it: http://jsfiddle.net/eLfs4vn1/5/
However this will probably be worse performance-wise than to for example use a ng-non-bindable
directive on a root element, since angular will still search for bindings.
Nevemind, that was a bad idea.
Upvotes: 1