【问题标题】:Rails 4 safely using variables in "Where" methodRails 4 在“Where”方法中安全地使用变量
【发布时间】:2015-06-12 17:56:39
【问题描述】:

我自己搜索了一个 Rails 4 应用程序。现在我需要为用户提供不同的列进行搜索。我在视图的搜索表单中创建了一个下拉菜单,如下所示:

<%= form_tag manage_accounts_administrator_path, :method => 'get', :id => "search-form" do %>
      <%= text_field_tag :search, params[:search], placeholder: 'Search Accounts' %>
      <%= select_tag("search_criteria", options_for_select([['by account number', '1'],['by customer id', '2'],['by customer name (ex: Jane Doe)', '3']])) %>
      <%= submit_tag "Search", :name => nil %>
<% end %>

然后在对应的控制器方法中,我是这样做的:

  def manage_accounts
    # criteria from the "Search by" select menu
    if params[:search]
        case (params[:search_criteria])
        when 1
          @criteria = id
        when 2
          @criteria = customer_id
        when 3 
          @criteria = customer.firstname + ' ' + customer.lastname
        end

        @accounts = Account.where("#{@criteria} LIKE ?", "%#{params[:search]}%").page(params[:page]).per(15)
        @table_heading = "Account Search Results"
    else
        @accounts = Account.order('id').page(params[:page]).per(15)
        @table_heading = "Listing All Accounts"
    end

    respond_to do |format|
      format.js
      format.html {render 'manage_accounts'}
    end
  end

上面案例块中@criteria 变量的三个可能值代表“帐户”模型的字段。如您所见,我期望发生的是使用“where”方法进行查询。这个语法是错误的,我得到了错误:

ActiveRecord::StatementInvalid in Administrators#manage_accounts Mysql2::Error: 你的 SQL 语法有错误;检查手册 对应于您的 MySQL 服务器版本以获得正确的语法 在第 1 行的 'LIKE '%722586388%')' 附近使用:SELECT COUNT(*) FROM accountsWHERE (LIKE '%722586388%')

显然我做错了。 如何插入 @criteria 变量,类似于插入搜索参数的方式? 错误告诉我的是该变量被完全转义。我已经尝试(猜测)了几十种不同的标点组合,但都无济于事。如果语法正确,我觉得这会起作用。

另外,我了解到这是一种不好的做法,因为它会使应用容易受到 SQL 注入的攻击。 那么,我应该如何以安全的方式编写此声明?

谢谢

它是带有 MySQL2 gem 的 rails 4.1.8,我是菜鸟。

【问题讨论】:

    标签: sql ruby-on-rails ruby rails-activerecord mysql2


    【解决方案1】:

    您忘记用引号将变量括起来。当执行到行时

    @accounts = Account.where("#{@criteria} LIKE ?", "%#{params[:search]}%").page(params[:page]).per(15)
    

    @criteria 仍将是 nil。所以activerecord生成的sql会是SELECT COUNT(*) FROM accounts WHERE ( LIKE '%722586388%')而不是SELECT COUNT(*) FROM accounts WHERE (id LIKE '%722586388%'),比如

    所以在你的情况下,你将不得不这样做:

    if params[:search]
        case (params[:search_criteria])
        when 1
          @criteria = 'id'
        when 2
          @criteria = 'customer_id'
        when 3 
          @criteria = 'customer.firstname'
        end
    

    【讨论】:

    • 仍然遇到同样的错误。尝试使用单引号和双引号。
    • params[:search]params[:search_criteria] 的值是多少?
    • 是的,我认为这是问题所在。 params[:search] 的值与在文本字段中输入的值一样正确。但是,params[:search_criteria]nil。有问题,显然是我的 select tag_。我不知道它可能是什么。我不习惯 form_tag 这样做的方式。不确定,但显然没有从选择菜单传递给控制器​​。
    • 如果不是12 也不是3@criteria 将是nil,并且您的 SQL 查询将我的格式错误。
    • 我明白了!由于我的 select_tag 选项用引号引起来('1'、'2' 和 '3'),我的“case”块中的 when 参数也需要引号。例如,when '1' .. @criteria = "id"。现在一切都很好!感谢您对这个菜鸟错误的帮助。将此标记为正确答案。
    【解决方案2】:
    if params[:search]
        case (params[:search_criteria])
        when 1
          @criteria = "id"
        when 2
          #assuming you have a customer_id column in your accounts table
          @criteria = "customer_id"
        when 3 
          #assuming you have a customer_name column in your accounts table
          @criteria = "customer_name"
        end
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-07-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-06-28
      • 2014-05-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多