brakeman 1.7.1 → 1.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/bin/brakeman +3 -0
- data/lib/brakeman.rb +2 -0
- data/lib/brakeman/brakeman.rake +4 -3
- data/lib/brakeman/checks/base_check.rb +40 -37
- data/lib/brakeman/checks/check_basic_auth.rb +3 -3
- data/lib/brakeman/checks/check_content_tag.rb +179 -0
- data/lib/brakeman/checks/check_cross_site_scripting.rb +41 -17
- data/lib/brakeman/checks/check_execute.rb +1 -1
- data/lib/brakeman/checks/check_file_access.rb +2 -2
- data/lib/brakeman/checks/check_link_to.rb +9 -7
- data/lib/brakeman/checks/check_link_to_href.rb +1 -1
- data/lib/brakeman/checks/check_mail_to.rb +1 -1
- data/lib/brakeman/checks/check_mass_assignment.rb +6 -5
- data/lib/brakeman/checks/check_redirect.rb +18 -17
- data/lib/brakeman/checks/check_render.rb +3 -1
- data/lib/brakeman/checks/check_select_tag.rb +2 -2
- data/lib/brakeman/checks/check_select_vulnerability.rb +3 -3
- data/lib/brakeman/checks/check_send.rb +3 -3
- data/lib/brakeman/checks/check_session_settings.rb +5 -5
- data/lib/brakeman/checks/check_single_quotes.rb +8 -8
- data/lib/brakeman/checks/check_skip_before_filter.rb +2 -2
- data/lib/brakeman/checks/check_sql.rb +36 -39
- data/lib/brakeman/checks/check_validation_regex.rb +3 -3
- data/lib/brakeman/checks/check_without_protection.rb +2 -2
- data/lib/brakeman/format/style.css +15 -0
- data/lib/brakeman/options.rb +4 -0
- data/lib/brakeman/processor.rb +1 -1
- data/lib/brakeman/processors/alias_processor.rb +63 -61
- data/lib/brakeman/processors/base_processor.rb +31 -45
- data/lib/brakeman/processors/controller_alias_processor.rb +11 -9
- data/lib/brakeman/processors/controller_processor.rb +26 -25
- data/lib/brakeman/processors/erb_template_processor.rb +12 -12
- data/lib/brakeman/processors/erubis_template_processor.rb +19 -17
- data/lib/brakeman/processors/gem_processor.rb +5 -5
- data/lib/brakeman/processors/haml_template_processor.rb +16 -12
- data/lib/brakeman/processors/lib/find_all_calls.rb +11 -17
- data/lib/brakeman/processors/lib/find_call.rb +16 -23
- data/lib/brakeman/processors/lib/processor_helper.rb +11 -5
- data/lib/brakeman/processors/lib/rails2_config_processor.rb +21 -20
- data/lib/brakeman/processors/lib/rails2_route_processor.rb +38 -34
- data/lib/brakeman/processors/lib/rails3_config_processor.rb +17 -17
- data/lib/brakeman/processors/lib/rails3_route_processor.rb +42 -40
- data/lib/brakeman/processors/lib/render_helper.rb +6 -6
- data/lib/brakeman/processors/lib/route_helper.rb +1 -1
- data/lib/brakeman/processors/library_processor.rb +11 -11
- data/lib/brakeman/processors/model_processor.rb +18 -16
- data/lib/brakeman/processors/template_alias_processor.rb +36 -29
- data/lib/brakeman/processors/template_processor.rb +4 -4
- data/lib/brakeman/report.rb +23 -4
- data/lib/brakeman/templates/error_overview.html.erb +9 -1
- data/lib/brakeman/templates/view_warnings.html.erb +16 -3
- data/lib/brakeman/tracker.rb +3 -0
- data/lib/brakeman/util.rb +5 -1
- data/lib/brakeman/version.rb +1 -1
- data/lib/brakeman/warning.rb +1 -1
- data/lib/ruby_parser/bm_sexp.rb +302 -2
- metadata +6 -5
@@ -27,7 +27,7 @@ class Brakeman::CheckFileAccess < Brakeman::BaseCheck
|
|
27
27
|
return if duplicate? result
|
28
28
|
add_result result
|
29
29
|
call = result[:call]
|
30
|
-
file_name = call
|
30
|
+
file_name = call.first_arg
|
31
31
|
|
32
32
|
if match = has_immediate_user_input?(file_name)
|
33
33
|
confidence = CONFIDENCE[:high]
|
@@ -38,7 +38,7 @@ class Brakeman::CheckFileAccess < Brakeman::BaseCheck
|
|
38
38
|
match = include_user_input?(file_name)
|
39
39
|
|
40
40
|
#Check for string building in file name
|
41
|
-
if call?(file_name) and (file_name
|
41
|
+
if call?(file_name) and (file_name.method == :+ or file_name.method == :<<)
|
42
42
|
confidence = CONFIDENCE[:high]
|
43
43
|
else
|
44
44
|
confidence = CONFIDENCE[:low]
|
@@ -40,21 +40,23 @@ class Brakeman::CheckLinkTo < Brakeman::CheckCrossSiteScripting
|
|
40
40
|
#an ignored method call by the code above.
|
41
41
|
call = result[:call] = result[:call].dup
|
42
42
|
|
43
|
+
args = call.args
|
44
|
+
|
43
45
|
@matched = false
|
44
46
|
|
45
47
|
#Skip if no arguments(?) or first argument is a hash
|
46
|
-
return if
|
48
|
+
return if args.first.nil? or hash? args.first
|
47
49
|
|
48
50
|
if version_between? "2.0.0", "2.2.99"
|
49
|
-
check_argument result,
|
51
|
+
check_argument result, args.first
|
50
52
|
|
51
|
-
if
|
52
|
-
check_argument result,
|
53
|
+
if args.second and not hash? args.second
|
54
|
+
check_argument result, args.second
|
53
55
|
end
|
54
|
-
elsif
|
56
|
+
elsif args.second
|
55
57
|
#Only check first argument if there is a second argument
|
56
58
|
#in Rails 2.3.x
|
57
|
-
check_argument result,
|
59
|
+
check_argument result, args.first
|
58
60
|
end
|
59
61
|
end
|
60
62
|
|
@@ -128,7 +130,7 @@ class Brakeman::CheckLinkTo < Brakeman::CheckCrossSiteScripting
|
|
128
130
|
def actually_process_call exp
|
129
131
|
return if @matched
|
130
132
|
|
131
|
-
target = exp
|
133
|
+
target = exp.target
|
132
134
|
if sexp? target
|
133
135
|
target = process target.dup
|
134
136
|
end
|
@@ -34,7 +34,7 @@ class Brakeman::CheckLinkToHref < Brakeman::CheckLinkTo
|
|
34
34
|
#an ignored method call by the code above.
|
35
35
|
call = result[:call] = result[:call].dup
|
36
36
|
@matched = false
|
37
|
-
url_arg = process call
|
37
|
+
url_arg = process call.args.second
|
38
38
|
|
39
39
|
#Ignore situations where the href is an interpolated string
|
40
40
|
#with something before the user input
|
@@ -52,8 +52,8 @@ class Brakeman::CheckMassAssignment < Brakeman::BaseCheck
|
|
52
52
|
|
53
53
|
if attr_protected and tracker.options[:ignore_attr_protected]
|
54
54
|
return
|
55
|
-
elsif input = include_user_input?(call
|
56
|
-
if not hash? call
|
55
|
+
elsif input = include_user_input?(call.arglist)
|
56
|
+
if not hash? call.first_arg and not attr_protected
|
57
57
|
confidence = CONFIDENCE[:high]
|
58
58
|
user_input = input.match
|
59
59
|
else
|
@@ -78,10 +78,11 @@ class Brakeman::CheckMassAssignment < Brakeman::BaseCheck
|
|
78
78
|
|
79
79
|
#Want to ignore calls to Model.new that have no arguments
|
80
80
|
def check_call call
|
81
|
-
args =
|
82
|
-
|
81
|
+
args = process_all call.args
|
82
|
+
|
83
|
+
if args.empty? #empty new()
|
83
84
|
false
|
84
|
-
elsif hash? args
|
85
|
+
elsif hash? args.first and not include_user_input? args.first
|
85
86
|
false
|
86
87
|
elsif all_literals? args
|
87
88
|
false
|
@@ -29,7 +29,7 @@ class Brakeman::CheckRedirect < Brakeman::BaseCheck
|
|
29
29
|
|
30
30
|
call = result[:call]
|
31
31
|
|
32
|
-
method = call
|
32
|
+
method = call.method
|
33
33
|
|
34
34
|
if method == :redirect_to and not only_path?(call) and res = include_user_input?(call)
|
35
35
|
add_result result
|
@@ -56,11 +56,12 @@ class Brakeman::CheckRedirect < Brakeman::BaseCheck
|
|
56
56
|
def include_user_input? call
|
57
57
|
Brakeman.debug "Checking if call includes user input"
|
58
58
|
|
59
|
-
args = call
|
59
|
+
args = call.args
|
60
|
+
first_arg = call.first_arg
|
60
61
|
|
61
|
-
if tracker.options[:ignore_redirect_to_model] and call?
|
62
|
-
(@model_find_calls.include?
|
63
|
-
model_name?
|
62
|
+
if tracker.options[:ignore_redirect_to_model] and call? first_arg and
|
63
|
+
(@model_find_calls.include? first_arg.method or first_arg.method.to_s.match(/^find_by_/)) and
|
64
|
+
model_name? first_arg.target
|
64
65
|
|
65
66
|
return false
|
66
67
|
end
|
@@ -94,14 +95,14 @@ class Brakeman::CheckRedirect < Brakeman::BaseCheck
|
|
94
95
|
#Checks +redirect_to+ arguments for +only_path => true+ which essentially
|
95
96
|
#nullifies the danger posed by redirecting with user input
|
96
97
|
def only_path? call
|
97
|
-
call
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
elsif call? arg and arg[2] == :url_for
|
103
|
-
return check_url_for(arg)
|
98
|
+
arg = call.first_arg
|
99
|
+
|
100
|
+
if hash? arg
|
101
|
+
if value = hash_access(arg, :only_path)
|
102
|
+
return true if true?(value)
|
104
103
|
end
|
104
|
+
elsif call? arg and arg.method == :url_for
|
105
|
+
return check_url_for(arg)
|
105
106
|
end
|
106
107
|
|
107
108
|
false
|
@@ -110,11 +111,11 @@ class Brakeman::CheckRedirect < Brakeman::BaseCheck
|
|
110
111
|
#+url_for+ is only_path => true by default. This checks to see if it is
|
111
112
|
#set to false for some reason.
|
112
113
|
def check_url_for call
|
113
|
-
call
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
114
|
+
arg = call.first_arg
|
115
|
+
|
116
|
+
if hash? arg
|
117
|
+
if value = hash_access(arg, :only_path)
|
118
|
+
return false if false?(value)
|
118
119
|
end
|
119
120
|
end
|
120
121
|
|
@@ -13,7 +13,9 @@ class Brakeman::CheckRender < Brakeman::BaseCheck
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def process_render result
|
16
|
-
|
16
|
+
return unless node_type? result[:call], :render
|
17
|
+
|
18
|
+
case result[:call].render_type
|
17
19
|
when :partial, :template, :action, :file
|
18
20
|
check_for_dynamic_path result
|
19
21
|
when :inline
|
@@ -38,12 +38,12 @@ class Brakeman::CheckSelectTag < Brakeman::BaseCheck
|
|
38
38
|
add_result result
|
39
39
|
|
40
40
|
#Only concerned if user input is supplied for :prompt option
|
41
|
-
last_arg = result[:call]
|
41
|
+
last_arg = result[:call].arglist.last
|
42
42
|
|
43
43
|
if hash? last_arg
|
44
44
|
prompt_option = hash_access last_arg, :prompt
|
45
45
|
|
46
|
-
if call? prompt_option and @ignore_methods.include? prompt_option
|
46
|
+
if call? prompt_option and @ignore_methods.include? prompt_option.method
|
47
47
|
return
|
48
48
|
elsif sexp? prompt_option and input = include_user_input?(prompt_option)
|
49
49
|
|
@@ -35,13 +35,13 @@ class Brakeman::CheckSelectVulnerability < Brakeman::BaseCheck
|
|
35
35
|
def process_result result
|
36
36
|
return if duplicate? result
|
37
37
|
|
38
|
-
|
38
|
+
third_arg = result[:call].args[2]
|
39
39
|
|
40
40
|
#Check for user input in options parameter
|
41
|
-
if sexp?
|
41
|
+
if sexp? third_arg and include_user_input? third_arg
|
42
42
|
add_result result
|
43
43
|
|
44
|
-
if node_type?
|
44
|
+
if node_type? third_arg, :string_interp, :dstr
|
45
45
|
confidence = CONFIDENCE[:med]
|
46
46
|
else
|
47
47
|
confidence = CONFIDENCE[:low]
|
@@ -16,10 +16,10 @@ class Brakeman::CheckSend < Brakeman::BaseCheck
|
|
16
16
|
end
|
17
17
|
|
18
18
|
def process_result result
|
19
|
-
args =
|
20
|
-
target = process result[:call]
|
19
|
+
args = process_all result[:call].args
|
20
|
+
target = process result[:call].target
|
21
21
|
|
22
|
-
if input = has_immediate_user_input?(args
|
22
|
+
if input = has_immediate_user_input?(args.first)
|
23
23
|
warn :result => result,
|
24
24
|
:warning_type => "Dangerous Send",
|
25
25
|
:message => "User controlled method execution",
|
@@ -31,8 +31,8 @@ class Brakeman::CheckSessionSettings < Brakeman::BaseCheck
|
|
31
31
|
#Looks for ActionController::Base.session = { ... }
|
32
32
|
#in Rails 2.x apps
|
33
33
|
def process_attrasgn exp
|
34
|
-
if not tracker.options[:rails3] and exp
|
35
|
-
check_for_issues exp
|
34
|
+
if not tracker.options[:rails3] and exp.target == @session_settings and exp.method == :session=
|
35
|
+
check_for_issues exp.first_arg, "#{tracker.options[:app_path]}/config/initializers/session_store.rb"
|
36
36
|
end
|
37
37
|
|
38
38
|
exp
|
@@ -41,8 +41,8 @@ class Brakeman::CheckSessionSettings < Brakeman::BaseCheck
|
|
41
41
|
#Looks for Rails3::Application.config.session_store :cookie_store, { ... }
|
42
42
|
#in Rails 3.x apps
|
43
43
|
def process_call exp
|
44
|
-
if tracker.options[:rails3] and exp
|
45
|
-
check_for_issues exp
|
44
|
+
if tracker.options[:rails3] and exp.target == @session_settings and exp.method == :session_store
|
45
|
+
check_for_issues exp.args.second, "#{tracker.options[:app_path]}/config/initializers/session_store.rb"
|
46
46
|
end
|
47
47
|
|
48
48
|
exp
|
@@ -63,7 +63,7 @@ class Brakeman::CheckSessionSettings < Brakeman::BaseCheck
|
|
63
63
|
end
|
64
64
|
|
65
65
|
if value = hash_access(settings, :secret)
|
66
|
-
if string? value and value
|
66
|
+
if string? value and value.value.length < 30
|
67
67
|
|
68
68
|
warn :warning_type => "Session Setting",
|
69
69
|
:message => "Session secret should be at least 30 characters long",
|
@@ -50,9 +50,9 @@ class Brakeman::CheckSingleQuotes < Brakeman::BaseCheck
|
|
50
50
|
#
|
51
51
|
# class ERB
|
52
52
|
def process_class exp
|
53
|
-
if exp
|
53
|
+
if exp.class_name == :ERB
|
54
54
|
@inside_erb = true
|
55
|
-
process exp
|
55
|
+
process exp.body
|
56
56
|
@inside_erb = false
|
57
57
|
end
|
58
58
|
|
@@ -63,9 +63,9 @@ class Brakeman::CheckSingleQuotes < Brakeman::BaseCheck
|
|
63
63
|
#
|
64
64
|
# module Util
|
65
65
|
def process_module exp
|
66
|
-
if @inside_erb and exp
|
66
|
+
if @inside_erb and exp.module_name == :Util
|
67
67
|
@inside_util = true
|
68
|
-
process exp
|
68
|
+
process exp.body
|
69
69
|
@inside_util = false
|
70
70
|
end
|
71
71
|
|
@@ -76,9 +76,9 @@ class Brakeman::CheckSingleQuotes < Brakeman::BaseCheck
|
|
76
76
|
#
|
77
77
|
# def html_escape
|
78
78
|
def process_defn exp
|
79
|
-
if @inside_util and exp
|
79
|
+
if @inside_util and exp.method_name == :html_escape
|
80
80
|
@inside_html_escape = true
|
81
|
-
process exp
|
81
|
+
process exp.body
|
82
82
|
@inside_html_escape = false
|
83
83
|
end
|
84
84
|
|
@@ -89,10 +89,10 @@ class Brakeman::CheckSingleQuotes < Brakeman::BaseCheck
|
|
89
89
|
#
|
90
90
|
# Rack::Utils.escape_html
|
91
91
|
def process_call exp
|
92
|
-
if @inside_html_escape and exp
|
92
|
+
if @inside_html_escape and exp.target == RACK_UTILS and exp.method == :escape_html
|
93
93
|
@uses_rack_escape = true
|
94
94
|
else
|
95
|
-
process exp
|
95
|
+
process exp.target if exp.target
|
96
96
|
end
|
97
97
|
|
98
98
|
exp
|
@@ -35,9 +35,9 @@ class Brakeman::CheckSkipBeforeFilter < Brakeman::BaseCheck
|
|
35
35
|
def skip_verify_except? filter
|
36
36
|
return false unless call? filter
|
37
37
|
|
38
|
-
args = filter
|
38
|
+
args = filter.args
|
39
39
|
|
40
|
-
if symbol? args
|
40
|
+
if symbol? args.first and args.first.value == :verify_authenticity_token and hash? args.last
|
41
41
|
if hash_access(args.last, :except)
|
42
42
|
return true
|
43
43
|
end
|
@@ -53,6 +53,7 @@ class Brakeman::CheckSQL < Brakeman::BaseCheck
|
|
53
53
|
end
|
54
54
|
|
55
55
|
#Find calls to named_scope() or scope() in models
|
56
|
+
#RP 3 TODO
|
56
57
|
def find_scope_calls
|
57
58
|
scope_calls = []
|
58
59
|
|
@@ -71,12 +72,11 @@ class Brakeman::CheckSQL < Brakeman::BaseCheck
|
|
71
72
|
model[:options][:scope].each do |args|
|
72
73
|
second_arg = args[2]
|
73
74
|
|
74
|
-
if second_arg.node_type == :iter and
|
75
|
-
(second_arg[-1].node_type == :block or second_arg[-1].node_type == :call)
|
75
|
+
if second_arg.node_type == :iter and node_type? second_arg.block, :block, :call
|
76
76
|
process_scope_with_block name, args
|
77
77
|
elsif second_arg.node_type == :call
|
78
78
|
call = second_arg
|
79
|
-
scope_calls << { :call => call, :location => [:class, name ], :method => call
|
79
|
+
scope_calls << { :call => call, :location => [:class, name ], :method => call.method }
|
80
80
|
else
|
81
81
|
call = Sexp.new(:call, nil, :scope, args).line(args.line)
|
82
82
|
scope_calls << { :call => call, :location => [:class, name ], :method => :scope }
|
@@ -135,7 +135,7 @@ class Brakeman::CheckSQL < Brakeman::BaseCheck
|
|
135
135
|
end
|
136
136
|
end
|
137
137
|
elsif block.node_type == :call
|
138
|
-
process_result :target => block
|
138
|
+
process_result :target => block.target, :method => block.method, :call => block, :location => [:class, model_name, scope_name]
|
139
139
|
end
|
140
140
|
end
|
141
141
|
|
@@ -170,38 +170,38 @@ class Brakeman::CheckSQL < Brakeman::BaseCheck
|
|
170
170
|
return if duplicate? result or result[:call].original_line
|
171
171
|
|
172
172
|
call = result[:call]
|
173
|
-
method = call
|
174
|
-
args = call
|
173
|
+
method = call.method
|
174
|
+
args = call.args
|
175
175
|
|
176
176
|
dangerous_value = case method
|
177
177
|
when :find
|
178
|
-
check_find_arguments args
|
178
|
+
check_find_arguments args.second
|
179
179
|
when :exists?
|
180
|
-
check_find_arguments args
|
180
|
+
check_find_arguments args.first
|
181
181
|
when :named_scope, :scope
|
182
|
-
check_scope_arguments
|
182
|
+
check_scope_arguments call.arglist
|
183
183
|
when :find_by_sql, :count_by_sql
|
184
|
-
check_by_sql_arguments args
|
184
|
+
check_by_sql_arguments args.first
|
185
185
|
when :calculate
|
186
|
-
check_find_arguments args[
|
186
|
+
check_find_arguments args[2]
|
187
187
|
when :last, :first, :all
|
188
|
-
check_find_arguments args
|
188
|
+
check_find_arguments args.first
|
189
189
|
when :average, :count, :maximum, :minimum, :sum
|
190
190
|
if args.length > 2
|
191
|
-
unsafe_sql?(args
|
191
|
+
unsafe_sql?(args.first) or check_find_arguments(args.last)
|
192
192
|
else
|
193
|
-
check_find_arguments args
|
193
|
+
check_find_arguments args.last
|
194
194
|
end
|
195
195
|
when :where, :having
|
196
|
-
check_query_arguments
|
196
|
+
check_query_arguments call.arglist
|
197
197
|
when :order, :group, :reorder
|
198
|
-
check_order_arguments
|
198
|
+
check_order_arguments call.arglist
|
199
199
|
when :joins
|
200
|
-
check_joins_arguments args
|
200
|
+
check_joins_arguments args.first
|
201
201
|
when :from, :select
|
202
|
-
unsafe_sql? args
|
202
|
+
unsafe_sql? args.first
|
203
203
|
when :lock
|
204
|
-
check_lock_arguments args
|
204
|
+
check_lock_arguments args.first
|
205
205
|
else
|
206
206
|
Brakeman.debug "Unhandled SQL method: #{method}"
|
207
207
|
end
|
@@ -375,8 +375,8 @@ class Brakeman::CheckSQL < Brakeman::BaseCheck
|
|
375
375
|
#unless safe_value? explicitly returns true.
|
376
376
|
def check_string_interp arg
|
377
377
|
arg.each do |exp|
|
378
|
-
if node_type?(exp, :string_eval, :evstr) and not safe_value? exp
|
379
|
-
return exp
|
378
|
+
if node_type?(exp, :string_eval, :evstr) and not safe_value? exp.value
|
379
|
+
return exp.value
|
380
380
|
end
|
381
381
|
end
|
382
382
|
|
@@ -417,9 +417,9 @@ class Brakeman::CheckSQL < Brakeman::BaseCheck
|
|
417
417
|
when :hash
|
418
418
|
check_hash_values exp unless ignore_hash
|
419
419
|
when :if
|
420
|
-
unsafe_sql? exp
|
420
|
+
unsafe_sql? exp.then_clause or unsafe_sql? exp.else_clause
|
421
421
|
when :call
|
422
|
-
unless IGNORE_METHODS_IN_SQL.include? exp
|
422
|
+
unless IGNORE_METHODS_IN_SQL.include? exp.method
|
423
423
|
if has_immediate_user_input? exp or has_immediate_model? exp
|
424
424
|
exp
|
425
425
|
else
|
@@ -427,13 +427,13 @@ class Brakeman::CheckSQL < Brakeman::BaseCheck
|
|
427
427
|
end
|
428
428
|
end
|
429
429
|
when :or
|
430
|
-
if unsafe = (unsafe_sql?(exp
|
430
|
+
if unsafe = (unsafe_sql?(exp.lhs) || unsafe_sql?(exp.rhs))
|
431
431
|
return unsafe
|
432
432
|
else
|
433
433
|
nil
|
434
434
|
end
|
435
435
|
when :block, :rlist
|
436
|
-
unsafe_sql? exp
|
436
|
+
unsafe_sql? exp.last
|
437
437
|
else
|
438
438
|
if has_immediate_user_input? exp or has_immediate_model? exp
|
439
439
|
exp
|
@@ -482,11 +482,11 @@ class Brakeman::CheckSQL < Brakeman::BaseCheck
|
|
482
482
|
def check_for_string_building exp
|
483
483
|
return unless call? exp
|
484
484
|
|
485
|
-
target = exp
|
486
|
-
method = exp
|
487
|
-
args = exp
|
485
|
+
target = exp.target
|
486
|
+
method = exp.method
|
487
|
+
args = exp.args
|
488
488
|
|
489
|
-
if string? target or string? args
|
489
|
+
if string? target or string? args.first
|
490
490
|
if STRING_METHODS.include? method
|
491
491
|
return exp
|
492
492
|
end
|
@@ -507,13 +507,13 @@ class Brakeman::CheckSQL < Brakeman::BaseCheck
|
|
507
507
|
when :str, :lit, :const, :colon2, :nil, :true, :false
|
508
508
|
true
|
509
509
|
when :call
|
510
|
-
IGNORE_METHODS_IN_SQL.include? exp
|
510
|
+
IGNORE_METHODS_IN_SQL.include? exp.method
|
511
511
|
when :if
|
512
|
-
safe_value? exp
|
512
|
+
safe_value? exp.then_clause and safe_value? exp.else_clause
|
513
513
|
when :block, :rlist
|
514
|
-
safe_value? exp
|
514
|
+
safe_value? exp.last
|
515
515
|
when :or
|
516
|
-
safe_value? exp
|
516
|
+
safe_value? exp.lhs and safe_value? exp.rhs
|
517
517
|
else
|
518
518
|
false
|
519
519
|
end
|
@@ -523,13 +523,10 @@ class Brakeman::CheckSQL < Brakeman::BaseCheck
|
|
523
523
|
def check_call exp
|
524
524
|
return unless call? exp
|
525
525
|
|
526
|
-
target = exp[1]
|
527
|
-
args = exp[3]
|
528
|
-
|
529
526
|
if unsafe = check_for_string_building(exp)
|
530
527
|
unsafe
|
531
|
-
elsif call? target
|
532
|
-
check_call target
|
528
|
+
elsif call? exp.target
|
529
|
+
check_call exp.target
|
533
530
|
else
|
534
531
|
nil
|
535
532
|
end
|
@@ -565,6 +562,6 @@ class Brakeman::CheckSQL < Brakeman::BaseCheck
|
|
565
562
|
# s(:arglist, s(:str, "something")))
|
566
563
|
def constantize_call? result
|
567
564
|
call = result[:call]
|
568
|
-
call? call
|
565
|
+
call? call.target and call.target.method == :constantize
|
569
566
|
end
|
570
567
|
end
|