RubyonRails教程中的SQL插值
这是MH提供的Ruby on Rails教程中的代码:RubyonRails教程中的SQL插值,sql,ruby-on-rails,ruby,database,model-view-controller,Sql,Ruby On Rails,Ruby,Database,Model View Controller,这是MH提供的Ruby on Rails教程中的代码: def feed following_ids = "SELECT followed_id FROM relationships WHERE follower_id = :user_id" Micropost.where("user_id IN (#{following_ids}) OR user_id = :user_id", user_i
def feed
following_ids = "SELECT followed_id FROM relationships
WHERE follower_id = :user_id"
Micropost.where("user_id IN (#{following_ids})
OR user_id = :user_id", user_id: id)
end
这个SQL安全吗?因为很多人告诉我,永远不要使用插值,而是使用转义代码(在本例中是?)。这代码安全吗?是的,这是安全的
事实上,没有插值:整个查询可以写成
Micropost.where("user_id IN (
SELECT followed_id FROM relationships
WHERE follower_id = :user_id)
OR user_id = :user_id", user_id: id)
但是为了清楚起见,第一个查询被提取到它自己的变量中
当插入的字符串来自外部时,必须避免插入。这个字符串是由您在这里构造的,因此不存在SQL注入之类的风险
示例 安全,
id
已确定:
不安全,params[:id]
来自外部,可能很危险:
这是安全的,因为字符串插值本身不是问题。只有在不控制插入到查询中的文本时,才会导致安全漏洞 在您的示例中,插入的\u id后面的字符串
不是未知的用户输入,而是一个固定的SQL子查询。这不会导致安全问题
但我同意这仍然不是一个好的例子,应该进行重构以使用作用域和Rails查询语法
id = 42
"SELECT * FROM users WHERE users.id = #{id}"
"SELECT * FROM users WHERE users.id = #{params[:id]}"