0

使用 Ruby on Rails,我的模型创建的唯一 ID 越来越多。例如,第一个用户的用户 id 为 1,第二个为 2,第三个为 3。

从安全角度来看,这并不好,因为如果有人可以窥探最后创建用户的用户 ID(可能通过创建新用户),他们可以推断出您的增长率。他们还可以轻松猜测用户 ID。

有没有使用随机 ID 的好方法?

人们对此做了什么?谷歌搜索并没有透露太多信息。

4

4 回答 4

1

我不认为将用户 ID 公开为安全漏洞,应该有其他安全机制。当访问者发现您没有他们承诺的那百万用户时,也许这是一个“营销安全漏洞”;-)

反正:

为了完全避免 url 中的 ID,您可以在所有地方使用用户的登录名。确保登录名不包含一些特殊字符(./\#?等),这些字符会导致路由出现问题(使用白名单正则表达式)。此外,登录名以后可能不会更改,如果您的页面有硬链接/搜索引擎条目,这可能会导致麻烦。

示例调用是/users/Jeffand/users/Jeff/edit而不是/users/522047and /users/522047/edit

在您的用户类中,您需要覆盖to_param以使用登录名而不是用户的 id。这样就不需要替换路由文件中的任何内容,也不需要替换link_to @user.

class User < ActiveRecord::Base
  def to_param
    self.login
  end
end

然后在每个控制器中替换User.findUser.find_by_login

class UsersController < ApplicationController

  def show 
     @user = User.find_by_login(params[:id])
  end

end

或者使用 abefore_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
于 2012-06-21T07:13:36.743 回答
0

即使您会生成随机 INTEGER id,它也可以很容易地被破坏。您应该为每个用户生成一个随机令牌,例如 MD5 或 SHA1(“asd342gdfg4534dfgdf”),然后它会对您有所帮助。您应该使用此随机哈希链接到用户配置文件。

请注意,这实际上不是哈希概念,它只是一个随机字符串。

例如,另一种方法是用他们的昵称链接到用户。

但是,我的猜测是知道用户 ID 或用户数或用户增长率本身并不是漏洞!

于 2012-06-21T04:19:24.617 回答
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

于 2012-06-21T05:30:22.207 回答
0

您需要添加适当的授权层以防止未经授权的访问。

假设您show在控制器的操作中显示用户信息,Users代码如下所示:

class UsersController < ActionController::Base

  before_filter :require_user

  def show
    @user = User.find(params[:id])
  end

end  

此实现容易受到 id 猜测的影响。您可以通过确保显示操作始终显示登录用户的信息来轻松修复它:

def show
  @user = current_user
end

现在,无论 URL 中给出什么 id,您都将显示当前用户配置文件。

假设我们要允许帐户管理员和帐户所有者访问显示操作:

def show
  @user = current_user.has_role?(:admin) ? User.find(params[:id]) : current_user
end

使用像CanCan这样的 gem 可以更好地实现 OTH 授权逻辑。

于 2012-06-21T06:08:06.557 回答