如何将whilte列表传递给caja web独立脚本

时间:2014-10-13 13:07:26

标签: javascript google-caja

我使用http://caja.appspot.com/html-css-sanitizer-minified.js来清理用户html,但在某些情况下,我想将所用的标签限制为白名单。

我发现https://code.google.com/p/google-caja/wiki/CajaWhitelists描述了如何定义白名单,但我无法解决如何将其传递给html-css-sanitizer-minified提供的html_sanitize方法。 JS

我试过调用html.sanitizeWithPolicy(the_html,white_list);但我收到一个错误:

TypeError: a is not a function

由于缩小而难以调试,但似乎html-css-sanitizer-minified.js不包含html-sanitizer.js文件中的所有内容。

我尝试过使用html-sanitizer.js和cssparser.js而不是缩小版本,但是在调用它之前我遇到了错误,大概是因为我错过了其他依赖项。

我该如何做到这一点?

编辑:sanitizeWithPolicy确实存在于缩小的文件中,但在此过程中缺少某些内容。这表明此文件无法与自定义白名单一起使用。我现在正在调查是否有可能找出我需要包含哪些未经过模仿的文件来制作我自己的版本。

Edit2:我错过了两个文件https://code.google.com/p/google-caja/source/browse/trunk/src/com/google/caja/plugin/html4-defs.js?spec=svn1950&r=1950https://code.google.com/p/google-caja/source/browse/trunk/src/com/google/caja/plugin/uri.js?r=5170

但是我现在收到错误,因为sanitizeWithPolicy希望函数不是白名单对象。另外html4-defs.js文件非常陈旧,根据this,我必须构建caja项目才能获得更新的文件。

2 个答案:

答案 0 :(得分:1)

我通过下载未经文明的文件解决了这个问题

https://code.google.com/p/google-caja/source/browse/trunk/src/com/google/caja/plugin/html-sanitizer.js

https://code.google.com/p/google-caja/source/browse/trunk/src/com/google/caja/plugin/uri.js

https://code.google.com/p/google-caja/source/browse/trunk/src/com/google/caja/plugin/html4-defs.js?spec=svn1950&r=1950 (最后一个来自一个旧的修订版。这个文件是从Java文件构建的,如果有更新的文件,那将是很好的。)

然后我向html-sanitizer.js添加了一个新函数

/**
* Trims down the element white list to just those passed in whilst still not allowing unsafe elements.
* @param {array} custom_elements An array of elements to include.
*/
function useCustomElements(custom_elements) {
  var length = custom_elements.length;
  var new_elements = {};
  for (var i = 0; i < length; i++) {
      var key = custom_elements[i].toLowerCase();
      if (typeof elements.ELEMENTS[key] !== 'undefined') {
          new_elements[key] = elements.ELEMENTS[key];
      }
  }
  elements.ELEMENTS = new_elements;
};

然后我使用其他公共函数语句将此函数设置为公共文件的末尾。

html.useCustomElements = html['useCustomElements'] = useCustomElements;

现在我可以这样称呼它:

var raw = '<p>This element is kept</p><div>this element is not</div>';
var white_list ['p', 'b'];
html.useCustomElements(white_list)
var sanitized = html.sanitize(raw);

然后我手动将一些html5元素添加到html4-defs.js文件中(那些只是定义块元素的文件)。

属性清理仍然被打破。这是因为html4-defs.js文件与html-sanitizer.js过时了。我在html-sanitizer.js中改变了这个:

if ((attribKey = tagName + '::' + attribName,
     elements.ATTRIBS.hasOwnProperty(attribKey)) ||
    (attribKey = '*::' + attribName,
     elements.ATTRIBS.hasOwnProperty(attribKey))) {
  atype = elements.ATTRIBS[attribKey];
}

if (elements.ATTRIBS.hasOwnProperty(attribName)) {
  atype = elements.ATTRIBS[attribName];
}

这远非理想,但没有编译Caja并生成最新的html-defs.js文件,我无法看到解决方法。

这仍然会使css消毒。我也想这样,但是我错过了css def文件,并且无法通过搜索找到任何工作,所以我暂时将其关闭。

编辑:我设法从html-css-sanitizer-minified.js中提取html-defs。 我已将副本上传到here。它包括像“导航”这样的元素。所以它已经更新为html5。

我试图对css解析做同样的事情,我设法提取了defs,但是它们依赖于一个位数,我无论如何都无法计算出哪些位用于哪个默认值。

答案 1 :(得分:1)

我决定采用另一种方法。我已经离开了另一个答案,以防我设法找到css定义的位值,因为如果我可以让它工作,它会比这更好。

这次我采用了html-css-sanitizer-minified文件,并在其中注入了一些代码,以便可以修改元素和属性。

搜索:

ka=/^(?:https?|mailto)$/i,m={};

之后插入以下内容:

var unmodified_elements = {};
for(var property_name in $.ELEMENTS) {
    unmodified_elements[property_name] = $.ELEMENTS[property_name];
};
var unmodified_attributes = {};
for(var property_name in $.ATTRIBS) {
    unmodified_attributes[property_name] = $.ATTRIBS[property_name];
};

var resetElements = function () {
    $.ELEMENTS = {};
    for(var property_name in unmodified_elements) {
        $.ELEMENTS[property_name] = unmodified_elements[property_name];
    }
    $.f = $.ELEMENTS;
};

var resetAttributes = function () {
    $.ATTRIBS = {};
    for(var property_name in unmodified_attributes) {
        $.ATTRIBS[property_name] = unmodified_attributes[property_name];
    }
    $.m = $.ATTRIBS;
};

var resetWhiteLists = function () {
    resetElements();
    resetAttributes();
};

/**
 * Trims down the element white list to just those passed in whilst still not allowing unsafe elements.
 * @param {array} custom_elements An array of elements to include.
 */
var applyElementsWhiteList = function(custom_elements) {
    resetElements();
    var length = custom_elements.length;
    var new_elements = {};
    for (var i = 0; i < length; i++) {
        var key = custom_elements[i].toLowerCase();
        if (typeof $.ELEMENTS[key] !== 'undefined') {
            new_elements[key] = $.ELEMENTS[key];
        }
    }
    $.f = new_elements;
    $.ELEMENTS = new_elements;
};

  /**
   * Trims down the attribute white list to just those passed in whilst still not allowing unsafe elements.
   * @param {array} custom_attributes An array of attributes to include.
   */
var applyAttributesWhiteList = function(custom_attributes) {
    resetAttributes();
    var length = custom_attributes.length;
    var new_attributes = {};
    for (var i = 0; i < length; i++) {
        var key = custom_attributes[i].toLowerCase();
        if (typeof $.ATTRIBS[key] !== 'undefined') {
            new_attributes[key] = $.ATTRIBS[key];
        }
    }
    $.m = new_attributes;
    $.ATTRIBS = new_attributes;
};

m.applyElementsWhiteList = applyElementsWhiteList;
m.applyAttributesWhiteList = applyAttributesWhiteList;
m.resetWhiteLists = resetWhiteLists;

您现在可以应用白名单:

var raw = "<a>element tags removed</a><p class='class-removed' style='color:black'>the p tag is kept</p>";
var tag_white_list = [
    'p'
];
var attribute_white_list = [
    '*::style'
];
html.applyElementsWhiteList(tag_white_list);
html.applyAttributesWhiteList(attribute_white_list);
var san = html.sanitize(raw);

这种方法也对我需要的样式进行了清理。可以为那些注入另一个白名单,但我不需要那样,所以我没有写过。