nnc*_*nnc 21 json ruby-on-rails html-parsing ruby-on-rails-3
在Rails 3.1应用程序中,如何安全地将一些JSON数据嵌入到HTML文档中?
假设我在控制器动作中有这个:
@tags = [
{name:"tag1", color:"green"},
{name:"</script><b>I can do something bad here</b>", color:"red"}
]
Run Code Online (Sandbox Code Playgroud)
这在相应的观点中:
<script type="text/javascript" charset="utf-8">
//<![CDATA[
var tags_list = <%= @tags.to_json %>;
// ]]>
</script>
Run Code Online (Sandbox Code Playgroud)
然后我得到这个结果HTML:
var tags_list = [
{"name":"tag1","color":"green"},
{"name":"</script><b>I can do something bad here</b>","color":"red"}
];
Run Code Online (Sandbox Code Playgroud)
这会SyntaxError: Unexpected token &在Chrome中触发
如果我删除Rails的默认HTML转义<%=raw tags.to_json
%>,则返回:
var tags_list = [
{"name":"tag1","color":"green"},
{"name":"</script><b>I can do something bad here</b>","color":"red"}
];
Run Code Online (Sandbox Code Playgroud)
当然,这会破坏HTML文档</script>.
我可以以某种方式告诉to_json()方法返回更像这样的东西:
var tags_list = [
{"name":"tag1","color":"green"},
{"name":"</script><b>I can do something bad here</b>","color":"red"}
];
Run Code Online (Sandbox Code Playgroud)
我在rubyonrails-talk邮件列表上问过这个问题,我现在明白有些人认为这是一个非常糟糕的想法,但在我的情况下,只要数据中没有HTML特殊字符,它就能很好地工作.所以我只想让to_jsonHTML 返回的字符串安全,并且仍然可以正确地解析它.
更新: 基于@coreyward评论,我确实把它变成了JS字符串文字,现在看起来效果很好.它不像我希望的那样优雅的解决方案,但也不是太糟糕.这是适合我的代码:
<% tags = [{name:"tag1", color:"green"}, {name:"</script><b>I can \n\ndo something bad here</b>", color:"red"}] %>
<script type="text/javascript" charset="utf-8">
//<![CDATA[
var tags_list = $.parseJSON('<%=j tags.to_json.html_safe %>');
// ]]>
</script>
Run Code Online (Sandbox Code Playgroud)
这导致:
<script type="text/javascript" charset="utf-8">
//<![CDATA[
var tags_list = $.parseJSON('[{\"name\":\"tag1\",\"color\":\"green\"},{\"name\":\"<\/script><b>I can \\n\\ndo something bad here<\/b>\",\"color\":\"red\"}]');
// ]]>
</script>
Run Code Online (Sandbox Code Playgroud)
小智 8
您的代码只能@tags.to_json在rails3中使用,如果您启用它:
ActiveSupport.escape_html_entities_in_json = true
Run Code Online (Sandbox Code Playgroud)
否则,你的另一个选择是:
var tags_list = <%= raw @tags.to_json.gsub("</", "<\\/") %>;
Run Code Online (Sandbox Code Playgroud)
这节省了客户端必须通过$解析整个事情
小智 8
2019年正确的做法是obj.to_json用json_escape功能来包裹。json_escape直接用于转义 JSON 字符串中的特定 HTML 符号。以下示例来自文档:
json = JSON.generate({ name: "</script><script>alert('PWNED!!!')</script>"})
# => "{\"name\":\"</script><script>alert('PWNED!!!')</script>\"}"
json_escape(json)
# => "{\"name\":\"\\u003C/script\\u003E\\u003Cscript\\u003Ealert('PWNED!!!')\\u003C/script\\u003E\"}"
JSON.parse(json) == JSON.parse(json_escape(json))
# => true
Run Code Online (Sandbox Code Playgroud)
看来此页面出现在 Google 搜索结果的顶部,这就是为什么我决定提供更新的评论:)
顺便说一句,这可行,但在我看来不是一个好的解决方案:
<script type="text/javascript" charset="utf-8">
//<![CDATA[
var tags_list = <%=raw @tags.to_json.gsub('/', '\/') %>;
// ]]>
</script>
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
11549 次 |
| 最近记录: |