web-dev-qa-db-ja.com

Rails許可されていないパラメーターをハッシュに変換できません

私は、webappに簡単な検索と並べ替えを実装しようとしています。 railscast とこの railscast をフォローしています。

リンクとして使用しているソート可能な関数のアプリケーションヘルパーは次のとおりです。

def sortable(column, title = nil)
      title ||= column.titleize
      css_class = column == sort_column ? "current #{sort_direction}" : nil
      direction = column == sort_column && sort_direction == "asc" ? "desc" : "asc"
      link_to title, params.merge(:sort => column, :direction => direction, :page => nil), {:class => css_class}
    end

ビューでこれらを使用しています。コントローラーでは、次のようにホワイトリストを使用しています。

 @listingssearch.where(:vehicletype => 'Car').order(sort_column + " " + sort_direction).paginate(:page => params[:page], :per_page => 30)

サニタイズのプライベートメソッド:

 private
     def sort_column
          Listing.column_names.include?(params) ? params[:sort] : "rateperhour"
        end

        def sort_direction
          %w[asc desc].include?(params[:direction]) ? params[:direction] : "asc"
        end

私はプライベートメソッドでマージを使用してみました:

(Listing.column_names + params) but its not working 

ヘルパーメソッドの場合検索パラメーターを提供しようとするとエラーが発生します並べ替えリンクに:許可されていないパラメーターをハッシュに変換できません

エラーがマージ用であることを示しています

link_to title, params.merge(:sort => column, :direction => direction, :page => nil), {:class => css_class}

他の方法はうまくいきます:

<%= bootstrap_form_for listings_path, :method => 'get' do %>

        <%= hidden_field_tag :direction, :value => params[:direction] %>
        <%= hidden_field_tag :sort,:value => params[:sort] %>



        <div class= "col-sm-12 col-lg-12 col-md-12" style = "margin: auto;">
            <h6 style = "color:#7C064D;"><strong> PICK A DATE  <span class="glyphicon glyphicon-calendar"></span></strong>
            <%= date_field_tag :startdate, params[:startdate], placeholder: 'DATE' %>           
            </h6>
        </div>  

        <div class= "col-sm-12 col-lg-12 col-md-12" style = "margin: auto;">    
        <p>     
            <%= text_field_tag :near, params[:near], placeholder: ' Destination' %>
            <%= text_field_tag :radius, params[:radius], placeholder: ' Search Radius' %>
        </p>
        </div>      
        <div class= "col-sm-12 col-lg-12 col-md-12" style = "margin: auto;">    
        <p>     
            <%= text_field_tag :min, params[:min], placeholder: ' Minimum Rate Per Hour' %>
            <%= text_field_tag :max, params[:max], placeholder: ' Maximum Rate Per Hour' %>
        </p>
        </div>

        <div class= "col-sm-12 col-lg-12 col-md-12" style = "margin-top: 10px;">        
            <%= submit_tag "Search", class: "btn btn-info", style: "width: 40%; background-color: #E20049; border: #e20049;" %>
            <%= link_to 'View All', root_path, class: "btn btn-info", style: "width: 40%; background-color: #E20049; border: #e20049;" %>
        </div>

        <!-- <div class= "col-sm-6 col-lg-6 col-md-6" style = "margin-top: 10px;">      

        </div> -->


    <% end %>

私の質問は、Rails 5?何が間違っていますか?のソートヘルパーメソッドで検索パラメータを保持する方法です。

25
Saurav Prakash

Rails 5、ActionController::ParametersHashを継承しなくなりました。明示的にフィルタリングせずに、リクエストパラメータでHash関連のメソッドを使用しないようにしようとしています。

このプルリクエスト の一部として、Rails 5.1にバックポートされ、部分的にRails 5.0にバックポートされました。 permitを呼び出さずに、パラメータオブジェクトでto_hを呼び出そうとします。

元のmergeオブジェクト(params.merge(:sort => column, :direction => direction, :page => nil))でparamsを呼び出すと、同じpermittedステータスを持つ新しいActionController::Parametersオブジェクトが返されます(つまり、permitはそれに呼ばれます)。 link_toメソッドは、そのオブジェクトでto_hを呼び出すことになり、例外が発生します。

リンクで許可されるパラメーターがわかっている場合は、リストされているパラメーターでpermitを呼び出すことができます。

params.permit(:param_1, :param_2).merge(:sort => column, :direction => direction, :page => nil)
# OR
params.merge(:sort => column, :direction => direction, :page => nil).permit(:param_1, :param_2, :sort, :direction, :page)

リンクに含めることができるパラメーターがわからない場合は、request.parameters.merge(...)this answer で述べたように)またはparams.to_unsafe_h.merge(...)を使用できます。これらはどちらも、リンクを作成するときに基本的に強力なパラメーター保護を回避します。デフォルトでは、元のリクエストに含まれていたパラメーターはすべてリンクURLにも表示されます。この特定の状況ではそれほど危険ではないと思いますが、パラメーターを適切にサニタイズしないコードが他にある場合、これはその状況を少し悪化させる可能性があります。

53
Max

このハックを使用できます:

params.to_enum.to_h

Rails開発者は、許可されていないパラメーターを使用する方法だとわかったときに、それを制限します。:)

9
Ghazi

request.parameters.mergeの使用を試みることができます。以下は上記のコードのサンプルです

<%= link_to title, listings_path(request.parameters.merge({:sort => "column", :direction => "direction", :page => nil})), :class => "form-control css_class" %>  
5
widjajayd

許可するために列を渡すと、再び動作するはずです!

def sortable(column, title = nil)
    title ||= column.titleize
    css_class = column == sort_column ? "current #{sort_direction}" : nil
    direction = column == sort_column && sort_direction == "asc" ? "desc" : "asc"
    link_to title, params.permit(column).merge(sort: column, direction: direction, page: nil), { class: css_class }
end
2
Mike Langston