问题描述
我已经阅读了很多关于此的内容,并且知道这里有很多相关问题,但我找不到有关如何对所有内容进行消毒的明确指南.一种选择是对插入进行消毒,例如我的模型中有以下内容
I've read a lot about this and know there are many related questions on here, but I couldn't find a definitive guide for how to go about sanitizing everything. One option is to sanitize on insert, for example I have the following in my model
before_validation :sanitize_content, :on => :create
def sanitize_content
self.content = ActionController::Base.helpers.sanitize(self.content)
end
我是否需要在每个模型的每个字段上运行此程序?我猜 :on => :create 也应该删除,以便在更新时运行?
Do I need to run this on every field in every model? I'm guessing the :on => :create should be removed too so it runs when updates too?
另一个选项是在视图中显示数据时进行清理,使用 simple_format、.html_safe 或 sanitize(fieldname).我是否应该对每个字段以及插入的所有视图进行消毒?必须在任何地方手动执行此操作似乎并不奇怪
The other option is to sanitize when data is displayed in views, using simple_format, or .html_safe or sanitize(fieldname). SHould I be sanitizing in all my views for every single field, as well as on insert? Having to do this manually everywhere doesn't seem very railsy
感谢您的帮助
推荐答案
TL;DR
关于用户输入和查询:确保始终使用活动记录查询方法(例如.where
),并避免使用字符串插值传递参数;将它们作为散列参数值或作为参数化语句传递.
TL;DR
Regarding user input and queries: Make sure to always use the active record query methods (such as .where
), and avoid passing parameters using string interpolation; pass them as hash parameter values, or as parameterized statements.
关于呈现可能不安全的用户生成的 html/javascript 内容:从 Rails 3 开始,html/javascript 文本会自动正确转义,以便在页面上显示为纯文本,而不是而不是解释为 html/javascript,因此您不需要明确清理(或使用 <%= h(potentially_unsafe_user_generated_content)
%>
Regarding rendering potentially unsafe user-generated html / javascript content: As of Rails 3, html/javascript text is automatically properly escaped so that it appears as plain text on the page, rather than interpreted as html/javascript, so you don't need to explicitly sanitize (or use <%= h(potentially_unsafe_user_generated_content)
%>
如果我理解正确,只要您正确使用活动记录查询方法,您就无需担心以这种方式清理数据.例如:
If I understand you correctly, you don't need to worry about sanitizing data in this manner, as long as you use the active record query methods correctly. For example:
假设我们的参数映射看起来像这样,这是恶意用户在 user_name
字段中输入以下字符串的结果:
Lets say our parameter map looks like this, as a result of a malicious user inputting the following string into the 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
的参数值的文字内容放入查询中,而无需清理.您可能知道,恶意用户的输入被视为普通的ol SQL",其危险性非常明显.
Direct string interpolation in this manner will place the literal contents of the parameter value with key :user_name
into the query without sanitization. As you probably know, the malicious user's input is treated as plain 'ol SQL, and the danger is pretty clear.
好方法(这样做):
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 实际上会为您清理它,只要您将参数作为散列或方法参数(取决于您使用的查询方法)传入.
So as you can see, Rails in fact sanitizes it for you, so long as you pass the parameter in as a hash, or method parameter (depending on which query method you're using).
在创建新模型记录时清理数据的情况并不真正适用,因为 new
或 create
方法需要值的散列.即使您尝试将不安全的 SQL 代码注入散列,散列的值也会被视为纯字符串,例如:
The case for sanitization of data on creating new model records doesn't really apply, as the new
or create
methods are expecting a hash of values. Even if you attempt to inject unsafe SQL code into the hash, the values of the hash are treated as plain strings, for example:
User.create(:user_name=>"bobby tables); drop table users;")
查询结果:
INSERT INTO `users` (`user_name`) VALUES ('bobby tables); drop table users;')
所以,和上面的情况一样.
So, same situation as above.
希望有帮助.如果我遗漏或误解了什么,请告诉我.
I hope that helps. Let me know if I've missed or misunderstood anything.
编辑关于转义 html 和 javascript,简短版本是 ERB 为您转义"您的字符串内容,以便将其视为纯文本.如果你真的想要,你可以把它当作 html 处理,方法是执行 your_string_content.html_safe
.
EditRegarding escaping html and javascript, the short version is that ERB "escapes" your string content for you so that it is treated as plain text. You can have it treated like html if you really want, by doing your_string_content.html_safe
.
但是,简单地执行类似 <%= your_string_content %>
的操作是非常安全的.内容被视为页面上的字符串.事实上,如果您使用 Chrome Developer Tools 或 Firebug 检查 DOM,您实际上应该看到该字符串周围的引号.
However, simply doing something like <%= your_string_content %>
is perfectly safe. The content is treated as a string on the page. In fact, if you examine the DOM using Chrome Developer Tools or Firebug, you should in fact see quotes around that string.
这篇关于在 Rails 中清理用户输入的最佳方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!