0

提前感谢您提供的任何帮助!我已经查看了有关 Stack Overflow 的类似文章以及这些文章:

但是,我对 MySQL 非常陌生,并且正在使用由另一个开发团队创建的 Ruby on Rails 网站。我只是无法根据我的情况拼凑不同的文章。

我知道我的代码中存在 SQL 注入漏洞,我需要使用参数。我只是不确定如何使用我的代码来做到这一点。我在下面包含了它的一部分:

从我的 search.html.erb 中,SELECT 语句读取:

@office_matches = Masterlocation.paginate_by_sql("select * from mylocations where #      {search_string} order by nickname asc",  :page => params[:page], :per_page => 20)

然后,在 search_controller.rb 中,它显示:

def results
@search_string = ""

@first_term = 'y'
      params[:search_terms_new] = "something in here so loop works"
    if params[:search_terms_new] != ""

# debugger

if params[:city] != ""
  @search_string << "and city like '%#{params[:city]}%' "
  if @first_term == 'y'
    @search_string = @search_string.gsub('and ', " ")
    @first_term = 'n'
  end
end

if params[:search][:state] != ""
  @search_string << "and state = '#{params[:search][:state]}' "
  if @first_term == 'y'
    @search_string = @search_string.gsub('and ', " ")
    @first_term = 'n'
  end
end

我应该如何更改此代码以防止 SQL 注入攻击?

4

1 回答 1

2

我认为您应该重构使用模型范围的方法。

首先将基于作用域的函数或作用域放入模型中。这是我的模型之一,我排除了一些与此示例无关的位。下面你会看到我有两个功能;一种按 account_grouping 搜索,另一种按帐户搜索。

account_grouping 函数与下拉框一起使用,其中下拉框中的第一项是“全部”,而帐户搜索是文本搜索字段。

class CostTypeAllocation < ActiveRecord::Base

  attr_accessible :fiscal_year_id, :fiscal_period_id, :cost_centre_id, :account_grouping, :account_code, :account, :fixed_percentage,
    :marginal_percentage, :incremental_percentage,  :non_applicable_percentage

  scope :in_sort_order, order("fiscal_year_id DESC, fiscal_period_id DESC, account_code")

  # Allow for searching by Account Grouping
  def self.search_account_grouping(account_grouping)
    if account_grouping
      case account_grouping
      when 'all'
        scoped
      else
        where("account_grouping = ?", account_grouping)
      end
    else
      scoped
    end

  end

  # Search the text of the account
  def self.search_account(account)
    if account
      where("account LIKE ?", "%#{account.downcase}%")
    else
      scoped
    end
  end
end

现在我的控制器中处理搜索的功能。

class Admin::CostTypeAllocationsController < ApplicationController
  before_filter :authenticate_user!
  def index
    @search_account_grouping = params[:search_account_grouping] || 'all'
    @search_account = params[:search_account]
    @cost_type_allocations = CostTypeAllocation.search_account_grouping(@search_account_grouping).search_account(@search_account).in_sort_order.paginate(:page => params[:page], :per_page => 10)

  end
end

所以控制器或参数中没有 SQL。一切都封装在模型中应有的位置。分页由 will_paginate gem 处理。


回复您的评论代码在哪里并不重要,但是最好将所有数据访问保留在模型层中。

您的主要问题是在字符串中使用 #{params[:city]} 。用户在参数中输入的任何内容都将放入您的 SQL 中,因此允许 SQL 注入攻击。where('city like ?', "%#{params[:city]}%") 是安全的,因为 rails 会在构造 where 子句之前过滤掉参数中的任何 SQL。

为 where 城市和 where 州设置一个范围,就像我为 where 帐户设置的那样;一旦你有了这些,你就可以去 model.cityscope(params[:city]).statescope(params[:state]) 并且rails会根据需要将它们链接在一起。

我想您需要将范围放在具有城市和州的任何模型中。

请参阅http://guides.rubyonrails.org/security.html上的安全指南

根据您的评论,我认为这就是您可能正在寻找的。

在你的模型中

def self.search_city(city)
    if city
        where ("city LIKE ?", "%#{city}%")
    else
        scoped
    end
end

def self.search_state(state)
    if state
        where ("state LIKE ?", "%#{state}%")
    else
        scoped
    end
end

在你的控制器中

@collection_for_view = Model.search_city(params[:city]).search_state(params[:state])

在每种情况下,如果参数已设置,搜索函数将返回 where 过滤器,如果参数为空,则返回所有记录。

于 2013-01-17T23:41:02.167 回答