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.
Files changed (57) hide show
  1. data/bin/brakeman +3 -0
  2. data/lib/brakeman.rb +2 -0
  3. data/lib/brakeman/brakeman.rake +4 -3
  4. data/lib/brakeman/checks/base_check.rb +40 -37
  5. data/lib/brakeman/checks/check_basic_auth.rb +3 -3
  6. data/lib/brakeman/checks/check_content_tag.rb +179 -0
  7. data/lib/brakeman/checks/check_cross_site_scripting.rb +41 -17
  8. data/lib/brakeman/checks/check_execute.rb +1 -1
  9. data/lib/brakeman/checks/check_file_access.rb +2 -2
  10. data/lib/brakeman/checks/check_link_to.rb +9 -7
  11. data/lib/brakeman/checks/check_link_to_href.rb +1 -1
  12. data/lib/brakeman/checks/check_mail_to.rb +1 -1
  13. data/lib/brakeman/checks/check_mass_assignment.rb +6 -5
  14. data/lib/brakeman/checks/check_redirect.rb +18 -17
  15. data/lib/brakeman/checks/check_render.rb +3 -1
  16. data/lib/brakeman/checks/check_select_tag.rb +2 -2
  17. data/lib/brakeman/checks/check_select_vulnerability.rb +3 -3
  18. data/lib/brakeman/checks/check_send.rb +3 -3
  19. data/lib/brakeman/checks/check_session_settings.rb +5 -5
  20. data/lib/brakeman/checks/check_single_quotes.rb +8 -8
  21. data/lib/brakeman/checks/check_skip_before_filter.rb +2 -2
  22. data/lib/brakeman/checks/check_sql.rb +36 -39
  23. data/lib/brakeman/checks/check_validation_regex.rb +3 -3
  24. data/lib/brakeman/checks/check_without_protection.rb +2 -2
  25. data/lib/brakeman/format/style.css +15 -0
  26. data/lib/brakeman/options.rb +4 -0
  27. data/lib/brakeman/processor.rb +1 -1
  28. data/lib/brakeman/processors/alias_processor.rb +63 -61
  29. data/lib/brakeman/processors/base_processor.rb +31 -45
  30. data/lib/brakeman/processors/controller_alias_processor.rb +11 -9
  31. data/lib/brakeman/processors/controller_processor.rb +26 -25
  32. data/lib/brakeman/processors/erb_template_processor.rb +12 -12
  33. data/lib/brakeman/processors/erubis_template_processor.rb +19 -17
  34. data/lib/brakeman/processors/gem_processor.rb +5 -5
  35. data/lib/brakeman/processors/haml_template_processor.rb +16 -12
  36. data/lib/brakeman/processors/lib/find_all_calls.rb +11 -17
  37. data/lib/brakeman/processors/lib/find_call.rb +16 -23
  38. data/lib/brakeman/processors/lib/processor_helper.rb +11 -5
  39. data/lib/brakeman/processors/lib/rails2_config_processor.rb +21 -20
  40. data/lib/brakeman/processors/lib/rails2_route_processor.rb +38 -34
  41. data/lib/brakeman/processors/lib/rails3_config_processor.rb +17 -17
  42. data/lib/brakeman/processors/lib/rails3_route_processor.rb +42 -40
  43. data/lib/brakeman/processors/lib/render_helper.rb +6 -6
  44. data/lib/brakeman/processors/lib/route_helper.rb +1 -1
  45. data/lib/brakeman/processors/library_processor.rb +11 -11
  46. data/lib/brakeman/processors/model_processor.rb +18 -16
  47. data/lib/brakeman/processors/template_alias_processor.rb +36 -29
  48. data/lib/brakeman/processors/template_processor.rb +4 -4
  49. data/lib/brakeman/report.rb +23 -4
  50. data/lib/brakeman/templates/error_overview.html.erb +9 -1
  51. data/lib/brakeman/templates/view_warnings.html.erb +16 -3
  52. data/lib/brakeman/tracker.rb +3 -0
  53. data/lib/brakeman/util.rb +5 -1
  54. data/lib/brakeman/version.rb +1 -1
  55. data/lib/brakeman/warning.rb +1 -1
  56. data/lib/ruby_parser/bm_sexp.rb +302 -2
  57. metadata +6 -5
@@ -28,7 +28,7 @@ class Brakeman::CheckValidationRegex < Brakeman::BaseCheck
28
28
 
29
29
  #Check validates_format_of
30
30
  def process_validator validator
31
- if value = hash_access(validator[-1], WITH)
31
+ if value = hash_access(validator.last, WITH)
32
32
  check_regex value, validator
33
33
  end
34
34
  end
@@ -38,12 +38,12 @@ class Brakeman::CheckValidationRegex < Brakeman::BaseCheck
38
38
  def check_regex value, validator
39
39
  return unless regexp? value
40
40
 
41
- regex = value[1].inspect
41
+ regex = value.value.inspect
42
42
  if regex =~ /^\/(.{2}).*(.{2})\/(m|i|x|n|e|u|s|o)*\z/
43
43
  if $1 != "\\A" or ($2 != "\\Z" and $2 != "\\z")
44
44
  warn :model => @current_model,
45
45
  :warning_type => "Format Validation",
46
- :message => "Insufficient validation for '#{get_name validator}' using #{value[1].inspect}. Use \\A and \\z as anchors",
46
+ :message => "Insufficient validation for '#{get_name validator}' using #{value.value.inspect}. Use \\A and \\z as anchors",
47
47
  :line => value.line,
48
48
  :confidence => CONFIDENCE[:high]
49
49
  end
@@ -33,7 +33,7 @@ class Brakeman::CheckWithoutProtection < Brakeman::BaseCheck
33
33
  #All results should be Model.new(...) or Model.attributes=() calls
34
34
  def process_result res
35
35
  call = res[:call]
36
- last_arg = call[3][-1]
36
+ last_arg = call.args.last
37
37
 
38
38
  if hash? last_arg and not call.original_line and not duplicate? res
39
39
 
@@ -41,7 +41,7 @@ class Brakeman::CheckWithoutProtection < Brakeman::BaseCheck
41
41
  if true? value
42
42
  add_result res
43
43
 
44
- if input = include_user_input?(call[3])
44
+ if input = include_user_input?(call.arglist)
45
45
  confidence = CONFIDENCE[:high]
46
46
  user_input = input.match
47
47
  else
@@ -116,3 +116,18 @@ p {
116
116
  .user_input {
117
117
  background-color: #fcecab;
118
118
  }
119
+
120
+ div.render_path {
121
+ display: none;
122
+ background-color: #ffe;
123
+ padding: 5px;
124
+ margin: 2px 0px 2px 0px;
125
+ }
126
+
127
+ div.template_name {
128
+ cursor: pointer;
129
+ }
130
+
131
+ div.template_name:hover {
132
+ background-color: white;
133
+ }
@@ -169,6 +169,10 @@ module Brakeman::Options
169
169
  options[:summary_only] = true
170
170
  end
171
171
 
172
+ opts.on "--relative-paths", "Output relative file paths in reports" do
173
+ options[:relative_paths] = true
174
+ end
175
+
172
176
  opts.on "-w",
173
177
  "--confidence-level LEVEL",
174
178
  ["1", "2", "3"],
@@ -72,7 +72,7 @@ module Brakeman
72
72
  #Each template which is rendered is stored separately
73
73
  #with a new name.
74
74
  if called_from
75
- name = (name.to_s + "." + called_from.to_s).to_sym
75
+ name = ("#{name}.#{called_from}").to_sym
76
76
  end
77
77
 
78
78
  @tracker.templates[name][:src] = result
@@ -97,7 +97,7 @@ class Brakeman::AliasProcessor < Brakeman::SexpProcessor
97
97
 
98
98
  #Process a method call.
99
99
  def process_call exp
100
- target_var = exp[1]
100
+ target_var = exp.target
101
101
  exp = process_default exp
102
102
 
103
103
  #In case it is replaced with something else
@@ -105,74 +105,75 @@ class Brakeman::AliasProcessor < Brakeman::SexpProcessor
105
105
  return exp
106
106
  end
107
107
 
108
- target = exp[1]
109
- method = exp[2]
108
+ target = exp.target
109
+ method = exp.method
110
110
  args = exp[3]
111
+ first_arg = exp.first_arg
111
112
 
112
113
  #See if it is possible to simplify some basic cases
113
114
  #of addition/concatenation.
114
115
  case method
115
116
  when :+
116
- if array? target and array? args[1]
117
- joined = join_arrays target, args[1]
117
+ if array? target and array? first_arg
118
+ joined = join_arrays target, first_arg
118
119
  joined.line(exp.line)
119
120
  exp = joined
120
- elsif string? args[1]
121
+ elsif string? first_arg
121
122
  if string? target # "blah" + "blah"
122
- joined = join_strings target, args[1]
123
+ joined = join_strings target, first_arg
123
124
  joined.line(exp.line)
124
125
  exp = joined
125
- elsif call? target and target[2] == :+ and string? target[3][1]
126
- joined = join_strings target[3][1], args[1]
126
+ elsif call? target and target.method == :+ and string? target.first_arg
127
+ joined = join_strings target.first_arg, first_arg
127
128
  joined.line(exp.line)
128
- target[3][1] = joined
129
+ target.first_arg = joined
129
130
  exp = target
130
131
  end
131
- elsif number? args[1]
132
+ elsif number? first_arg
132
133
  if number? target
133
- exp = Sexp.new(:lit, target[1] + args[1][1])
134
- elsif target[2] == :+ and number? target[3][1]
135
- target[3][1] = Sexp.new(:lit, target[3][1][1] + args[1][1])
134
+ exp = Sexp.new(:lit, target.value + first_arg.value)
135
+ elsif call? target and target.method == :+ and number? target.first_arg
136
+ target.first_arg = Sexp.new(:lit, target.first_arg.value + first_arg.value)
136
137
  exp = target
137
138
  end
138
139
  end
139
140
  when :-
140
- if number? target and number? args[1]
141
- exp = Sexp.new(:lit, target[1] - args[1][1])
141
+ if number? target and number? first_arg
142
+ exp = Sexp.new(:lit, target.value - first_arg.value)
142
143
  end
143
144
  when :*
144
- if number? target and number? args[1]
145
- exp = Sexp.new(:lit, target[1] * args[1][1])
145
+ if number? target and number? first_arg
146
+ exp = Sexp.new(:lit, target.value * first_arg.value)
146
147
  end
147
148
  when :/
148
- if number? target and number? args[1]
149
- exp = Sexp.new(:lit, target[1] / args[1][1])
149
+ if number? target and number? first_arg
150
+ exp = Sexp.new(:lit, target.value / first_arg.value)
150
151
  end
151
152
  when :[]
152
153
  if array? target
153
- temp_exp = process_array_access target, args[1..-1]
154
+ temp_exp = process_array_access target, exp.args
154
155
  exp = temp_exp if temp_exp
155
156
  elsif hash? target
156
- temp_exp = process_hash_access target, args[1..-1]
157
+ temp_exp = process_hash_access target, exp.args
157
158
  exp = temp_exp if temp_exp
158
159
  end
159
160
  when :merge!, :update
160
- if hash? target and hash? args[1]
161
- target = process_hash_merge! target, args[1]
161
+ if hash? target and hash? first_arg
162
+ target = process_hash_merge! target, first_arg
162
163
  env[target_var] = target
163
164
  return target
164
165
  end
165
166
  when :merge
166
- if hash? target and hash? args[1]
167
- return process_hash_merge(target, args[1])
167
+ if hash? target and hash? first_arg
168
+ return process_hash_merge(target, first_arg)
168
169
  end
169
170
  when :<<
170
- if string? target and string? args[1]
171
- target[1] << args[1][1]
171
+ if string? target and string? first_arg
172
+ target.value << first_arg.value
172
173
  env[target_var] = target
173
174
  return target
174
175
  elsif array? target
175
- target << args[1]
176
+ target << first_arg
176
177
  env[target_var] = target
177
178
  return target
178
179
  else
@@ -187,7 +188,7 @@ class Brakeman::AliasProcessor < Brakeman::SexpProcessor
187
188
  #Process a new scope.
188
189
  def process_scope exp
189
190
  env.scope do
190
- process exp[1]
191
+ process exp.block
191
192
  end
192
193
  exp
193
194
  end
@@ -203,7 +204,7 @@ class Brakeman::AliasProcessor < Brakeman::SexpProcessor
203
204
  def process_methdef exp
204
205
  env.scope do
205
206
  set_env_defaults
206
- process exp[3]
207
+ process exp.body
207
208
  end
208
209
  exp
209
210
  end
@@ -212,7 +213,7 @@ class Brakeman::AliasProcessor < Brakeman::SexpProcessor
212
213
  def process_selfdef exp
213
214
  env.scope do
214
215
  set_env_defaults
215
- process exp[4]
216
+ process exp.body
216
217
  end
217
218
  exp
218
219
  end
@@ -223,18 +224,18 @@ class Brakeman::AliasProcessor < Brakeman::SexpProcessor
223
224
  #Local assignment
224
225
  # x = 1
225
226
  def process_lasgn exp
226
- exp[2] = process exp[2] if sexp? exp[2]
227
- return exp if exp[2].nil?
227
+ exp.rhs = process exp.rhs if sexp? exp.rhs
228
+ return exp if exp.rhs.nil?
228
229
 
229
- local = Sexp.new(:lvar, exp[1]).line(exp.line || -2)
230
+ local = Sexp.new(:lvar, exp.lhs).line(exp.line || -2)
230
231
 
231
232
  if @inside_if and val = env[local]
232
233
  #avoid setting to value it already is (e.g. "1 or 1")
233
- if val != exp[2] and val[1] != exp[2] and val[2] != exp[2]
234
- env[local] = Sexp.new(:or, val, exp[2]).line(exp.line || -2)
234
+ if val != exp.rhs and val[1] != exp.rhs and val[2] != exp.rhs
235
+ env[local] = Sexp.new(:or, val, exp.rhs).line(exp.line || -2)
235
236
  end
236
237
  else
237
- env[local] = exp[2]
238
+ env[local] = exp.rhs
238
239
  end
239
240
 
240
241
  exp
@@ -243,15 +244,15 @@ class Brakeman::AliasProcessor < Brakeman::SexpProcessor
243
244
  #Instance variable assignment
244
245
  # @x = 1
245
246
  def process_iasgn exp
246
- exp[2] = process exp[2]
247
- ivar = Sexp.new(:ivar, exp[1]).line(exp.line)
247
+ exp.rhs = process exp.rhs
248
+ ivar = Sexp.new(:ivar, exp.lhs).line(exp.line)
248
249
 
249
250
  if @inside_if and val = env[ivar]
250
- if val != exp[2]
251
- env[ivar] = Sexp.new(:or, val, exp[2]).line(exp.line)
251
+ if val != exp.rhs
252
+ env[ivar] = Sexp.new(:or, val, exp.rhs).line(exp.line)
252
253
  end
253
254
  else
254
- env[ivar] = exp[2]
255
+ env[ivar] = exp.rhs
255
256
  end
256
257
 
257
258
  exp
@@ -260,8 +261,8 @@ class Brakeman::AliasProcessor < Brakeman::SexpProcessor
260
261
  #Global assignment
261
262
  # $x = 1
262
263
  def process_gasgn exp
263
- match = Sexp.new(:gvar, exp[1])
264
- value = exp[2] = process(exp[2])
264
+ match = Sexp.new(:gvar, exp.lhs)
265
+ value = exp.rhs = process(exp.rhs)
265
266
 
266
267
  if @inside_if and val = env[match]
267
268
  if val != value
@@ -277,8 +278,8 @@ class Brakeman::AliasProcessor < Brakeman::SexpProcessor
277
278
  #Class variable assignment
278
279
  # @@x = 1
279
280
  def process_cvdecl exp
280
- match = Sexp.new(:cvar, exp[1])
281
- value = exp[2] = process(exp[2])
281
+ match = Sexp.new(:cvar, exp.lhs)
282
+ value = exp.rhs = process(exp.rhs)
282
283
 
283
284
  if @inside_if and val = env[match]
284
285
  if val != value
@@ -296,13 +297,14 @@ class Brakeman::AliasProcessor < Brakeman::SexpProcessor
296
297
  #or
297
298
  # x[:y] = 1
298
299
  def process_attrasgn exp
299
- tar_variable = exp[1]
300
- target = exp[1] = process(exp[1])
301
- method = exp[2]
300
+ tar_variable = exp.target
301
+ target = exp.target = process(exp.target)
302
+ method = exp.method
303
+ args = exp.args
302
304
 
303
305
  if method == :[]=
304
- index = exp[3][1] = process(exp[3][1])
305
- value = exp[3][2] = process(exp[3][2])
306
+ index = exp.first_arg = process(args.first)
307
+ value = exp.second_arg = process(args.second)
306
308
  match = Sexp.new(:call, target, :[], Sexp.new(:arglist, index))
307
309
  env[match] = value
308
310
 
@@ -310,7 +312,7 @@ class Brakeman::AliasProcessor < Brakeman::SexpProcessor
310
312
  env[tar_variable] = hash_insert target.deep_clone, index, value
311
313
  end
312
314
  elsif method.to_s[-1,1] == "="
313
- value = exp[3][1] = process(exp[3][1])
315
+ value = exp.first_arg = process(args.first)
314
316
  #This is what we'll replace with the value
315
317
  match = Sexp.new(:call, target, method.to_s[0..-2].to_sym, Sexp.new(:arglist))
316
318
 
@@ -397,17 +399,17 @@ class Brakeman::AliasProcessor < Brakeman::SexpProcessor
397
399
  #Constant assignments like
398
400
  # BIG_CONSTANT = 234810983
399
401
  def process_cdecl exp
400
- if sexp? exp[2]
401
- exp[2] = process exp[2]
402
+ if sexp? exp.rhs
403
+ exp.rhs = process exp.rhs
402
404
  end
403
405
 
404
- if exp[1].is_a? Symbol
405
- match = Sexp.new(:const, exp[1])
406
+ if exp.lhs.is_a? Symbol
407
+ match = Sexp.new(:const, exp.lhs)
406
408
  else
407
- match = exp[1]
409
+ match = exp.lhs
408
410
  end
409
411
 
410
- env[match] = exp[2]
412
+ env[match] = exp.rhs
411
413
 
412
414
  exp
413
415
  end
@@ -416,10 +418,10 @@ class Brakeman::AliasProcessor < Brakeman::SexpProcessor
416
418
  def process_if exp
417
419
  @ignore_ifs ||= @tracker && @tracker.options[:ignore_ifs]
418
420
 
419
- condition = process exp[1]
421
+ condition = process exp.condition
420
422
 
421
423
  if true? condition
422
- exps = [exp[2]]
424
+ exps = [exp.then_clause]
423
425
  elsif false? condition
424
426
  exps = exp[3..-1]
425
427
  else
@@ -58,9 +58,9 @@ class Brakeman::BaseProcessor < Brakeman::SexpProcessor
58
58
  #Process an if statement.
59
59
  def process_if exp
60
60
  exp = exp.dup
61
- exp[1] = process exp[1]
62
- exp[2] = process exp[2] if exp[2]
63
- exp[3] = process exp[3] if exp[3]
61
+ exp[1] = process exp.condition
62
+ exp[2] = process exp.then_clause if exp.then_clause
63
+ exp[3] = process exp.else_clause if exp.else_clause
64
64
  exp
65
65
  end
66
66
 
@@ -69,16 +69,16 @@ class Brakeman::BaseProcessor < Brakeman::SexpProcessor
69
69
  #s(:iter, CALL, {:lasgn|:masgn}, BLOCK)
70
70
  def process_iter exp
71
71
  exp = exp.dup
72
- call = process exp[1]
72
+ call = process exp.block_call
73
73
  #deal with assignments somehow
74
- if exp[3]
75
- block = process exp[3]
74
+ if exp.block
75
+ block = process exp.block
76
76
  block = nil if block.empty?
77
77
  else
78
78
  block = nil
79
79
  end
80
80
 
81
- call = Sexp.new(:call_with_block, call, exp[2], block).compact
81
+ call = Sexp.new(:call_with_block, call, exp.block_args, block).compact
82
82
  call.line(exp.line)
83
83
  call
84
84
  end
@@ -90,8 +90,8 @@ class Brakeman::BaseProcessor < Brakeman::SexpProcessor
90
90
  exp.map! do |e|
91
91
  if e.is_a? String
92
92
  e
93
- elsif e[1].is_a? String
94
- e[1]
93
+ elsif e.value.is_a? String
94
+ e.value
95
95
  else
96
96
  res = process e
97
97
  if res.empty?
@@ -126,22 +126,6 @@ class Brakeman::BaseProcessor < Brakeman::SexpProcessor
126
126
  exp
127
127
  end
128
128
 
129
- #Processes an or keyword
130
- def process_or exp
131
- exp = exp.dup
132
- exp[1] = process exp[1]
133
- exp[2] = process exp[2]
134
- exp
135
- end
136
-
137
- #Processes an and keyword
138
- def process_and exp
139
- exp = exp.dup
140
- exp[1] = process exp[1]
141
- exp[2] = process exp[2]
142
- exp
143
- end
144
-
145
129
  #Processes a hash
146
130
  def process_hash exp
147
131
  exp = exp.dup
@@ -171,22 +155,24 @@ class Brakeman::BaseProcessor < Brakeman::SexpProcessor
171
155
  #Processes a local assignment
172
156
  def process_lasgn exp
173
157
  exp = exp.dup
174
- exp[2] = process exp[2]
158
+ exp.rhs = process exp.rhs
175
159
  exp
176
160
  end
177
161
 
162
+ alias :process_iasgn :process_lasgn
163
+
178
164
  #Processes an instance variable assignment
179
165
  def process_iasgn exp
180
166
  exp = exp.dup
181
- exp[2] = process exp[2]
167
+ exp.rhs = process exp.rhs
182
168
  exp
183
169
  end
184
170
 
185
171
  #Processes an attribute assignment, which can be either x.y = 1 or x[:y] = 1
186
172
  def process_attrasgn exp
187
173
  exp = exp.dup
188
- exp[1] = process exp[1]
189
- exp[3] = process exp[3]
174
+ exp.target = process exp.target
175
+ exp.arglist = process exp.arglist
190
176
  exp
191
177
  end
192
178
 
@@ -202,7 +188,7 @@ class Brakeman::BaseProcessor < Brakeman::SexpProcessor
202
188
 
203
189
  #Generates :render node from call to render.
204
190
  def make_render exp, in_view = false
205
- render_type, value, rest = find_render_type exp[3], in_view
191
+ render_type, value, rest = find_render_type exp.args, in_view
206
192
  rest = process rest
207
193
  result = Sexp.new(:render, render_type, value, rest)
208
194
  result.line(exp.line)
@@ -220,28 +206,29 @@ class Brakeman::BaseProcessor < Brakeman::SexpProcessor
220
206
  rest = Sexp.new(:hash)
221
207
  type = nil
222
208
  value = nil
209
+ first_arg = args.first
223
210
 
224
- if args.length == 2 and args[-1] == Sexp.new(:lit, :update)
225
- return :update, nil, args[0..-2]
211
+ if args.length == 1 and first_arg == Sexp.new(:lit, :update)
212
+ return :update, nil, Sexp.new(:arglist, *args[0..-2]) #TODO HUH?
226
213
  end
227
214
 
228
215
  #Look for render :action, ... or render "action", ...
229
- if string? args[1] or symbol? args[1]
216
+ if string? first_arg or symbol? first_arg
230
217
  if @current_template and @tracker.options[:rails3]
231
218
  type = :partial
232
- value = args[1]
219
+ value = first_arg
233
220
  else
234
221
  type = :action
235
- value = args[1]
222
+ value = first_arg
236
223
  end
237
- elsif args[1].is_a? Symbol or args[1].is_a? String
224
+ elsif first_arg.is_a? Symbol or first_arg.is_a? String
238
225
  type = :action
239
- value = Sexp.new(:lit, args[1].to_sym)
240
- elsif args[1].nil?
226
+ value = Sexp.new(:lit, first_arg.to_sym)
227
+ elsif first_arg.nil?
241
228
  type = :default
242
- elsif not hash? args[1]
229
+ elsif not hash? first_arg
243
230
  type = :action
244
- value = args[1]
231
+ value = first_arg
245
232
  end
246
233
 
247
234
  types_in_hash = Set[:action, :file, :inline, :js, :json, :nothing, :partial, :template, :text, :update, :xml]
@@ -253,10 +240,10 @@ class Brakeman::BaseProcessor < Brakeman::SexpProcessor
253
240
 
254
241
  #Look for "type" of render in options hash
255
242
  #For example, render :file => "blah"
256
- if hash? args[-1]
257
- hash_iterate(args[-1]) do |key, val|
258
- if types_in_hash.include? key[1]
259
- type = key[1]
243
+ if hash? args.last
244
+ hash_iterate(args.last) do |key, val|
245
+ if symbol? key and types_in_hash.include? key.value
246
+ type = key.value
260
247
  value = val
261
248
  else
262
249
  rest << key << val
@@ -266,7 +253,6 @@ class Brakeman::BaseProcessor < Brakeman::SexpProcessor
266
253
 
267
254
  type ||= :default
268
255
  value ||= :default
269
- args[-1] = rest
270
256
  return type, value, rest
271
257
  end
272
258
  end