【问题标题】:Escaping </script> tag inside javascript在 javascript 中转义 </script> 标记
【发布时间】:2012-02-13 18:43:53
【问题描述】:

我正在使用主干,以及在页面加载时传递集合的一般方式

window.router = new Routers.ManageRouter({store: #{@store.to_json});

这很好,效果很好,直到有人决定将文本“&lt;script&gt;alert("owned")&lt;/script&gt;”添加到商店字段之一。最后一个&lt;/script&gt; 显然关闭了javascript。如何避免这种情况?

  :javascript
    $(function() {
      window.router = new Dotz.Routers.ManageRouter({store: #{@store.to_json}});
      Backbone.history.start();
    });

以上输出:

<script>
    //<![CDATA[
      $(function() {
        window.router = new Dotz.Routers.ManageRouter({store: '{"_id":"4f3300e19c2ee41d9a00001c", "points_text":"<script>alert(\"hey\");</script>"'});
        Backbone.history.start();
      });
    //]]>
  </script>

【问题讨论】:

    标签: javascript ruby-on-rails ruby backbone.js haml


    【解决方案1】:

    &lt;script&gt; 块内,syntactically illegal 后面有任何&lt;/ 后跟一个名称——不仅仅是&lt;/script&gt;——所以你需要在它可能出现的任何地方转义它。例如:

    :javascript
       var foo = { store: #{@store.to_json.gsub('</','<\/')} };
    

    这将在您的 JS 字符串中创建序列 &lt;\/,它被解释为与 &lt;/ 相同。确保在 gsub 替换字符串中使用单引号,否则由于 Ruby 中单引号和双引号之间的差异,请使用 gsub( "&lt;/", "&lt;\\/" )

    实际效果:

    irb:02.0> s = "<b>foo</b>" # Here's a dangerous string
    #=> "<b>foo</b>"
    
    irb:03.0> a = [s]          # Wrapped in an array, for fun.
    #=> ["<b>foo</b>"]
    
    irb:04.0> json = a.to_json.gsub( '</', '<\/' )  # Sanitized
    irb:05.0> puts json        # This is what would come out in your HTML; safe!
    #=> ["<b>foo<\/b>"]
    
    irb:06.0> puts JSON.parse(json).first  # Same as the original? Yes! Yay!
    #=> <b>foo</b>
    

    如果您使用的是 Rails(或 ActiveSupport),您可以启用 JSON escaping:

    ActiveSupport::JSON::Encoding.escape_html_entities_in_json = true
    

    实际操作:

    irb:02.0> a = ["<b>foo</b>"]
    irb:03.0> puts a.to_json # Without the magic
    #=> ["<b>foo</b>"]
    
    irb:04.0> require 'active_support'
    irb:05.0> ActiveSupport::JSON::Encoding.escape_html_entities_in_json = true
    irb:06.0> puts a.to_json # With the magic
    #=> ["\u003Cb\u003Efoo\u003C/b\u003E"]
    

    它生成的 JSON 比解决此特定问题所需的更详细,但它很有效。

    【讨论】:

      【解决方案2】:

      神奇的词是:

      ActiveSupport.escape_html_entities_in_json = true
      

      虽然标记为已弃用,但它仍然适用于当前的 rails 版本(请参阅我的 rails c):

      ruby-1.9.3-head :001 > ::Rails.version
       => "3.2.1" 
      ruby-1.9.3-head :002 > ["<>"].to_json
       => "[\"<>\"]" 
      ruby-1.9.3-head :003 > ActiveSupport.escape_html_entities_in_json = true
       => true 
      ruby-1.9.3-head :004 > ["<>"].to_json
       => "[\"\\u003C\\u003E\"]" 
      

      【讨论】:

      • 奇数;也许他们或您有一个向后兼容的垫片。它在原始 ActiveSupport v3.0.7 中不起作用;尽管如此,我还是会取消我对你说它有效的反对意见。
      • 这在我的 Rails 3.2.13 应用程序中效果很好。我想知道 ActiveSupport 团队为什么会弃用这种有用的、与安全相关的功能。
      【解决方案3】:

      你忘记了''

      :javascript
          $(function() {
            window.router = new Dotz.Routers.ManageRouter({store: '#{@store.to_json}'});
            Backbone.history.start();
          });
      

      【讨论】:

      • 不。它仍然会呈现类似{id: '324234', text: '&lt;/script&gt;'... 的内容,同时会关闭脚本
      • 你能把渲染页面的HTML贴出来吗?
      猜你喜欢
      • 2015-04-22
      • 2016-04-05
      • 1970-01-01
      • 1970-01-01
      • 2012-08-24
      • 2015-06-07
      • 1970-01-01
      • 2011-05-06
      • 1970-01-01
      相关资源
      最近更新 更多