我遇到了这个示例,在该示例中,不使用绑定参数,而是将键值对传递给heredoc。我知道这将允许用户以任何顺序输入输入,但是我的问题是,如果我使用键值对而不是绑定参数,是否仍然可以防止SQL注入攻击?如果没有,是否有一种方法可以允许用户在没有任何特定顺序的情况下传递输入,同时还能防止注入攻击?
这里是使用键值对的示例:
def self.find_by_id(id)
found_user = QuestionDatabase.instance.execute(<<-SQL, id: id)
SELECT
users.*
FROM
users
WHERE
users.id = :id
SQL
found_user.nil? ? nil : User.new(found_user)
end
这里是使用绑定参数的示例:
def self.find_by_id(id)
found_user = QuestionDatabase.instance.execute(<<-SQL, id)
SELECT
users.*
FROM
users
WHERE
users.id = ?
SQL
found_user.nil? ? nil : User.new(found_user)
end
据我所知,没有将参数传递给heredoc的语法。您所显示的实际上只是将哈希作为参数传递给execute()
。
Ruby允许参数为标量或数组或哈希。
require 'pp'
def execute(sql, binds)
pp binds
end
id = 123
execute('blah blah blah', id: id)
execute('blah blah blah', id)
输出:
{:id=>123}
123
实际上并没有将id
与字符串组合,只是将其作为参数传递给execute()
函数。第一次,它传递了哈希,因此您获得了关联的键值对。第二次,它只是通过了一个标量。
大概是真正的Rails execute()
方法具有一些代码来检查传递的参数是标量还是散列,然后从SQL字符串中解析命名的参数占位符,并且如果使用的RDBMS不支持命名参数,它将替换为?
占位符。
无论哪种方式,对于SQL注入都是安全的。