形成隐藏字段和安全性

时间:2016-11-03 13:49:12

标签: ruby-on-rails forms security

我在我的应用中使用隐藏字段将user_id添加到我的数据库" Camping"。我有协会"用户"有许多露营和"露营" belongs_to" user"。

当我运行firebug或类似的东西时,我可以修改此字段的user_id值。如果任何用户输入他的ID,我可以将对象修改为其他用户...我想避免这个!

我的代码

<%= f.hidden_field :user_id, :value => current_user.id %>

这段代码是必要的,因为我只允许用户编辑/更新/创建对象,如果他们有user_id == current_user.id。 如何解决这个安全问题?

顺便说一下,我正在使用设计。

使用完整代码编辑

我的_form.html.erb

    <%= form_for(camping) do |f| %>
      <% if camping.errors.any? %>
        <div id="error_explanation">
          <h2><%= pluralize(camping.errors.count, "error") %> prohibited this camping from being saved:</h2>
          <ul>
          <% camping.errors.full_messages.each do |message| %>
            <li><%= message %></li>
          <% end %>
          </ul>
        </div>
      <% end %>

      <%= f.hidden_field :user_id, :value => current_user.id %>

    <div class="form-group">
       <label for="name">Nom du camping</label>
          <%= f.text_field :name, autofocus: true, class:"form-control", id:"name", :required => true%>
      </div>

  <div class="actions">
    <%= f.submit "Enregistrer", class:"btn btn-success" %>
  </div>
<% end %>

我的控制器

    def new
          @camping = Camping.new
          @campings = Camping.all
        end


        def edit

        end
def create
      @camping = Camping.new(camping_params)
      respond_to do |format|
        if @camping.save
          format.html { redirect_to @camping, notice: 'Camping was successfully created.' }
          format.json { render :show, status: :created, location: @camping }
        else
          format.html { render :new }
          format.json { render json: @camping.errors, status: :unprocessable_entity }
        end
      end
    end

    def update
      @camping = Camping.find(params[:id])
      respond_to do |format|
        if @camping.update(camping_params)
          format.html { redirect_to @camping, notice: 'Camping was successfully updated.' }
          format.json { render :show, status: :ok, location: @camping }
        else
          format.html { render :edit }
          format.json { render json: @camping.errors, status: :unprocessable_entity }
        end
      end
    end

我的edit.html.erb

<div class="containershow">
<h1>Editing Camping</h1>

<%= render 'form', camping: @camping %>

<%= link_to 'Show', @camping %> |
<%= link_to 'Back', campings_path %>
</div>

我的new.html.erb

<h1>New Camping</h1>

<%= render 'form', camping: @camping %>

<%= link_to 'Back', campings_path %>

编辑解决方案?

用户可以创建和更新他的露营。我删除hidden_​​field

 def create
     # @camping = Camping.new(camping_params)

        @camping = Camping.new((camping_params).merge(:user_id => current_user.id))

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

2 个答案:

答案 0 :(得分:1)

在Devise中,当前用户对象位于current_user,可供控制器使用。保存模型时,请确保从该对象填充用户ID字段,而不是在控制器的update操作中填写用户输入。请注意,edit操作无关紧要,只是呈现编辑页面,实际更新发生在update中(如果您遵循默认约定)。当然,如果您不希望用户甚至看到其他用户的对象,那么您还需要在其他控制器操作(如edit)中进行访问控制,但这样做(实现访问控制)多租户Rails应用程序)是一个不同的,更广泛的问题。

更一般地说,请注意,来自请求的任何内容都可以很容易地由用户伪造。始终实现安全服务器端,不信任用户输入!

修改(查看您的代码)

为防止用户更新其他人的Campings,您需要在获取@camping对象(第二行)后检查update是否是您登录的用户(current_user.id)应该使用的驻留对象能够编辑。

同样,如果您想阻止用户为其他用户创建Campings,您需要确保在create中将user_id设置为当前用户,例如@camping.user_id=current_user.id。< / p>

同样,如果您想要防止查看彼此的Campings,您需要将检查添加到editshow以及几乎所有返回此类对象的操作。

像cancan和cancancan这样的宝石可能有助于Rails中的访问控制,值得一看!

答案 1 :(得分:1)

您的问题非常有趣但很简单在任何HTML视图中任何人都可以更改任何内容,这也会导致安全方面的漏洞。

为了避免这些问题,我们需要通过两种方式对其进行身份验证。您必须检查代码,例如它应该由Controller使用而不是通过视图。

假设您正在创建特定用户的任何文章

所以要避免它你可以做什么你可以在Session中设置用户ID并使Helper方法始终找到当前用户

这样您就可以直接从控制器中找到当前用户并根据用户

创建文章
  def Create

   @article = current_user.articles.create(article_params)

  end

这种双向检查可以让你安全起来。

为了避免花在这些工作上,你可以直接使用gem,如Devise