简体   繁体   中英

Brakeman - Ruby on Rails - Remote Code Execution (Security Warning) on 'RatyRate' gem controller

In my RoR app, I've installed the 'RatyRate' gem in order for a Users to rate one another using a 5-star system.

However, upon installing and running the 'Brakeman' security scanner gem in my app's root directory, I receive this somewhat-alarming message:

+SECURITY WARNINGS+
+------------+-----------------+--------+-----------------------+------------->>
| Confidence | Class           | Method | Warning Type          | Message     >>
+------------+-----------------+--------+-----------------------+------------->>
| High       | RaterController | create | Remote Code Execution | Unsafe reflection method constantize called with parameter value near line 5: +params[:klass].classify+.constantize.find(params:[id])>>
+------------+-----------------+--------+-----------------------+------------->>

Along with these "Medium" errors being reported: View Warnings:

+------------+-----------------------------------------+-->>
| Confidence | Template    | Warning Type     | Message   >>
+------------+-----------------------------------------+-->>
| Medium     | listings/edit (ListingsController#edit) | Cross Site Scripting | Unsafe parameter value in link_to href near line 31: link_to("Delete", current_user.listings.fin>>
| Medium     | listings/show (ListingsController#show) | Cross Site Scripting | Unsafe parameter value in link_to href near line 11: link_to(current_user.listings.find_by(:id =>>
+------------+-----------------------------------------+-->>

Are these errors something I should be concerned with and fix somehow, or are they most likely false positives that can be ignored..?

-My listings/edit view is shown below:

<% provide(:title, 'Edit listing') %>
<h1>Editing Listing</h1>

<div class="row">
  <div class="col-md-6 col-md-offset-3">
    <div class="center">
    <div class="panel panel-white">
      <div class="panel-heading">
        <div class="panel-title">
        </div>
      </div>
      <div class="panel-body">
        <h4>
          <%= form_for(@listing) do |f| %>
            <%= render 'shared/listing_error_messages' %>

            <%= f.label :name %>
            <%= f.text_field :name, class: "form-control" %>

            <%= f.label :description %>
            <%= f.text_area :description, class: "form-control" %>

            <%= f.label :price %>
            <%= f.text_field :price, class: "form-control" %>

            <%= f.submit "Edit listing", class: "btn btn-warning" %>
          <% end %>
          <%= link_to "Back", listings_path, class: "btn btn-link" %>
        </h4>
        <h4>
          <%= link_to "Delete", @listing, method: :delete, class: "btn btn-danger",
                                     data: { confirm: "You sure?" } %>
        </h4>
      </div>
    </div>
    </div>
  </div>
</div>

-And here's the listings/show view:

<div class="col-md-8">
  <div class="panel panel-default">
    <div class="panel-heading">
      <h3 class="panel-title"><%= @listing.name %></h3>
    </div>
    <div class="panel-body">

      <p>
        <strong>Category:</strong>
        <% if @listing.category %>
          <%= link_to @listing.category.name, @listing.category %>
        <% else %>
          none
        <% end %>
      </p>

      <p>
        <strong>Description:</strong>
        <%= @listing.description %>
      </p>

      <p>
        <strong>Price:</strong>
        <%= number_to_currency(@listing.price) %>
      </p>

      <p>
        <strong>Image:</strong>
        <%= image_tag @listing.image_url if @listing.image? %>
      </p>

    </div>
    <div class="panel-footer"><%= link_to 'Edit', edit_listing_path(@listing) %> |
      <%= link_to 'Back', listings_path %></div>
  </div>
</div>

-the Rater Controller:

class RaterController < ApplicationController

  def create
    if user_signed_in?
      obj = params[:klass].classify.constantize.find(params[:id])
      obj.rate params[:score].to_f, current_user, params[:dimension]

      render :json => true
    else
      render :json => false
    end
  end
end

-the Listing Controller:

class ListingsController < ApplicationController
  before_action :logged_in_user, only: [:create, :destroy]
  before_action :correct_user,   except: [:create, :index, :new]

  def index
    @listings = Listing.all
  end

  def show
  end

  def new
    @listing = Listing.new
  end

  def edit
  end

  def create
    @listing = Listing.new(listing_params)
    @listing.user = current_user
    @listing.username = current_user.username
    if @listing.save
      redirect_to @listing
      flash[:success] = "Listing was successfully created."
    else
      render 'new'
    end
  end

  def update
    if @listing.update(listing_params)
      flash[:success] = "Listing was successfully updated."
      redirect_to @listing
    else
      render 'edit'
    end
  end

  def destroy
    @listing.destroy
    flash[:success] = "Listing deleted."
    redirect_to request.referrer || root_url
  end

  private

    def listing_params
      params.require(:listing).permit(:name, :description, :price, :image, :category_id)
    end

    def correct_user
      @listing = current_user.listings.find_by(id: params[:id])
      redirect_to root_url if @listing.nil?
    end
end

Yes! Don't do this:

obj = params[:klass].classify.constantize.find(params[:id])

That would allow any user to send a url param and have .find(id) executed on the class with that name! This means they can take data from any model!

The other two errors may be false positives. See this github issue for more info on those: https://github.com/presidentbeef/brakeman/issues/311

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM