【问题标题】:Devise and security: 3 admin-roles with booleans. Is this 100% secure?设计和安全性:3 个带有布尔值的管理员角色。这是 100% 安全的吗?
【发布时间】:2016-09-02 05:49:57
【问题描述】:

我为基于 Devise 的应用程序定义了 3 个管理员角色。 God_mode、normal_mode 和 guest_mode。它们都是布尔值。但我想知道是否没有办法绕过以某种方式伪造请求并通过“admin god_mode:True”发送普通管理员或访客管理员的请求?通过批量分配或类似方式攻击我的应用程序。

我只是想知道这是否完全不可破解且 100% 安全。

为了示例本身,我已经搭建了应用程序的 CRUD 部分(在现实世界中不会这样做),但参数部分是相同的。设计配置是默认的/开箱即用的。

我基本上有 3 个管理员角色(布尔值)和一个“before_action :authenticate_admin!” + 带有 client_params 和 params.require(:client).permit(:name, :description) 的私有方法 - 我想知道这本身是否足以保护我的网站免受恶意攻击。我们假设我知道如何保护自己的计算机,不被钓鱼等。

我在 Google 上搜索了很多,但不幸的是,仍然会弹出很多 rails 3 文章,并且是基于过时的(?) attr_accessible 和类似的。我知道我们现在使用强参数,但这对我来说似乎太好了,不可能是真的 - 有没有办法破解你的方式来将你的访客管理员角色更改为管理员 God_mode在这个例子中?

客户.rb

class ClientsController < ApplicationController

before_action :set_client, only: [:show, :edit, :update, :destroy]

before_action :authenticate_admin!


# GET /clients
# GET /clients.json
def index
  @clients = Client.all
end

# GET /clients/1
# GET /clients/1.json

def show
end

# GET /clients/new

def new
  @client = Client.new
end

# GET /clients/1/edit

def edit
end

# POST /clients
# POST /clients.json

def create
@client = Client.new(client_params)

respond_to do |format|
  if @client.save
    format.html { redirect_to @client, notice: 'Client was successfully created.' }
    format.json { render :show, status: :created, location: @client }
  else
    format.html { render :new }
    format.json { render json: @client.errors, status: :unprocessable_entity }
  end
  end
  end

# PATCH/PUT /clients/1
# PATCH/PUT /clients/1.json
def update
  respond_to do |format|
    if @client.update(client_params)
      format.html { redirect_to @client, notice: 'Client was successfully updated.' }
    format.json { render :show, status: :ok, location: @client }
  else
    format.html { render :edit }
    format.json { render json: @client.errors, status: :unprocessable_entity }
  end
end
end

# DELETE /clients/1
# DELETE /clients/1.json
def destroy
  @client.destroy
    respond_to do |format|
    format.html { redirect_to clients_url, notice: 'Client was successfully destroyed.' }
    format.json { head :no_content }
  end
end

private
  # Use callbacks to share common setup or constraints between actions.
  def set_client
    @client = Client.find(params[:id])
  end

  # Never trust parameters from the scary internet, only allow the white list through.
  def client_params
    params.require(:client).permit(:name, :description)
  end
  end

schmema:(但管理员应该有一个 default-value=false:

ActiveRecord::Schema.define(version: 20160825190018) do

  create_table "admins", force: :cascade do |t|
    t.string   "email",                  default: "", null: false
    t.string   "encrypted_password",     default: "", null: false
    t.string   "reset_password_token"
    t.datetime "reset_password_sent_at"
    t.datetime "remember_created_at"
    t.integer  "sign_in_count",          default: 0,  null: false
    t.datetime "current_sign_in_at"
    t.datetime "last_sign_in_at"
    t.string   "current_sign_in_ip"
    t.string   "last_sign_in_ip"
    t.boolean  "god_mode"
    t.boolean  "normal_mode"
    t.boolean  "guest_mode"
    t.datetime "created_at",                          null: false
    t.datetime "updated_at",                          null: false
    t.index ["email"], name: "index_admins_on_email", unique: true
    t.index ["reset_password_token"], name: "index_admins_on_reset_password_token", unique: true
  end

  create_table "clients", force: :cascade do |t|
    t.string   "name"
    t.text     "description"
    t.datetime "created_at",  null: false
    t.datetime "updated_at",  null: false
  end

end

【问题讨论】:

  • 没有什么是 100% 防破解的……但就它而言,rails 和 devise 开箱即用就做得很好。只要您不将密码信息放在获取请求中或将密码存储在您的数据库中,您就可以了。总是加密是吗?但是无论如何设计都会自动为您执行此操作,因此您应该没问题。

标签: ruby-on-rails security devise


【解决方案1】:

我会在您的代码中更改几处:

  • 我将存储一个表示该角色的整数,而不是在您的数据库中使用 3 个布尔字段来存储用户的角色。这样,您就可以在需要时添加更多角色。此外,没有什么能阻止您将这些标志中的一个以上设置为 true,从而留下奇怪的配置。

  • 我不会检查用户是否是管理员(这似乎是before_action :authenticate_admin! 的用途),而是检查登录的用户是否有权执行某项任务。在每个操作中,我都会检查登录的用户是否具有创建用户、更新用户等的权限。这些权限将在一个文件中定义,您只需要说明哪些角色可以做什么。查看CanCan(Rails 3)或CanCanCan(Rails > 3)可能会很有用。这样做的原因是,在某些时候您可能希望允许其他角色对您的用户执行某些操作(可能是索引?),您只需修改您的权限文件以允许他们访问您的用户列表。甚至无需触摸控制器。

最后,只想声明,就安全性而言,没有人能保证系统是不可破解的。即使您尽最大努力确保您的服务安全,0 天漏洞、第 3 方 gem 或人为错误(代码错误、错误配置的服务器/路由器……)也可能留下一个足以让攻击者攻击的小漏洞进去吧。

【讨论】:

  • 非常感谢您的回答!真的很感谢帮助!我认为第 1 点很有意义。问题:您有第 1 点和第 2 点的示例吗?该代码的外观如何?这将使我更容易掌握并进一步搜索教程和文档
  • 对于第 2 点,我建议阅读文档,其中充满了示例。对于第 1 点,我将定义一个 Role 类,其中包含将 role_ids 与角色名称相关联的哈希。之后,我将在您的用户模型中定义一个字段,该字段将存储来自该哈希键的值
猜你喜欢
  • 1970-01-01
  • 2012-01-22
  • 1970-01-01
  • 1970-01-01
  • 2010-12-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多