【问题标题】:How is concatenating urls in templates in angular less secure than in other locations?如何在 Angular 模板中连接 url 的安全性低于其他位置?
【发布时间】:2014-05-25 13:03:51
【问题描述】:

我有一个类似这样的 angularjs 模板:

<img ng:src="/resources/{{id}}/thumbnail" />

但是这会导致$interpolate:noconcat error。与此模板相反:

<img ng:src="{{fullUrl}}" />

甚至:

<img ng:src="{{id|createThumbnailURL}}" />

(其中 createThumbnailURL 是一个简单的过滤器,它执行与上面相同的连接)工作得很好。

文档说:

连接表达式使得很难推断某些表达式是否 连接值的组合使用起来不安全,并且很容易 导致XSS。

嗯,是的,静态 URL 总是比串联 URL 更容易评估,我明白了这一点。但是,对于我来说,拥有可以通过简单连接构建的 URL 的 REST-API 并不少见,并且连接必须完成somehwere。我可以在控制器甚至服务器端执行此操作,但是如何改进以将串联移动到其他位置?推荐的解决问题的方法是什么?

更新

这里是错误的演示:http://cipher-code.de/tmp/angular3/index.xhtml

也许这与页面是 XML 有关。

【问题讨论】:

  • 很确定您的第一个示例应该可以工作。这是一个工作示例:plnkr.co/edit/rCjtaoiWEczflENZl7AR您可以创建一个说明您的问题的 plunker 吗?
  • @Beyers:我在我的问题中添加了一个演示链接。当你问我第一次尝试 plunkr 时,我无法在那里重现错误。出乎意料地进来了……

标签: javascript angularjs


【解决方案1】:

这称为 SCE(严格上下文转义): 像许多“严格”模式一样,这是可配置的。但从 V 1.2 开始,它会自动设置为 true。

更具体地说,在 Angular 认为易受攻击的上下文中(如 url),允许的插值较少(严格性)。您的 URL 连接正在被“清理”。

您已经知道原因:XSS 攻击。它还用于保护开发者:一个稍微错误的 url 可能会导致数据删除或覆盖。

您可能会感到困惑,为什么全字符串插值ng:src="{{fullUrl}}" 比字符串连接ng:src="/resources/{{id}}/thumbnail" 安全得多。 TBH,我不确定是否存在严重差异,但这些都是判断要求。


你有一些替代方法来处理这种烦恼:

1) 将你的 url 结构包裹在 $sce.trustAs()

<img ng:src="sce.trustAs('url', '/resources/{{id}}/thumbnail')" />

2)如果您选择,您可以在您的应用程序中禁用 SCE

angular.module('myApp').config(function($sceProvider) {
    $sceProvider.enabled(false);
});

更正:

您不能从指令调用 $sce 服务。只有 $scope 服务是直接可用的。但是您可以使用函数(或使用函数的指令)。

    $scope.createUrl = function (strName) {
        var truststring = '/resources/' + strName + '/thumbnail';

        return truststring;
    }

你的指令调用看起来像

<img ng:src="{{ createUrl(id) }}" />

在这种情况下,如果你将你的串联包装在一个函数中,你甚至可能不需要去净化它,因为你不会违反 SCE 规则。

【讨论】:

  • 你也可以使用getTrustedResourceUrl('/resources/{{id}}/thumbnail');
  • trustAsSCE disabled 都出现同样的错误。
  • @Aperçu:getTrustedResourceUrl 出现同样的错误
  • @DaveA:是的,这就是我现在正在做的事情。实际上我正在使用过滤器,但它并没有太大的区别。我仍然感到困惑,特别是因为当页面是 XML 页面时似乎还有其他规则生效......而且我仍然想知道制定这条规则的人会对此说些什么。对我来说,由于不知道如何应该完成,因此绕过 SCE 只是一种黑客行为。他们会说这是推荐的方式,因为它更容易评估 XSS?
  • @yankee,你所有的观察都是正确的。 SCE 的实现很奇怪。以至于我什至建议将其关闭。您绝不是唯一一个将其视为令人讨厌而不是有价值的功能的人。公平地说,谷歌在提供语言供其他开发人员使用方面仍然是新手。他们使用 Angular 的方式与大多数 Angular 用户的方式不同。这是“实施”良好实践的第一步,我相信它们会适应和发展。希望他们会意识到客户开发是非常制度化的,并且他们会尽量不执行任何类型的标准。
【解决方案2】:

我加入聚会有点晚了,但这是我的两分钱:

用(非常)简单的话:

(1)
Angular 使用 $sce 服务来执行“严格的概念转义”(SCE)。基本上,SCE “要求在某些上下文中进行绑定以产生一个标记为可安全用于该上下文的值”

这是 Angular 为开发人员提供的一种保护机制,可以轻松保护您的应用(某些方面)(这对于根据用户输入绑定值的应用更为重要)。

(2)
有些地方(即属性)被认为更容易受到某些类型的攻击(例如 XSS),SCE 对它们使用更严格的规则。一些示例是表单的 action 或框架或对象的 src/ngSrc

(3)
根据 Angular 当前的实现(v1.2.16),当这样一个易受攻击的属性被分配一个包含超过 1 个“部分”的值时,将引发错误。一部分(根据$interpolate服务的解析算法是{{}}中包含的表达式的一部分或{{}}之外的表达式的一部分。

在您的情况下,/resources/{{id}}/thumbnail 被解析为 3 个部分:
/resources/{{id}}/thumbnail


那么,多于 1 个部分有什么问题???

在视图中连接与在控制器中连接并使用单部分表达式在本质上没有什么比这更不安全的了。

引用 Angular 的源代码(强调我的):

// 连接表达式使得很难推断出某些组合是否是
// 连接的值使用起来不安全,很容易导致 XSS。通过要求一个
// iframe[src]、object[src]等使用单个表达式,我们保证value
// 使用的是 由一些 JS 代码在更可测试的地方分配或构造的
// 清楚地表明您将值绑定到某个用户控制的值。这有助于减少
// 审核 XSS 问题时的负载

因此,这是 Angular 强制您进行“更安全”实践的方式。在视图中构造值可测试性较低不太明确,因此您(或其他人)将更难审核应用程序的 XSS 漏洞(增加发生 XSS 漏洞的概率)安全问题)。


有几种方法(在 DaveA 的回答中已经提到)来规避这一点。 (不过,我绝对不会完全禁用 $sce。)

【讨论】:

  • 很多优点。就我个人而言,我对 SCE 感到很痛苦。作为 .NET 开发人员,我很欣赏作为工具的严格性。在 SCE 的情况下,我觉得它太不一致而没有用处。但我同意你的观点,SCE 有价值。而且我相信 Angular 会不断发展壮大。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-19
  • 2016-05-13
  • 2018-05-25
  • 1970-01-01
  • 1970-01-01
  • 2020-02-15
相关资源
最近更新 更多