防止 Rails 中 escape_javascript() 输出中的 XSS
在我正在开发的应用程序中,客户端视图是根据数据库中的一些记录生成的。我首先生成记录的 JSON,将其保存在页面的变量中,然后使用 JS 构建界面。
问题在于记录包含用户生成的字段,因此应用程序容易受到 XSS 的影响。如果您让 JSON 通过 escape_html
(不调用 html_safe
),它会搞乱引号。
获取代码。在我的模型中:
Class Foo
# ...
def describe_for_view
[{:title => "hello", :content => "<script>I.Am.Evil()</script>"}]
end
end
在我看来:
<script>
var describedForView = $.parseJSON("<%= escape_javascript(@foo.describe_for_view.to_json).html_safe %>");
</script>
然后在我的 javascript 中:
$("body").append("title: " + describedForView[0].title + ", content: " + describedForView[0].content);
我当前正在做的是,通过调用 $.sanitize
来包装对用户生成字段的访问,定义如下:
$.sanitize = function(str) {
return $("<div/>").text(str).html();
};
事情是这样的,但我不认为它是干净的。
有什么建议吗?
In an application I am working on, a client-side view is generated based on some records in the database. I am first generating JSON of the records, saving it in a variable in my page, then using JS to build the interface.
The problem is that the records contain user-generated fields, and the application is thus susceptible to XSS. If you let the JSON pass through escape_html
(by not calling html_safe
on it), it will screw up the quotes.
To get to the code. In my model:
Class Foo
# ...
def describe_for_view
[{:title => "hello", :content => "<script>I.Am.Evil()</script>"}]
end
end
Somewhere in my view:
<script>
var describedForView = $.parseJSON("<%= escape_javascript(@foo.describe_for_view.to_json).html_safe %>");
</script>
Then in my javascript:
$("body").append("title: " + describedForView[0].title + ", content: " + describedForView[0].content);
What I am currently doing is that I am wrapping the access to the user-generated fields with a call to $.sanitize
as defined by:
$.sanitize = function(str) {
return $("<div/>").text(str).html();
};
Things work this way, but I don't think it is clean.
Any suggestions?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
Rails 3 有一个内置的 SanitizeHelper,它采用白名单方法。我要么在将用户数据保存到数据库之前调用它,要么在 escape_javascript 调用中调用它:
escape_javascript(sanitize(some_stuff.to_json))
Rails 3 has a built in SanitizeHelper which takes a whitelist approach. I would either call it on user data before persisting it to the database, or in your escape_javascript call:
escape_javascript(sanitize(some_stuff.to_json))