在 angularjs 中使用 $sce 或 Strict Contextual Escaping 有啥好处,为啥 react 不需要这样做?

Posted

技术标签:

【中文标题】在 angularjs 中使用 $sce 或 Strict Contextual Escaping 有啥好处,为啥 react 不需要这样做?【英文标题】:What is the benefit of having $sce or Strict Contextual Escaping in angularjs and why react does not need to do it?在 angularjs 中使用 $sce 或 Strict Contextual Escaping 有什么好处,为什么 react 不需要这样做? 【发布时间】:2016-06-04 02:46:58 【问题描述】:

令我感到困惑的是,我真的看不到在 angularjs 中拥有 SCE 的真正好处(即使在阅读了文档之后)关于安全性的好处,并且想知道为什么 react 不需要在其中包含这样的 SCE?

所以问题只是为了重新组合:

    SCE 的好处 为什么 Angular 可以,而 React 不可以?

【问题讨论】:

您是否不熟悉它旨在减少的漏洞类型(例如 XSS、点击劫持),或者您不了解它如何帮助减少这些漏洞? React 有 dangerouslySetInnerhtml 出于同样的原因。默认情况下,它会自动转义 HTML,您必须使用 dangerouslySetInnerHTML @JackA。我认为@sergiu 回答了第二部分,澄清了我的一个误解,我认为你所说的也是正确的,比如当不使用dangerouslySetInnerHTML 时,一个人可以对反应应用程序做什么?一个人是否可以仅仅因为在 react.js 文件中说 text = <span>0 –  而实际执行服务器端脚本? 在 React 中如果你使用 text 那么它会被自动转义并且不会发生任何不好的事情。所以默认情况下你是受保护的。如果您使用dangerouslySetInnerHTML=__html: text,那么您有责任对text 进行消毒,所以不会发生任何不好的事情,这就是为什么名称dangerously :) @SergiuParaschiv 啊...这真的很有趣!知道这一点非常有用,所以实际上 dangerouslySetInnerHTML 不应该像 angular 那样作为防止 XSS 的一种鼓励方式,对吧? 【参考方案1】:

在 React 中,如果你使用 text,那么它会被自动转义,不会发生任何不好的事情。所以默认情况下你是受保护的。如果您使用dangerouslySetInnerHTML=__html: text,那么您有责任对text 进行消毒,所以不会发生任何不好的事情,这就是名称dangerously的原因:)

Angular 也有类似的方法。它将任何字符串处理为内部可能包含危险的 HTML,因此它会自动对其进行转义。 $sce 本质上是 React 的 dangerouslySetInnerHTML,因为它将你的文本包装在一个对象中,告诉 Angular sceWrappedText 不应该被自动转义。而且,就像在 React 中一样,清理它是你的责任。

$sce 确实带有一些帮助清理程序,例如parseAsHtml,您可以使用它们在输出 HTML 之前对其进行清理。我认为它使用了$sanitize 服务并删除了ng-click 之类的东西。

澄清:不应该使用$scedangerouslySetInnerHTML,认为它们会神奇地使不安全(用户输入的)字符串安全地显示为HTML。它们存在是因为默认情况下一切都被转义了。作为开发人员,您有责任决定什么是安全的:

它来自对其进行清理的服务器; 您使用一些客户端代码(https://github.com/mganss/HtmlSanitizer、https://www.npmjs.com/package/sanitize-html 和许多其他代码)对其进行了清理 它是一段 HTML,你从本质上安全的部分粘合在一起(想想'<b>' + parseInt(this.props.numberFromTextInput, 10) + '</b>'

默认是什么意思:

控制器:

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

模板:

<div>text</div>

会输出“你好,&lt;b&gt;foo&lt;/b&gt;!”

虽然

$scope.text = $sce.trustAsHtml('&lt;b&gt;foo&lt;/b&gt;');

会输出“你好,foo!”

与 React 的 dangerouslySetInnerHTML 相同,其中 &lt;div dangerouslySetInnerHTML=__html: '&lt;b&gt;foo&lt;/b&gt;' /&gt; 将输出“Hello, foo!”而&lt;div&gt;'&lt;b&gt;foo&lt;/b&gt;'&lt;/div&gt; 将被转义。

【讨论】:

我可以详细说明They exist so that by default everything is escaped. 我不太清楚default 是什么意思?就像,这是否意味着,默认情况下,数据发送到服务器之前的那一刻?还是其他意思? 对不起,我的意思是“它们存在是因为” 非常感谢 :) "在 React 中如果你使用 text 那么它会被自动转义并且不会发生任何不好的事情。"这绝对不是真的。 React 不提供上下文自动转义,因此呈现如下链接 &lt;a href='javascript:console.log("XSS!")'&gt;XSS&lt;/a&gt; 可以执行任意 javascript。这是一个例子:codesandbox.io/s/xss-demo-cibwm. @AnthonyE 最初的问题和我的回答是关于清理 HTML,而不是 JS,IMO。确实,$sce.trustAsJs 存在,但我们谈论的是不同的事情。

以上是关于在 angularjs 中使用 $sce 或 Strict Contextual Escaping 有啥好处,为啥 react 不需要这样做?的主要内容,如果未能解决你的问题,请参考以下文章

深入理解AngularJS中的ng-bind-html指令和$sce服务

Angularjs 中的iframe 标签 ng-src 路径 报错问题 解决办法

如何将 $sce.trustAsResourceUrl 与 $http 服务一起使用

angularjs中避免被转义,HTMl标识能被识别,可以正常链接,下载!

AngularJS:如何解决“尝试在安全上下文中使用不安全值”?

angular中的ng-bind-html指令和$sce服务