class TaintedLove::Replacer::ReplaceActiveRecord

Public Instance Methods

replace!() click to toggle source
Calls superclass method
# File lib/tainted_love/replacer/replace_active_record.rb, line 10
def replace!
  require 'active_record/relation'

  TaintedLove.proxy_method('ActiveRecord::QueryMethods', :where) do |_, *args|
    unless args.empty?
      f = args.first
      if f.is_a?(String) && f.tainted?
        TaintedLove.report(:ReplaceActiveRecord, f, [:sqli], 'Model.where using tainted string')
      end
    end
  end

  TaintedLove.proxy_method('ActiveRecord::QueryMethods', :order) do |_, *args|
    unless args.empty?
      f = args.first
      if f.is_a?(String) && f.tainted?
        TaintedLove.report(:ReplaceActiveRecord, f, [:sqli], 'Model.order using tainted string')
      end
    end
  end

  TaintedLove.proxy_method('ActiveRecord::QueryMethods', :select) do |_, *args|
    unless args.empty?
      f = args.first
      if f.is_a?(String) && f.tainted?
        TaintedLove.report(:ReplaceActiveRecord, f, [:sqli], 'Model.select using tainted string')
      end
    end
  end

  mod = Module.new do
    [:find_by_sql, :count_by_sql].each do |method|
      define_method(method) do |*args|

        # skip if find_by_sql is coming from find_by because the where monkey-patch will catch it
        unless Thread.current.backtrace(3).take(1).first["in `find_by'"]
          if args.first.tainted?
            TaintedLove.report(:ReplaceActiveRecord, args.first, [:sqli], "Model##{method} using tainted string")
          end
        end

        super(*args)
      end
    end

    # Removes taint on string have been sanitized, unless the first argument is tainted
    def sanitize_sql_array(ary)
      return_value = super(ary)

      if ary.first.tainted?
        return_value.taint
      else
        return_value.untaint
      end
    end
  end

  ActiveRecord::Base.extend(mod)
end
sanitize_sql_array(ary) click to toggle source

Removes taint on string have been sanitized, unless the first argument is tainted

Calls superclass method
# File lib/tainted_love/replacer/replace_active_record.rb, line 56
def sanitize_sql_array(ary)
  return_value = super(ary)

  if ary.first.tainted?
    return_value.taint
  else
    return_value.untaint
  end
end
should_replace?() click to toggle source
# File lib/tainted_love/replacer/replace_active_record.rb, line 6
def should_replace?
  Object.const_defined?('ActiveRecord')
end