【问题标题】:How do I pass a whilte list to the caja web standalone script如何将白名单传递给 caja web 独立脚本
【发布时间】:2014-10-13 13:07:26
【问题描述】:

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

我找到了https://code.google.com/p/google-caja/wiki/CajaWhitelists,它描述了如何定义白名单,但我不知道如何将其传递给 html-css-sanitizer-minified.js 提供的 html_sanitize 方法

我试过调用 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 项目才能获得更新的项目。

【问题讨论】:

    标签: javascript google-caja


    【解决方案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。它包含像“nav”这样的元素,因此它已针对 html5 进行了更新。

    我尝试对 css 解析做同样的事情,我设法提取了 defs,但它们取决于位数,而且我无论如何也找不到计算哪些位用于哪些默认值。

    【讨论】:

      【解决方案2】:

      我决定采用另一种方法。我留下了另一个答案,以防我设法找到 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);
      

      这种方法还可以处理我需要的样式。可以为这些人注入另一个白名单,但我不需要,所以我没有写。

      【讨论】:

        猜你喜欢
        • 2018-02-03
        • 2016-02-04
        • 2014-05-25
        • 2021-10-22
        • 1970-01-01
        • 2013-01-21
        • 1970-01-01
        • 2013-10-15
        • 1970-01-01
        相关资源
        最近更新 更多