简体   繁体   English

在javascript中转义</ script>标记

[英]Escaping </script> tag inside javascript

I'm using backbone, and the general way for passing the collections when the page load is 我正在使用骨干,以及在页面加载时传递集合的一般方法

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

which is fine and works well, until someone decides to add the text " <script>alert("owned")</script> " to one of the store fields. 这很好,效果很好,直到有人决定将文本“ <script>alert("owned")</script> ”添加到其中一个商店字段。 the last </script> obviously closes the javascript. 最后一个</script>显然关闭了javascript。 How can this be circumvented? 怎么能绕过这个呢?

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

The above outputs: 以上输出:

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

Inside a <script> block it is syntactically illegal to have any </ followed by a name—not just </script> —so you need to escape that anywhere it may appear. <script>块中,任何</后跟一个名称 - 不仅仅是</script> - 在语法上都是非法的 - 所以你需要在任何可能出现的地方进行转义。 For example: 例如:

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

This will create the sequence <\\/ inside your JS strings, which is interpreted to be the same as </ . 这将在JS字符串中创建序列<\\/ ,它被解释为与</相同。 Ensure that you use single quotes in your gsub replacement string, or else use gsub( "</", "<\\\\/" ) due to the difference between single and double quotes in Ruby. 确保在gsub替换字符串中使用单引号,或者使用gsub( "</", "<\\\\/" )因为Ruby中的单引号和双引号之间存在差异。

Shown in action: 显示在行动中:

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>

If you are using Rails (or ActiveSupport) you can enable JSON escaping : 如果您使用的是Rails(或ActiveSupport),则可以启用JSON转义

ActiveSupport::JSON::Encoding.escape_html_entities_in_json = true

Seen in action: 看到行动:

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"]

It produces JSON that is more verbose than you need to solve this particular problem, but it is effective. 它生成的JSON比解决这个特定问题所需的更冗长,但它是有效的。

The magic word is: 神奇的词是:

ActiveSupport.escape_html_entities_in_json = true

Although marked as deprecated, this still works in current rails versions (see my rails c ): 虽然标记为已弃用,但这仍适用于当前的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\"]" 

You forgot the '' 你忘记了''

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM