【问题标题】:Partial HTML string escaping in Angular.jsAngular.js 中的部分 HTML 字符串转义
【发布时间】:2015-01-19 14:17:43
【问题描述】:

我已经阅读了关于 angular 转义 默认情况下所有内容 和 $sce 的方式,因此我通过过滤器将带有 $sce.trustAsHtml() 的数据列入白名单(因为 $sce 未在服务中工作),像这样:

<sup class="ng-binding" ng-bind-html="row|logEntry"></sup>

但问题是,我不信任 HTML 的某些部分。

深入了解细节 - 我有 translations,其中包含 HTML,但其中包含可替换的标记/变量。所以translations support HTML,但我不希望提供的令牌包含 HTML。

我的过滤器logEntry 内部如下所示:

var translated = $translate('Log.' + msg.context.entity_type) + '.' + msg.context.action, {
        'object_name': msg.context.object_name,
        'user': msg.context.user_name
});
return $sce.trustAsHtml(translated);

例如,我可以翻译有关 userX 更改文章的内容,但如果用户名包含 &lt;script&gt;alert('evilname')&lt;/script&gt;

,我不希望结果文本触发 alert()

$translate 本身不相关,它可以是任何 HTML 字符串,我希望将某些部分替换为常规 JS .replace(),内容保持“作为文本”。

所以我的问题是 - 如何转义部分 HTML?我是否必须在视图内将其切成部分?还是我必须求助于自定义转义( Fastest method to escape HTML tags as HTML entities?)?是否有此类事情的首选做法?

【问题讨论】:

    标签: javascript angularjs security angular-translate


    【解决方案1】:

    在你的应用中添加

    $translateProvider.useSanitizeValueStrategy('escapeParameters');
    

    因此,您的代码如下所示:

    myApp.config(function ($translateProvider) {
    
        //...whatever
    
      $translateProvider.useSanitizeValueStrategy('escapeParameters');
    
    });
    

    【讨论】:

      【解决方案2】:

      让我们首先重组您的 logEntry 以分离出 interpolateParams

      var translationId = 'Log.' + msg.context.entity_type) + '.' + msg.context.action;
      var interpolateParams = {
              'object_name': msg.context.object_name,
              'user': msg.context.user_name
      };
      var translated = $translate(translationId, interpolateParams);
      return $sce.trustAsHtml(translated);
      

      您想转义来自 interpolateParams 的所有 HTML,但在翻译模板中保留任何 HTML。使用此代码复制对象,迭代其值并替换为转义的 HTML。

      var safeParams = angular.copy(interpolateParams);    
      angular.forEach(safeParams, function(value, key, obj) {     
        obj[key] = encodeEntities(value)
        // if you want safe/sanitized HTML, use this instead
        // obj[key] = $sanitize(value);
      });
      var translated = $translate(translationId, safeParams);
      

      最后,angular的encodeEntities功能没有暴露出来,所以我们不得不借用angular-sanitize.js的源码

      var SURROGATE_PAIR_REGEXP = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g,
          // Match everything outside of normal chars and " (quote character)
          NON_ALPHANUMERIC_REGEXP = /([^\#-~| |!])/g;
      function encodeEntities(value) {
        return value.
          replace(/&/g, '&amp;').
          replace(SURROGATE_PAIR_REGEXP, function(value) {
            var hi = value.charCodeAt(0);
            var low = value.charCodeAt(1);
            return '&#' + (((hi - 0xD800) * 0x400) + (low - 0xDC00) + 0x10000) + ';';
          }).
          replace(NON_ALPHANUMERIC_REGEXP, function(value) {
            return '&#' + value.charCodeAt(0) + ';';
          }).
          replace(/</g, '&lt;').
          replace(/>/g, '&gt;');
      }
      

      更新:更新到 angular-translate 2.7.0 后出现此消息:

      pascalprecht.translate.$translateSanitization: 没有消毒 策略已配置。这可能具有严重的安全性 影响。看 http://angular-translate.github.io/docs/#/guide/19_security 为 详情。

      Sp 而不是上面的trustlate 答案,angular-translate 可以通过以下方式实现相同的结果:

      $translateProvider.useSanitizeValueStrategy('escapeParameters');
      

      查看文档了解更多清理价值策略

      【讨论】:

        猜你喜欢
        • 2012-05-27
        • 1970-01-01
        • 2016-03-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-05-19
        • 2015-09-27
        相关资源
        最近更新 更多