ruby-on-rails-4 - 在 Rails 中清理用户输入的最佳方法

标签 ruby-on-rails-4 sanitization

我已经阅读了很多关于此的内容,并且知道这里有很多相关的问题,但是我找不到有关如何对所有内容进行 sanitizer 的权威指南。一种选择是在插入时进行 sanitizer ,例如我的模型中有以下内容

before_validation :sanitize_content, :on => :create
def sanitize_content
  self.content = ActionController::Base.helpers.sanitize(self.content)
end

我需要在每个模型的每个字段上运行它吗?我猜 :on => :create 也应该被删除,以便它在更新时也运行?

另一个选项是在 View 中显示数据时进行清理,使用 simple_format、.html_safe 或 sanitize(fieldname)。我应该对每个字段以及插入时的所有 View 进行 sanitizer 吗?必须在任何地方手动执行此操作似乎不是很麻烦

谢谢你的帮助

最佳答案

TL;DR
关于用户输入和查询:确保始终使用事件记录查询方法(例如 .where ),并避免使用字符串插值传递参数;将它们作为散列参数值或参数化语句传递。

关于呈现可能不安全的用户生成的 html/javascript 内容:从 Rails 3 开始,html/javascript 文本会自动正确转义,使其在页面上显示为纯文本,而不是解释为 html/javascript,因此您不需要显式清理(或使用 <%= h(potentially_unsafe_user_generated_content) %>

如果我对您的理解正确,您无需担心以这种方式清理数据,只要您正确使用事件记录查询方法即可。例如:

假设我们的参数映射看起来像这样,因为恶意用户将以下字符串输入到 user_name field :

: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))

以这种方式直接进行字符串插值会将参数值的文字内容与键 :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 实际上会为您清理它,只要您将参数作为散列或方法参数传递(取决于您使用的查询方法)。

在创建新模型记录时对数据进行清理的情况并不真正适用,因为 newcreate方法需要一个哈希值。即使您尝试将不安全的 SQL 代码注入(inject)散列,散列的值也会被视为纯字符串,例如:
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,您实际上应该看到该字符串周围的引号。

关于ruby-on-rails-4 - 在 Rails 中清理用户输入的最佳方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21886170/

相关文章:

ruby - 如何在 Fabrication 中对属性进行分组,就像在 Factory_Girl 中使用特征一样

sql-server - SQL Server 中的 SQL 注入(inject)如何击败转义单引号的卫生措施?

javascript - 如何通过覆盖 odoo.define 中的函数来禁用 Odoo JavaScript 清理

.net - 在 .NET 的动态 SQL 中清理表/列名? (防止SQL注入(inject)攻击)

c# - 如何加载未净化的 XML?

ruby-on-rails - 未知属性 - 属性存在

ruby-on-rails - Ruby on Rails 将通配符子域路由到 Controller /操作

Rails 中的 HTML,对齐来自不同文件的链接和后退按钮

php - 如何在不使用 PDO 的情况下改进 PHP 清理

ruby-on-rails-4 - Rails 对 CORS 预检选项请求响应 404