TL; DR
关于用户输入和查询:确保始终使用活动记录查询方法(如.where
),并避免使用字符串插值传递参数;将它们作为散列参数值或作为参数化语句传递。
关于呈现潜在不安全用户生成html/JavaScript的内容:作为导轨3,HTML/JavaScript的文本被自动正确转义,以便它显示为在网页上的纯文本,而不是解释为HTML/JavaScript,因此您无需显式消毒(或使用<%= h(potentially_unsafe_user_generated_content)
%>
如果我理解正确的话,你不需要担心以这种方式消毒的数据,只要您使用活动记录例如:
比方说,我们的参数图看起来是这样的,因为恶意用户输入下面的字符串到user_name
场的结果:
:user_name => "(select user_name from users limit 1)"
糟糕的方法(不这样做):
Users.where("user_name = #{params[:id}") # string interpolation is bad here
结果查询将如下所示:
SELECT `users`.* FROM `users` WHERE (user_name = (select user_name from users limit 1))
以这种方式直接串插将会把文字内容Ø f将带有键:user_name
的参数值放入查询中而不进行清理。正如您可能知道的那样,恶意用户的输入被视为普通的SQL语句,并且危险非常明显。
的好方法(这样做):
Users.where(id: params[:id]) # hash parameters
OR
Users.where("id = ?", params[:id]) # parameterized statement
结果查询将如下所示:
SELECT `users`.* FROM `users` WHERE user_name = '(select user_name from users limit 1)'
因此,大家可以看到,Rails实际上是为了哟对它进行消毒ü,只要您将参数作为散列或方法参数传递(取决于您使用的是哪种查询方法)。
对于创建新模型记录的数据进行消毒处理的情况并不适用,因为new
或create
方法需要哈希值。即使你试图注入不安全的SQL代码到哈希散列值被视为纯字符串,例如:在查询
User.create(:user_name=>"bobby tables); drop table users;")
结果:
INSERT INTO `users` (`user_name`) VALUES ('bobby tables); drop table users;')
所以,同样的情况如上。
我希望帮助。如果我错过了或误解了任何内容,请告诉我。
编辑 关于逃逸HTML和JavaScript短版本是这样的,它是为纯文本处理ERB“逃逸”为您的字符串内容。你可以它对待像html一样,如果你真的想要,通过做your_string_content.html_safe
。
但是,只是做一些像<%= your_string_content %>
是完全安全的。内容在页面上被视为一个字符串。实际上,如果您使用Chrome开发人员工具或Firebug检查DOM,则实际上应该会看到该字符串的引号。
非常感谢您的快速和彻底的答案 - 非常有帮助!所以我可以基本上允许插入任何东西,只要我使用正确的查询方法,但我仍然需要在视图中的每个用户添加的字段上使用sanitize(field)或simple_format?否则有人不能输入一些JavaScript或HTML,将在我看来这样呈现?似乎有点麻烦,以这种方式手动消毒每个领域 – Dave
也许我对安全卫生与剥离标签之间的混淆,以防止用户格式化他们的内容 – Dave
@Dave噢好吧,作为一个例子,你想确保像''被呈现为纯文本而不是解释为html/javascript?如果是这样,那么你可以安全地将内容插入到页面上。我会为此回答一个快速更新。 –