首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >表单隐藏字段和安全性

表单隐藏字段和安全性
EN

Stack Overflow用户
提问于 2016-11-03 21:49:12
回答 2查看 811关注 0票数 1

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

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

我的代码

代码语言:javascript
复制
<%= f.hidden_field :user_id, :value => current_user.id %>

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

顺便说一下,我使用的是devise。

使用完整代码进行编辑

我的_form.html.erb

代码语言:javascript
复制
    <%= 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 %>

我的控制器

代码语言:javascript
复制
    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

代码语言:javascript
复制
<div class="containershow">
<h1>Editing Camping</h1>

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

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

我的new.html.erb

代码语言:javascript
复制
<h1>New Camping</h1>

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

<%= link_to 'Back', campings_path %>

是否编辑解决方案?

用户可以创建和更新他的露营。我删除了hidden_field

代码语言:javascript
复制
 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
EN

回答 2

Stack Overflow用户

发布于 2016-11-03 21:55:59

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

更广泛地说,请注意,来自请求的任何内容都很容易被用户伪造。始终实现安全的服务器端,不要相信用户的输入!

编辑(查看您的代码)

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

同样,如果您希望防止用户为其他用户创建宿营,则需要确保在create中将user_id设置为当前用户,如@camping.user_id=current_user.id

类似地,如果您想防止查看彼此的宿营地,则需要向editshow以及几乎所有返回此类对象的操作添加检查。

有像cancan和cancancan这样的gem可以帮助Rails中的访问控制,它们值得一看!

票数 1
EN

Stack Overflow用户

发布于 2016-11-03 22:11:31

你的问题很有趣,但很简单,在任何HTML视图中,任何人都可以更改任何东西,这也会导致安全漏洞。

为了避免这些问题,我们需要通过两种方式对它进行身份验证,你必须检查代码,就像它应该由Controller而不是view使用一样。

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

因此,为了避免这种情况,您可以在会话中设置用户ID,并创建一个Helper方法来始终查找当前用户

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

代码语言:javascript
复制
  def Create

   @article = current_user.articles.create(article_params)

  end

这种双向检查你可以设置,这样它将是安全的。

为了避免在这些工作上花费时间,你可以像Devise一样直接使用gem。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40403228

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档