使用Ruby on Rails,我的模型正在使用增加的唯一ID进行创建。例如,第一个用户的用户标识为1,第二个为2,第三个为3.Ruby on Rails安全漏洞,通过id枚举用户枚举
从安全角度来看,这是不好的,因为如果有人可以窥探最后创建的用户的用户标识(可能通过创建一个新用户),他们可以推断出你的增长率。他们也可以轻松猜测用户ID。
有没有好的方法来使用随机ID?
有人为此做了什么?谷歌搜索没有透露任何东西。
使用Ruby on Rails,我的模型正在使用增加的唯一ID进行创建。例如,第一个用户的用户标识为1,第二个为2,第三个为3.Ruby on Rails安全漏洞,通过id枚举用户枚举
从安全角度来看,这是不好的,因为如果有人可以窥探最后创建的用户的用户标识(可能通过创建一个新用户),他们可以推断出你的增长率。他们也可以轻松猜测用户ID。
有没有好的方法来使用随机ID?
有人为此做了什么?谷歌搜索没有透露任何东西。
我不认为公开用户ID是一种安全漏洞,应该有其他安全机制。也许这是一种“营销安全漏洞”当游客发现你没有那个万个用户,他们答应;-)
总之:
为了避免在URL中的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_by_login
更换User.find
:
class UsersController < ApplicationController
def show
@user = User.find_by_login(params[:id])
end
end
或者使用before_filter
之前更换PARAMS。对于其他控制器,嵌套资源使用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
即使您要生成随机的INTEGER ID,它也可能非常容易被破坏。您应该为每个用户(如MD5或SHA1(“asd342gdfg4534dfgdf”))生成一个随机令牌,然后它会对您有所帮助。你应该用这个随机散列链接到用户配置文件。
注意,这实际上并不是散列的概念,它只是一个随机字符串。例如,
另一种方法是链接到用户与他们的昵称。
但是,我的猜测是知道用户ID或用户数或用户增长率本身不是一个漏洞!
添加一个名为random_id
的字段或任何你想要的用户模型。然后创建用户时,将此代码放在您的UsersController:
def create
...
user.random_id = User.generate_random_id
user.save
end
,并把这个代码在用户等级:
# 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
。
为什么不直接将'id'设置为随机数?这样,你不需要改变一件事情。 – Zabba
您需要添加适当的授权层以防止未经授权的访问。
让我们说你,你在Users
控制器show
动作显示用户信息和代码如下所示:
class UsersController < ActionController::Base
before_filter :require_user
def show
@user = User.find(params[:id])
end
end
此实现易受ID猜测。您可以轻松地通过确保节目的行动解决它总是显示登录的用户的信息:
def show
@user = current_user
end
现在不管是什么ID给出的网址,你会显示当前的用户配置文件。
让我们说,我们希望允许帐户管理员和帐户所有者访问演出动作:
def show
@user = current_user.has_role?(:admin) ? User.find(params[:id]) : current_user
end
OTH授权逻辑是利用宝石一样CanCan更好的实现。
我迷路了,为什么这是一个安全漏洞... – John
推断增长率无关安全。 – x1a4
不是一个真正的漏洞,因为它不允许用户以任何方式危害您的应用程序。 Stackoverflow似乎甚至使用增量用户ID。 –