Dav*_*ave 27 sanitization ruby-on-rails-4
我已经阅读了很多关于此的内容,并且知道这里有很多相关的问题,但是我找不到关于如何对一切进行消毒的明确指南.一种选择是对插入进行清理,例如我的模型中有以下内容
before_validation :sanitize_content, :on => :create
def sanitize_content
self.content = ActionController::Base.helpers.sanitize(self.content)
end
Run Code Online (Sandbox Code Playgroud)
我是否需要在每个模型的每个字段上运行它?我猜测:on =>:create也应该删除,以便在更新时运行?
另一种选择是使用simple_format或.html_safe或sanitize(fieldname)在视图中显示数据时进行清理.我应该对每一个领域以及插入的所有观点进行消毒吗?必须在任何地方手动执行此操作似乎并不是很困难
谢谢你的帮助
Pau*_*ter 69
TL; DR
关于用户输入和查询:确保始终使用活动记录查询方法(例如.where),并避免使用字符串插值传递参数; 将它们作为哈希参数值传递,或作为参数化语句传递.
关于渲染可能不安全的用户生成的html/javascript内容:从Rails 3开始,html/javascript文本会自动正确转义,以便在页面上显示为纯文本,而不是解释为html/javascript,因此您不需要明确消毒(或使用<%= h(potentially_unsafe_user_generated_content)%>
如果我理解正确,只要您正确使用活动记录查询方法,就不必担心以这种方式清理数据.例如:
让我们说我们的参数映射看起来像这样,因为恶意用户在user_name字段中输入以下字符串:
:user_name => "(select user_name from users limit 1)"
Run Code Online (Sandbox Code Playgroud)
糟糕的方式(不要这样做):
Users.where("user_name = #{params[:id}") # string interpolation is bad here
Run Code Online (Sandbox Code Playgroud)
生成的查询看起来像:
SELECT `users`.* FROM `users` WHERE (user_name = (select user_name from users limit 1))
Run Code Online (Sandbox Code Playgroud)
以这种方式进行直接字符串插值会将带有键的参数值的文字内容:user_name放入查询中而不进行清理.您可能知道,恶意用户的输入被视为普通的SQL,危险非常明显.
好方法(这样做):
Users.where(id: params[:id]) # hash parameters
Run Code Online (Sandbox Code Playgroud)
要么
Users.where("id = ?", params[:id]) # parameterized statement
Run Code Online (Sandbox Code Playgroud)
生成的查询看起来像:
SELECT `users`.* FROM `users` WHERE user_name = '(select user_name from users limit 1)'
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,Rails实际上为您清理它,只要您将参数作为哈希或方法参数传递(取决于您使用的查询方法).
关于创建新模型记录的数据的清理的情况并不真正适用,因为new或者create方法期望值的散列.即使您尝试将不安全的SQL代码注入到散列中,散列的值也会被视为纯字符串,例如:
User.create(:user_name=>"bobby tables); drop table users;")
Run Code Online (Sandbox Code Playgroud)
结果在查询中:
INSERT INTO `users` (`user_name`) VALUES ('bobby tables); drop table users;')
Run Code Online (Sandbox Code Playgroud)
所以,和上面的情况一样.
我希望有所帮助.如果我错过或误解了任何事情,请告诉我.
编辑
关于转义html和javascript,简短版本是ERB为您"转义"您的字符串内容,以便将其视为纯文本.如果你真的想要的话,你可以把它当作html来对待your_string_content.html_safe.
但是,简单地做一些事情<%= your_string_content %>是非常安全的.内容在页面上被视为字符串.事实上,如果您使用Chrome开发者工具或Firebug检查DOM,您实际上应该看到该字符串周围的引号.
Bry*_*mas 11
因为当我在任何SO答案中找到知识和代码的来源时,我总是很感激,我会为这个问题提供.
ActiveRecord和ActionController都提供了清理sql输入的方法.
具体来说,ActiveRecord::Sanitization::ClassMethods你有sanitize_sql_for_conditions和它的另外两个别名:
sanitize_conditions和sanitize_sql.三者确实完全相同.
sanitize_sql_for_conditions
接受SQL条件的数组,散列或字符串,并将它们清理为WHERE子句的有效SQL片段.
但是,在ActiveRecord中你也有
sanitize_sql_for_assignment 哪一个
接受SQL条件的数组,散列或字符串,并将它们清理为SET子句的有效SQL片段.
另一方面,在ActionController中,您可以使用ActionController::Parameters它
选择哪些属性应该列入白名单以进行批量更新,从而防止意外暴露不应暴露的属性.为此提供两种方法:require和permit.
params = ActionController::Parameters.new(user: { name: 'Bryan', age: 21 })
req = params.require(:user) # will throw exception if user not present
opt = params.permit(:name) # name parameter is optional, returns nil if not present
user = params.require(:user).permit(:name, :age) # user hash is required while `name` and `age` keys are optional
Run Code Online (Sandbox Code Playgroud)
我希望这有助于任何人,如果只是为了学习和揭开Rails的神秘面纱!:)
| 归档时间: |
|
| 查看次数: |
27714 次 |
| 最近记录: |