before_validation :sanitize_content,:on => :create def sanitize_content self.content = ActionController::Base.helpers.sanitize(self.content) end
我需要在每个模型的每个领域运行这个吗?我猜:on => :创建应该被删除,所以它运行时的更新呢?
另一个选项是使用simple_format或.html_safe或者清理(字段名)在视图中显示数据时进行清理.我应该在每一个领域的所有观点,以及插入?手工无处不在,看起来不是很有道理
感谢任何帮助
解决方法
关于用户输入和查询:确保始终使用活动记录查询方法(如.where),并避免使用字符串插值传递参数;将它们作为哈希参数值或参数化语句传递.
关于渲染可能不安全的用户生成的html / javascript内容:从Rails 3开始,html / javascript文本被自动正确地转义,使其在页面上显示为纯文本,而不是解释为html / javascript,因此您不需要(或使用<%= h(potential_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))
以这种方式进行直接字符串插入将将带有key:user_name的参数值的文字内容放入查询中,无需进行清理.您可能知道,恶意用户的输入被视为纯粹的sql,危险性非常明显.
好办法(做这个):
Users.where(id: params[:id]) # hash parameters
要么
Users.where("id = ?",params[:id]) # parameterized statement
SELECT `users`.* FROM `users` WHERE user_name = '(select user_name from users limit 1)'
所以,您可以看到,Rails实际上是为您清理,只要您将参数作为散列或方法参数传递(取决于您使用的查询方法).
用于清理创建新模型记录的数据的情况并不适用,因为新的或创建方法期望值的哈希值.即使您尝试将不安全的sql代码注入散列,散列值也将被视为纯字符串,例如:
User.create(:user_name=>"bobby tables); drop table users;")
查询结果:
INSERT INTO `users` (`user_name`) VALUES ('bobby tables); drop table users;')
所以,同样的情况如上.
我希望有帮助.让我知道我是否错过或误解了什么.
编辑
关于转义html和javascript,简短版本是ERB“转义”您的字符串内容,以便它被视为纯文本.您可以通过执行your_string_content.html_safe将其视为html,如果您真的想要的话.
但是,只要简单的做一些<%= your_string_content%>是完全安全的内容被视为页面上的字符串.事实上,如果您使用Chrome Developer Tools或Firebug检查DOM,您实际上应该看到该字符串的引号.