Angular.js中的部分HTML字符串转义

时间:2014-11-21 12:22:13

标签: javascript angularjs security angular-translate

我已经阅读了有关棱角分享默认情况下的所有内容$sce的方式,因此我通过过滤器将$sce.trustAsHtml()数据列入白名单(自{{ 1}}无法正常使用),如下所示:

$sce

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

要深入了解详细信息 - 我的translations中包含HTML,但它们中包含可替换的令牌/变量。所以translations support HTML,但我不希望提供的代币包含HTML。

我的过滤器<sup class="ng-binding" ng-bind-html="row|logEntry"></sup> 在内部看起来像这样:

logEntry

例如,我可以翻译有关userX更改文章的内容,但如果用户的名称包含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); <我不希望结果文本触发alert() / p>

<script>alert('evilname')</script>本身并不相关,它可以是任何HTML字符串,我希望将某些部分替换为常规JS $translate,内容保持&#34;作为文本&#34;。< / p>

所以我的问题是 - 如何逃避HTML的部分?我是否必须在视图内部分切片?或者我必须诉诸自定义转义( Fastest method to escape HTML tags as HTML entities?)?这种事情是否有首选做法?

2 个答案:

答案 0 :(得分:5)

让我们首先重构您的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);

最后,角度的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');

请参阅文档了解更多消毒价值策略

答案 1 :(得分:3)

在您的应用中添加

HttpContextAccessor.HttpContext

这样,您的代码如下所示:

$translateProvider.useSanitizeValueStrategy('escapeParameters');