提前感谢您提供的任何帮助!我已经回顾了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注入攻击?
答案 0 :(得分:2)
我认为你应该重构你使用模型范围的方法。
首先将基于范围的函数或作用域放在模型中。这是我的一个模型,我已经排除了一些与此示例无关的位。下面你会看到我有两个功能;一个按帐号分组搜索,另一个按帐号搜索。
account_grouping函数与下拉框一起使用,其中下拉列表中的第一项是“all”,而帐户搜索是文本搜索字段。
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子句之前过滤出param中的任何SQL。
设置一个范围,用于指明城市和州的状况,就像我为帐户设置的那样;一旦你有了那些,你就可以去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过滤器,如果为空,则返回所有记录。