【问题标题】:How can I secure my use of Devise/CanCan/JavaScript?如何保护我对 Devise/CanCan/JavaScript 的使用?
【发布时间】:2013-02-28 03:04:26
【问题描述】:

我有一个受 Devise/CanCan 保护的控制器,带有 :authenticate_user!load_and_authorize_resource。我必须将:except => [:sort] 添加到那些以使我的sort 操作在javascript 中工作,因为与sort 操作的javascript 连接不包括current_user 或其角色。

我通过使用gon 传递current_user 的角色(如果没有current_user,那么它传递'匿名')来解决这个问题。我不确定这在 JavaScript 端是否安全(也许可以在浏览器的控制台中设置/覆盖该变​​量),并且我确定我的 sort 操作不安全,因为我已将其打开对于直接 POST 访问 - 我通过发送正确的操作参数使用 RESTed 对此进行了测试,这导致数据重新排序。

那么:如何从 JavaScript 启用对受 Devise/CanCan 保护的 Rails 控制器的安全访问?

这是我的 Rails 应用程序的详细信息...

这是(截断的)控制器,显示我如何从 Devise/CanCan 中免除 sort 操作并将 gon.current_user_role 变量设置为 current_user 的角色(如果可用):

class ThingsController < ApplicationController
  before_filter :authenticate_user!, :except => [:sort]
  load_and_authorize_resource :except => [:sort]

  def show
    @thing = Thing.find(params[:id])

    if current_user
      gon.current_user_role = current_user.role
    else
      gon.current_user_role = "anonymous"
    end

    respond_to do |format|
      format.html
    end
  end

  def sort
    params[:thing].each_with_index do |id, index|
      Thing.update_all({position: index+1}, {id: id})
    end
    render nothing: true
  end

end

在我看来,我有一个无序列表的项目,应该由具有“管理员”角色的用户排序:

<ul class="things" data-update-url="<%= sort_things_url %>">
  <% @things.each do |t| %>
    <%= content_tag_for(:li, t) do %>
      <%= image_tag t.image %>
    <% end %>
  <% end %>
</ul>

这是 application.js 文件中的 javascript,如果gon.current_user_role 变量为“admin”,我只会在其中使列表可排序:

$(function() {
  if (gon.current_user_role == "admin")
  {
    $( ".things" ).sortable({
      update: function() {
        return $.post($(this).data('update-url'), $(this).sortable('serialize'));
      }
    });
    $( ".things" ).disableSelection();
  }
});

最后,我的 routes.rb 文件打开了 sort 操作以进行 POST 调用:

  resources :things do
    collection { post :sort }
  end

【问题讨论】:

    标签: javascript ruby-on-rails devise cancan


    【解决方案1】:

    我误认为与排序操作的 JavaScript 连接不包括 current_user 或其角色。我弄错的原因是因为我使用的是Pow,所以我一直在http://railsapp.dev 访问我的Rails 应用程序......但是我的JavaScript 请求被标记为来自127.0.0.1......所以它们是视为 XSS 请求。

    当我使用rails s 启动标准Rails 服务器时,或者当我在登台服务器上进行这些尝试时,JavaScript 知道current_user

    我的控制器最终是这样的:

    class ThingsController < ApplicationController
      before_filter :authenticate_user!
      load_and_authorize_resource
    
      def show
        @thing = Thing.find(params[:id])
    
        if current_user
          gon.current_user_role = current_user.role
        else
          gon.current_user_role = "anonymous"
        end
    
        respond_to do |format|
          format.html
        end
      end
    
      def sort
        params[:thing].each_with_index do |id, index|
          Thing.update_all({position: index+1}, {id: id})
        end
        render nothing: true
      end
    
    end
    

    我的视图和 JavaScript 保持不变。

    此设置不允许对sort 操作进行任意 POST 调用,并且还可以防止没有“管理员”角色的人重新排列项目。如果有人确实弄清楚了如何操作 gon.current_user_role JavaScript 变量,他们将能够明显地重新排列页面上的项目,但该重新排列不会存储在数据库中,因为 sort 操作将禁止该请求(并且它们的更改将在下一页加载时恢复)。

    此设置无法解决我的 Pow 问题,但我可以接受。

    【讨论】:

      猜你喜欢
      • 2012-10-30
      • 2012-08-08
      • 2012-06-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-03-14
      • 1970-01-01
      相关资源
      最近更新 更多