Ruby on rails 第8条防止注射
我正在构建一个webform,我想用外部oracle数据库中的数据预填充它。我们正在使用rails OCI8插件 我希望通过直接在查询中使用URL参数来确保自己不会被注入 例如,在控制器中:Ruby on rails 第8条防止注射,ruby-on-rails,ruby-on-rails-3,oracle,sql-injection,oci8,Ruby On Rails,Ruby On Rails 3,Oracle,Sql Injection,Oci8,我正在构建一个webform,我想用外部oracle数据库中的数据预填充它。我们正在使用rails OCI8插件 我希望通过直接在查询中使用URL参数来确保自己不会被注入 例如,在控制器中: def new if params[:provider] && u = findByUserName(params[:provider]) monkey = { :employeeEmail => u['EMAIL_ADDRESS']
def new
if params[:provider] && u = findByUserName(params[:provider])
monkey = {
:employeeEmail => u['EMAIL_ADDRESS'],
:employeeFirst => u['FIRST_NAME'],
:employeeLast => u['LAST_NAME'],
:userID => u['LOGIN_ID'],
:supervisorUserID => u['SUPERVISOR_ID'],
:supervisorName => u['SUPERVISOR_NAME'],
:supervisorEmail => u['SUPERVISOR_EMAIL']
}
@service = Service.new(monkey)
else
@service = Service.new
end
end
如您所见,参数[:provider]直接传递给OCI8查询:
def findByUserName(id)
if id
cursor = cursor_exec("SELECT DISTINCT
<QUERY INFO HERE>
AND external_user = :id
ORDER BY last_name, first_name", id)
collection = cursor.fetch_hash()
cursor.close
logoff
collection
end
end
OCI8是否会通过绑定正确清理参数,或者是否有更安全的方法?由于您正在内部调用
OCI8#exec()
,传递给它的第二个参数将作为参数绑定到查询,您不必担心额外的转义。应该通过调用exec()
对其进行内部保护
exec(sql,*bindvars)
执行sql语句。返回值的类型取决于sql语句的类型:select;插入、更新和删除;创建、更改和删除;和PL/SQL
当指定BindVar时,它们在执行之前被绑定为绑定变量
由于您正在内部调用
OCI8#exec()
,因此传递给它的第二个参数将作为参数绑定到查询,您不必担心额外的转义。应该通过调用exec()
对其进行内部保护
exec(sql,*bindvars)
执行sql语句。返回值的类型取决于sql语句的类型:select;插入、更新和删除;创建、更改和删除;和PL/SQL
当指定BindVar时,它们在执行之前被绑定为绑定变量
我在
cursor\u exec()
(我可以找到cursor.exec()
)上找不到文档,但如果它实际上是在创建一个看起来像是准备好的语句,那么它就不易受攻击。@Michael是的,cursor\u exec是在文件的开头定义的,并使用.exec像这样构建查询cursor=@conn.exec(query,params)
那么您的cursor\u exec()
函数实际上是在输入参数上调用bind\u param()
,还是只是对它们进行一些字符串替换?@Michael我编辑了这个问题,向您展示cursor\u exec函数。其定义的原因是我们有多个查询用于不同的用途。其中有些有参数,有些没有参数,这是我们可以使用一个连接而不必为每个实例重新定义它的一种方法。请参见下面--您应该可以。我在cursor\u exec()
(我可以找到cursor.exec()
)上找不到文档,但如果它实际上是在创建一个看起来准备好的语句,那么这就没有漏洞了。@Michael是的,cursor\u exec是在我们的文件开头定义的,并使用.exec像这样构建查询cursor=@conn.exec(query,params)
所以你的cursor\u exec()
函数实际上调用了bind\u param()
在输入参数上,还是只对其执行一些字符串替换?@Michael我已经编辑了这个问题,向您展示了cursor\u exec函数。其定义的原因是我们有多个查询用于不同的用途。其中有些有参数,有些没有参数,这是一种方法,我们可以使用一个连接,而不必为每个实例重新定义它。请参见下文——您应该可以。那么绑定变量不支持的表名和其他标识符呢?@Alexander如果您使用的是动态表名或标识符名,在将它们传递到SQL之前,应该根据可接受的可能值列表对它们进行验证(因为表和列等总是事先知道的)。为标识符创建一个可能值的数组,然后检查您的输入值是否在该数组中。这实际上是我正在做的,但我宁愿加入剥离逻辑作为额外的故障保护,以防止将来在表名数组中错误编辑表名,以及绑定变量不支持的其他标识符?@Alexander如果您使用的是动态表或标识符名称,则应在将其传递到SQL之前,根据可接受的可能值列表对其进行验证(因为表和列等总是事先知道的)。为标识符创建一个可能值的数组,然后检查您的输入值是否在该数组中。这实际上就是我正在做的,但我宁愿将剥离逻辑作为一个额外的故障保护,以防将来在表名数组中进行错误编辑
def cursor_exec(sql, *params)
@conn = OCI8.new('user','pass','server')
if params.length > 0
cursor = @conn.exec(sql, *params)
else
cursor = @conn.exec(sql)
end
end