使用Ruby on Rails,我的模型正在创建,增加了独特的ID。例如,第一个用户的用户ID为1,第二个用户ID为3,
从安全角度来看,这并不好,因为如果有人可以窥探最后创建的用户的用户ID(可能是通过创建新用户),他们可以推断出您的增长率。他们也可以轻松猜出用户ID。
是否有一种使用随机ID的好方法?
人们对此做了什么?谷歌搜索没有透露任何内容。
答案 0 :(得分:1)
我不认为将用户ID公开为公开作为安全漏洞,应该有其他安全机制。当访问者发现你没有他们承诺的那百万用户时,也许这是一个“营销安全漏洞”; - )
反正:
要完全避免网址中的ID,您可以在所有位置使用用户的登录信息。确保登录不包含某些特殊字符(./\#?
等),这会导致路由出现问题(使用白名单正则表达式)。此外,以后可能不会更改登录名,如果您的网页上有硬链接/搜索引擎条目,则可能会造成麻烦。
示例调用是/users/Jeff
和/users/Jeff/edit
,而不是/users/522047
和/users/522047/edit
。
在您的用户类中,您需要覆盖to_param
以使用路由登录而不是用户的ID。这样就不需要替换路由文件中的任何内容,也不需要替换link_to @user
等帮助程序。
class User < ActiveRecord::Base
def to_param
self.login
end
end
然后在每个控制器中将User.find
替换为User.find_by_login
:
class UsersController < ApplicationController
def show
@user = User.find_by_login(params[:id])
end
end
或者之前使用before_filter
替换参数。对于具有嵌套资源的其他控制器,请使用params[:user_id]
:
class UsersController < ApplicationController
before_filter :get_id_from_login
def show
@user = User.find(params[:id])
end
private
# As users are not called by +id+ but by +login+ here is a function
# that converts a params[:id] containing an alphanumeric login to a
# params[:id] with a numeric id
def get_id_from_login
user = User.find_by_login(params[:id])
params[:id] = user.id unless user.nil?
end
end
答案 1 :(得分:0)
即使你会生成随机的INTEGER id,它也可以很容易地被攻陷。您应该为每个用户生成一个随机令牌,如MD5或SHA1(&#34; asd342gdfg4534dfgdf&#34;),然后它会对您有所帮助。您应该使用此随机哈希链接到用户个人资料。
注意,这实际上不是哈希概念,它只是一个随机字符串。
另一种方法是用他们的昵称链接到用户,例如。
但是,我的猜测是知道用户ID或用户数量或用户增长率本身不是漏洞!
答案 2 :(得分:0)
向用户模型添加名为random_id
的字段或任何您想要的字段。然后在创建用户时,将此代码放在UsersController中:
def create
...
user.random_id = User.generate_random_id
user.save
end
并将此代码放在User类中:
# random_id will contain capital letters and numbers only
def self.generate_random_id(size = 8)
alphanumerics = ('0'..'9').to_a + ('A'..'Z').to_a
key = (0..size).map {alphanumerics[Kernel.rand(36)]}.join
# if random_id exists in database, regenerate key
key = generate_random_id(size) if User.find_by_random_id(key)
# output the key
return key
end
如果您也需要小写字母,请将它们添加到字母数字中,并确保从内核中获取正确的随机数,即Kernel.rand(62)
。
另外,请务必修改您的路线和其他控制器,以使用random_id
代替默认id
。
答案 3 :(得分:0)
您需要添加适当的授权层以防止未经授权的访问。
我们假设您在show
控制器的Users
操作中显示用户信息,代码如下所示:
class UsersController < ActionController::Base
before_filter :require_user
def show
@user = User.find(params[:id])
end
end
此实现容易受到id猜测。您可以通过确保show action始终显示登录用户的信息来轻松修复它:
def show
@user = current_user
end
现在,无论URL中给出了什么ID,您都会显示当前的用户个人资料。
我们假设我们希望允许帐户管理员和帐户所有者访问show操作:
def show
@user = current_user.has_role?(:admin) ? User.find(params[:id]) : current_user
end
使用像CanCan这样的宝石可以更好地实现OTH授权逻辑。