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:
- The benefit of SCE
- Why Angular does it but React does not?
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:
- The benefit of SCE
- Why Angular does it but React does not?
- Are you not familiar with the types of vulnerabilities it is intended to reduce (e.g., XSS, clickjacking) or do you not see how it helps to reduce them? – Jack A. Commented Feb 22, 2016 at 16:26
-
1
React has
dangerouslySetInnerHTML
for the same reason. By default it automatically escapes HTML and you have to usedangerouslySetInnerHTML
. – Sergiu Paraschiv Commented Feb 22, 2016 at 16:29 -
@JackA. I think @sergiu answered the 2nd part which clarified a mis-conception I had, and I think what you said is true as well, like what can a person do to a react app when the
dangerouslySetInnerHTML
is not used? can a person actually execute server side script just because, let saytext = <span>0 –
in a react.js file? – ey dee ey em Commented Feb 22, 2016 at 16:44 -
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 usedangerouslySetInnerHTML={{__html: text}}
then it's your responsibility to sanitizetext
so nothing bad happens, that's why the name dangerously :) – Sergiu Paraschiv Commented Feb 22, 2016 at 16:48 -
@SergiuParaschiv ah... thats really interesting! very useful to know, so actually
dangerouslySetInnerHTML
should not really be an encouraged way to prevent XSS as what angular does, right ? – ey dee ey em Commented Feb 22, 2016 at 16:52
1 Answer
Reset to default 10In 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 e 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 es from the server where it was sanitized;
- you sanitized it using some client-side code (https://github./mganss/HtmlSanitizer, https://www.npmjs./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.