Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the benefit of having $sce or Strict Contextual Escaping in angularjs and why react does not need to do it?

I am puzzled by the fact that I can't really see the true benefit of having SCE in angularjs (even after read the doc) regarding security benefit and wonder why react does not need to have such SCE in it?

So question just to regroup:

  1. The benefit of SCE
  2. Why Angular does it but React does not?
like image 879
Ezeewei Avatar asked Dec 25 '22 08:12

Ezeewei


1 Answers

In React if you use {text} then it'll be automatically escaped and nothing bad can happen. So by default you are protected. If you use dangerouslySetInnerHTML={{__html: text}} then it's your responsibility to sanitize text so nothing bad happens, that's why the name dangerously :)

Angular has a similar approach. It handles any string as possibly having dangerous HTML inside, so it automatically escapes it. $sce is in essence React's dangerouslySetInnerHTML, in that it wraps your text in an object telling Angular that {sceWrappedText} should not be automatically escaped. And, just like in React, it's your responsibility to sanitize it.

$sce does come with some helper sanitizers like parseAsHtml that you can use to sanitize the HTML before outputing it. I think it uses the $sanitize service and removes stuff like ng-click and such.

To clarify: neither $sce nor dangerouslySetInnerHTML should be used thinking they will magically make unsafe (user inputed) strings safe to display as HTML. They exist because by default everything is escaped. You as a developer are responsible to decide what is safe to use:

  • it comes from the server where it was sanitized;
  • you sanitized it using some client-side code (https://github.com/mganss/HtmlSanitizer, https://www.npmjs.com/package/sanitize-html, and many many others)
  • it's a piece of HTML you glued together from pieces that are by nature safe (think '<b>' + parseInt(this.props.numberFromTextInput, 10) + '</b>')

What default means:

Controller:

$scope.text = '<b>foo</b>';

Template:

<div>{{text}}</div>

Would output "Hello, <b>foo</b>!"

While

$scope.text = $sce.trustAsHtml('<b>foo</b>');

would output "Hello, foo!"

Same with React's dangerouslySetInnerHTML where <div dangerouslySetInnerHTML={{__html: '<b>foo</b>'}} /> would output "Hello, foo!" while <div>{'<b>foo</b>'}</div> would be escaped.

like image 171
Sergiu Paraschiv Avatar answered Dec 28 '22 15:12

Sergiu Paraschiv