以下表达式在Rails中很常见:
然而,我意识到
查询
@project = Project.find params[:id] # example 1
@project = current_user.projects.find params[:project_id] # example 2
然而,我意识到
find
也接受数组!这意味着使用假设@project
是单个项目而不是数组的代码将产生意外和潜在的危险行为。
现在的问题是:
- 每次在
find
中使用时,我是否应该对params[:id].to_s
进行强制类型转换? - 我是否应该使用强参数来避免数组?
find params.permit(:id)[:id]
)?(如果您不想将nil
转换为""
,则比to_s
更好) - 是否有其他替代方法或常规做法?
上述漏洞似乎只存在于路由没有定义该名称的参数的情况下。
例如:
# SAFE routes.rb
resources :projects
# projects_controller.rb
Project.find params[:id]
查询
/projects/3?id[]=4&id[]=5
只会产生一个参数{id: 3}
。这使得使用Project.find params[:id]
是安全的,但我找不到有关此行为的任何文档,并且我不知道是否可以依赖它:也许这只是偶然发生的。
此外,以下内容根本不等效,并将在控制器中创建漏洞:# Likely UNSAFE routes.rb
# E.g.:
# /projects?id=3 => params = {id: 3}
# /projects?id[]=3&id[]=4 => params = {id: [3, 4]}
put '/projects' => 'projects#update'
find_by(id: params[:id])
。如果find
不能找到给定值,它会导致代码错误,并返回ActiveRecord::RecordNotFound
错误。而find_by
如果找不到任何内容,将返回nil
,在某种意义上我认为这更安全。 - lusketeerfind
并让异常生成404错误是惯用的做法。 - user229044