10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
|
# 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|
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
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
|