2

在我们的 Angular 应用程序中,我们有一个在服务器端填充用户内容的链接。所以我们需要告诉 Angular 不要解释那个链接内容。否则,如果用户或攻击者将 Angular 绑定表达式放在那里(比如 {{User.Password}}),那么 Angular 会评估它,从而打开一个安全漏洞——一种 XSS 攻击。

ng-non-bindable主要是这样做的。但是,我们也希望链接本身由 Angular 操作。

<a href="" class="side-bar-element" ng-class="{ 'side-bar-element-selected': isSiteSelected(@site.value.ID) }">@site.value.Name</a>

@site.value.Name 是插入内容的服务器端代码。

如果我们将 ng-non-bindable 放在 a 元素上,那么 ng-class 将不起作用。我能看到的唯一解决方案是在其中插入另一个 span/div 并将 ng-non-bindable 应用于:

<a href="" class="side-bar-element" ng-class="{ 'side-bar-element-selected': isSiteSelected(@site.value.ID) }"><span ng-non-bindable>@site.value.Name</span></a>

这看起来很笨拙,必须修改 HTML 结构才能阻止 Angular 干扰服务器端数据。

有没有更清洁的解决方案?

理想情况下,我希望 ng-non-bindable (或变体)表示“不绑定内容,但将此元素视为正常”。

4

1 回答 1

0

如果用户或攻击者将 Angular 绑定表达式放入用户内容(比如 {{User.Password}}),那么 Angular 会评估它,从而打开一个安全漏洞——一种 XSS 攻击。

使用$delegate服务降低ng-non-bindable指令优先级:

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="nonBindableExample">  
  <script>
    function delegator($delegate)
     {
     /* Override the directive definition object (DDO) */ 
     $delegate[0].priority = 0;
     
     return $delegate;
     }


    function provider($provide)
     {
     /* Decorate ng-non-bindable with a proxy function */
     $provide.decorator('ngNonBindableDirective', ["$delegate", delegator]);
     }

    /* Inject the provider and the delegator methods with services */
    provider['$inject'] = ['$provide'];
    delegator['$inject'] = ['$delegate'];

    /* Inject the module with the new provider */
    angular.module('nonBindableExample', []);
    angular.module("nonBindableExample").config(["$provide",provider]);
  </script>
  
<div>{{$id}}</div><div ng-non-bindable class="{{$id}}">{{$id}}</div></div>
</body>

当在单个 DOM 元素上定义了多个指令时,有时需要指定应用指令的顺序。优先级用于在调用编译函数之前对指令进行排序。优先级被定义为一个数字。首先编译具有更高数值优先级的指令。预链接功能也按优先级顺序运行,但后链接功能按相反顺序运行。具有相同优先级的指令的顺序未定义。默认优先级为 0。

或者简单地通过以下方式分隔用户内容<script type="text/ng-template">

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
  <!--Declare module-->
  <script>
  angular.module('foo', []);
  </script>

<!--Auto Bootstrapping-->
<div ng-app="foo">  
  <!--Inline Template-->
  <script type="text/ng-template" id="baz">
    <span ng-non-bindable>Hi {{bar}}</span>
  </script>

  <!--data binding-->
  <a href="" ng-init="bar=1" ng-class="{{bar}}" ng-include="'baz'"></a>
</div>

ng-include指令与a元素一起使用,并将元素span与指令一起使用ng-non-bindable以将文本与元素分离。

参考

于 2016-02-11T02:56:42.863 回答