brakeman 3.3.2 → 3.3.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGES +13 -0
  3. data/lib/brakeman/app_tree.rb +6 -1
  4. data/lib/brakeman/checks/base_check.rb +10 -0
  5. data/lib/brakeman/checks/check_create_with.rb +1 -2
  6. data/lib/brakeman/checks/check_cross_site_scripting.rb +0 -4
  7. data/lib/brakeman/checks/check_deserialize.rb +1 -2
  8. data/lib/brakeman/checks/check_dynamic_finders.rb +1 -2
  9. data/lib/brakeman/checks/check_evaluation.rb +1 -2
  10. data/lib/brakeman/checks/check_execute.rb +2 -5
  11. data/lib/brakeman/checks/check_file_access.rb +1 -2
  12. data/lib/brakeman/checks/check_link_to_href.rb +13 -3
  13. data/lib/brakeman/checks/check_mass_assignment.rb +2 -4
  14. data/lib/brakeman/checks/check_redirect.rb +1 -4
  15. data/lib/brakeman/checks/check_regex_dos.rb +1 -2
  16. data/lib/brakeman/checks/check_render.rb +10 -5
  17. data/lib/brakeman/checks/check_render_inline.rb +1 -2
  18. data/lib/brakeman/checks/check_select_tag.rb +1 -2
  19. data/lib/brakeman/checks/check_send.rb +1 -2
  20. data/lib/brakeman/checks/check_session_manipulation.rb +1 -2
  21. data/lib/brakeman/checks/check_simple_format.rb +1 -2
  22. data/lib/brakeman/checks/check_ssl_verify.rb +1 -2
  23. data/lib/brakeman/checks/check_symbol_dos.rb +2 -4
  24. data/lib/brakeman/checks/check_unsafe_reflection.rb +1 -2
  25. data/lib/brakeman/checks/check_weak_hash.rb +3 -6
  26. data/lib/brakeman/parsers/template_parser.rb +9 -0
  27. data/lib/brakeman/processors/base_processor.rb +25 -0
  28. data/lib/brakeman/processors/controller_processor.rb +6 -99
  29. data/lib/brakeman/processors/erb_template_processor.rb +1 -4
  30. data/lib/brakeman/processors/erubis_template_processor.rb +4 -16
  31. data/lib/brakeman/processors/haml_template_processor.rb +4 -11
  32. data/lib/brakeman/processors/lib/find_all_calls.rb +13 -25
  33. data/lib/brakeman/processors/lib/find_return_value.rb +34 -4
  34. data/lib/brakeman/processors/lib/module_helper.rb +111 -0
  35. data/lib/brakeman/processors/lib/render_helper.rb +1 -1
  36. data/lib/brakeman/processors/library_processor.rb +4 -57
  37. data/lib/brakeman/processors/model_processor.rb +4 -104
  38. data/lib/brakeman/processors/slim_template_processor.rb +7 -21
  39. data/lib/brakeman/processors/template_processor.rb +11 -0
  40. data/lib/brakeman/scanner.rb +1 -1
  41. data/lib/brakeman/version.rb +1 -1
  42. data/lib/ruby_parser/bm_sexp.rb +7 -3
  43. metadata +4 -3
@@ -1,8 +1,11 @@
1
1
  require 'brakeman/processors/base_processor'
2
+ require 'brakeman/processors/lib/module_helper'
2
3
  require 'brakeman/tracker/controller'
3
4
 
4
5
  #Processes controller. Results are put in tracker.controllers
5
6
  class Brakeman::ControllerProcessor < Brakeman::BaseProcessor
7
+ include Brakeman::ModuleHelper
8
+
6
9
  FORMAT_HTML = Sexp.new(:call, Sexp.new(:lvar, :format), :html)
7
10
 
8
11
  def initialize app_tree, tracker
@@ -47,64 +50,15 @@ class Brakeman::ControllerProcessor < Brakeman::BaseProcessor
47
50
  return exp
48
51
  end
49
52
 
50
- if @current_class
51
- outer_class = @current_class
52
- name = (outer_class.name.to_s + "::" + name.to_s).to_sym
53
- end
54
-
55
- if @current_module
56
- name = (@current_module.name.to_s + "::" + name.to_s).to_sym
57
- end
58
-
59
- if @tracker.controllers[name]
60
- @current_class = @tracker.controllers[name]
61
- @current_class.add_file @file_name, exp
62
- else
63
- @current_class = Brakeman::Controller.new name, parent, @file_name, exp, @tracker
64
- @tracker.controllers[name] = @current_class
65
- end
66
-
67
- exp.body = process_all! exp.body
68
- set_layout_name
69
-
70
- if outer_class
71
- @current_class = outer_class
72
- else
73
- @current_class = nil
53
+ handle_class(exp, @tracker.controllers, Brakeman::Controller) do
54
+ set_layout_name
74
55
  end
75
56
 
76
57
  exp
77
58
  end
78
59
 
79
60
  def process_module exp, parent = nil
80
- name = class_name(exp.module_name)
81
-
82
- if @current_module
83
- outer_module = @current_module
84
- name = (outer_module.name.to_s + "::" + name.to_s).to_sym
85
- end
86
-
87
- if @current_class
88
- name = (@current_class.name.to_s + "::" + name.to_s).to_sym
89
- end
90
-
91
- if @tracker.libs[name]
92
- @current_module = @tracker.libs[name]
93
- @current_module.add_file @file_name, exp
94
- else
95
- @current_module = Brakeman::Controller.new name, parent, @file_name, exp, @tracker
96
- @tracker.libs[name] = @current_module
97
- end
98
-
99
- exp.body = process_all! exp.body
100
-
101
- if outer_module
102
- @current_module = outer_module
103
- else
104
- @current_module = nil
105
- end
106
-
107
- exp
61
+ handle_module exp, Brakeman::Controller, parent
108
62
  end
109
63
 
110
64
  #Look for specific calls inside the controller
@@ -187,53 +141,6 @@ class Brakeman::ControllerProcessor < Brakeman::BaseProcessor
187
141
  end
188
142
  end
189
143
 
190
- #Process method definition and store in Tracker
191
- def process_defn exp
192
- name = exp.method_name
193
- @current_method = name
194
- res = Sexp.new :defn, name, exp.formal_args, *process_all!(exp.body)
195
- res.line(exp.line)
196
- @current_method = nil
197
-
198
- if @current_class
199
- @current_class.add_method @visibility, name, res, @file_name
200
- elsif @current_module
201
- @current_module.add_method @visibility, name, res, @file_name
202
- end
203
-
204
- res
205
- end
206
-
207
- #Process self.method definition and store in Tracker
208
- def process_defs exp
209
- name = exp.method_name
210
-
211
- if node_type? exp[1], :self
212
- if @current_class
213
- target = @current_class.name
214
- elsif @current_module
215
- target = @current_module.name
216
- else
217
- target = nil
218
- end
219
- else
220
- target = class_name exp[1]
221
- end
222
-
223
- @current_method = name
224
- res = Sexp.new :defs, target, name, exp.formal_args, *process_all!(exp.body)
225
- res.line(exp.line)
226
- @current_method = nil
227
-
228
- if @current_class
229
- @current_class.add_method @visibility, name, res, @file_name
230
- elsif @current_module
231
- @current_module.add_method @visibility, name, res, @file_name
232
- end
233
-
234
- res
235
- end
236
-
237
144
  #Look for before_filters and add fake ones if necessary
238
145
  def process_iter exp
239
146
  if @current_method.nil? and call? exp.block_call
@@ -28,10 +28,7 @@ class Brakeman::ErbTemplateProcessor < Brakeman::TemplateProcessor
28
28
  if arg.node_type == :str #ignore plain strings
29
29
  ignore
30
30
  else
31
- s = Sexp.new :output, arg
32
- s.line(exp.line)
33
- @current_template.add_output s
34
- s
31
+ add_output arg
35
32
  end
36
33
  elsif method == :force_encoding
37
34
  ignore
@@ -23,15 +23,9 @@ class Brakeman::ErubisTemplateProcessor < Brakeman::TemplateProcessor
23
23
  if arg.node_type == :str #ignore plain strings
24
24
  ignore
25
25
  elsif node_type? target, :ivar and target.value == :@output_buffer
26
- s = Sexp.new :escaped_output, arg
27
- s.line(exp.line)
28
- @current_template.add_output s
29
- s
26
+ add_escaped_output arg
30
27
  else
31
- s = Sexp.new :output, arg
32
- s.line(exp.line)
33
- @current_template.add_output s
34
- s
28
+ add_output arg
35
29
  end
36
30
  elsif method == :to_s
37
31
  ignore
@@ -75,15 +69,9 @@ class Brakeman::ErubisTemplateProcessor < Brakeman::TemplateProcessor
75
69
  if arg.node_type == :str
76
70
  ignore
77
71
  elsif safe_append_method?(exp.method)
78
- s = Sexp.new :output, arg
79
- s.line(exp.line)
80
- @current_template.add_output s
81
- s
72
+ add_output arg
82
73
  else
83
- s = Sexp.new :escaped_output, arg
84
- s.line(exp.line)
85
- @current_template.add_output s
86
- s
74
+ add_escaped_output arg
87
75
  end
88
76
  else
89
77
  super
@@ -81,10 +81,7 @@ class Brakeman::HamlTemplateProcessor < Brakeman::TemplateProcessor
81
81
  if out.node_type == :str #ignore plain strings
82
82
  ignore
83
83
  else
84
- s = Sexp.new(:output, out)
85
- @current_template.add_output s
86
- s.line(exp.line)
87
- s
84
+ add_output out
88
85
  end
89
86
  elsif target == nil and method == :render
90
87
  #Process call to render()
@@ -175,16 +172,12 @@ class Brakeman::HamlTemplateProcessor < Brakeman::TemplateProcessor
175
172
  exp.map! { |e| get_pushed_value e }
176
173
  else
177
174
  if call? exp and exp.target == HAML_HELPERS and exp.method == :html_escape
178
- s = Sexp.new(:escaped_output, exp.first_arg)
175
+ add_escaped_output exp.first_arg
179
176
  elsif @javascript and call? exp and (exp.method == :j or exp.method == :escape_javascript)
180
- s = Sexp.new(:escaped_output, exp.first_arg)
177
+ add_escaped_output exp.first_arg
181
178
  else
182
- s = Sexp.new(default, exp)
179
+ add_output exp, default
183
180
  end
184
-
185
- s.line(exp.line)
186
- @current_template.add_output s
187
- s
188
181
  end
189
182
  end
190
183
  end
@@ -28,11 +28,7 @@ class Brakeman::FindAllCalls < Brakeman::BasicProcessor
28
28
  process_all exp.body
29
29
  end
30
30
 
31
- #Process body of method
32
- def process_defs exp
33
- return exp unless @current_method
34
- process_all exp.body
35
- end
31
+ alias process_defs process_defn
36
32
 
37
33
  #Process body of block
38
34
  def process_rlist exp
@@ -70,11 +66,7 @@ class Brakeman::FindAllCalls < Brakeman::BasicProcessor
70
66
  def process_render exp
71
67
  process exp.last if sexp? exp.last
72
68
 
73
- @calls << { :target => nil,
74
- :method => :render,
75
- :call => exp,
76
- :nested => false,
77
- :location => make_location }
69
+ add_simple_call :render, exp
78
70
 
79
71
  exp
80
72
  end
@@ -84,11 +76,7 @@ class Brakeman::FindAllCalls < Brakeman::BasicProcessor
84
76
  def process_dxstr exp
85
77
  process exp.last if sexp? exp.last
86
78
 
87
- @calls << { :target => nil,
88
- :method => :`,
89
- :call => exp,
90
- :nested => false,
91
- :location => make_location }
79
+ add_simple_call :`, exp
92
80
 
93
81
  exp
94
82
  end
@@ -97,11 +85,7 @@ class Brakeman::FindAllCalls < Brakeman::BasicProcessor
97
85
  def process_dsym exp
98
86
  exp.each { |arg| process arg if sexp? arg }
99
87
 
100
- @calls << { :target => nil,
101
- :method => :literal_to_sym,
102
- :call => exp,
103
- :nested => false,
104
- :location => make_location }
88
+ add_simple_call :literal_to_sym, exp
105
89
 
106
90
  exp
107
91
  end
@@ -110,11 +94,7 @@ class Brakeman::FindAllCalls < Brakeman::BasicProcessor
110
94
  def process_dregx exp
111
95
  exp.each { |arg| process arg if sexp? arg }
112
96
 
113
- @calls << { :target => nil,
114
- :method => :brakeman_regex_interp,
115
- :call => exp,
116
- :nested => false,
117
- :location => make_location }
97
+ add_simple_call :brakeman_regex_interp, exp
118
98
 
119
99
  exp
120
100
  end
@@ -126,6 +106,14 @@ class Brakeman::FindAllCalls < Brakeman::BasicProcessor
126
106
 
127
107
  private
128
108
 
109
+ def add_simple_call method_name, exp
110
+ @calls << { :target => nil,
111
+ :method => method_name,
112
+ :call => exp,
113
+ :nested => false,
114
+ :location => make_location }
115
+ end
116
+
129
117
  #Gets the target of a call as a Symbol
130
118
  #if possible
131
119
  def get_target exp, include_calls = false
@@ -65,7 +65,7 @@ class Brakeman::FindReturnValue
65
65
  @uses_ivars = true if node_type? current, :ivar
66
66
 
67
67
  if node_type? current, :return
68
- @return_values << current.value unless current.value.nil?
68
+ @return_values << last_value(current.value) if current.value
69
69
  elsif sexp? current
70
70
  todo = current[1..-1].concat todo
71
71
  end
@@ -97,10 +97,40 @@ class Brakeman::FindReturnValue
97
97
  true_branch or false_branch
98
98
  end
99
99
  end
100
- when :lasgn, :iasgn
101
- exp.rhs
100
+ when :lasgn, :iasgn, :op_asgn_or, :attrasgn
101
+ last_value exp.rhs
102
+ when :rescue
103
+ values = []
104
+
105
+ exp.each_sexp do |e|
106
+ if node_type? e, :resbody
107
+ if e.last
108
+ values << last_value(e.last)
109
+ end
110
+ elsif sexp? e
111
+ values << last_value(e)
112
+ end
113
+ end
114
+
115
+ values.reject! do |v|
116
+ v.nil? or node_type? v, :nil
117
+ end
118
+
119
+ if values.length > 1
120
+ values.inject do |m, v|
121
+ make_or(m, v)
122
+ end
123
+ else
124
+ values.first
125
+ end
102
126
  when :return
103
- exp.value
127
+ if exp.value
128
+ last_value exp.value
129
+ else
130
+ nil
131
+ end
132
+ when :nil
133
+ nil
104
134
  else
105
135
  exp.original_line = exp.line unless exp.original_line
106
136
  exp
@@ -0,0 +1,111 @@
1
+ module Brakeman::ModuleHelper
2
+ def handle_module exp, tracker_class, parent = nil
3
+ name = class_name(exp.module_name)
4
+
5
+ if @current_module
6
+ outer_module = @current_module
7
+ name = (outer_module.name.to_s + "::" + name.to_s).to_sym
8
+ end
9
+
10
+ if @current_class
11
+ name = (@current_class.name.to_s + "::" + name.to_s).to_sym
12
+ end
13
+
14
+ if @tracker.libs[name]
15
+ @current_module = @tracker.libs[name]
16
+ @current_module.add_file @file_name, exp
17
+ else
18
+ @current_module = tracker_class.new name, parent, @file_name, exp, @tracker
19
+ @tracker.libs[name] = @current_module
20
+ end
21
+
22
+ exp.body = process_all! exp.body
23
+
24
+ if outer_module
25
+ @current_module = outer_module
26
+ else
27
+ @current_module = nil
28
+ end
29
+
30
+ exp
31
+ end
32
+
33
+ def handle_class exp, collection, tracker_class
34
+ name = class_name(exp.class_name)
35
+ parent = class_name exp.parent_name
36
+
37
+ if @current_class
38
+ outer_class = @current_class
39
+ name = (outer_class.name.to_s + "::" + name.to_s).to_sym
40
+ end
41
+
42
+ if @current_module
43
+ name = (@current_module.name.to_s + "::" + name.to_s).to_sym
44
+ end
45
+
46
+ if collection[name]
47
+ @current_class = collection[name]
48
+ @current_class.add_file @file_name, exp
49
+ else
50
+ @current_class = tracker_class.new name, parent, @file_name, exp, @tracker
51
+ collection[name] = @current_class
52
+ end
53
+
54
+ exp.body = process_all! exp.body
55
+
56
+ yield if block_given?
57
+
58
+ if outer_class
59
+ @current_class = outer_class
60
+ else
61
+ @current_class = nil
62
+ end
63
+
64
+ exp
65
+ end
66
+
67
+ def process_defs exp
68
+ name = exp.method_name
69
+
70
+ if node_type? exp[1], :self
71
+ if @current_class
72
+ target = @current_class.name
73
+ elsif @current_module
74
+ target = @current_module.name
75
+ else
76
+ target = nil
77
+ end
78
+ else
79
+ target = class_name exp[1]
80
+ end
81
+
82
+ @current_method = name
83
+ res = Sexp.new :defs, target, name, exp.formal_args, *process_all!(exp.body)
84
+ res.line(exp.line)
85
+ @current_method = nil
86
+
87
+ if @current_class
88
+ @current_class.add_method @visibility, name, res, @file_name
89
+ elsif @current_module
90
+ @current_module.add_method @visibility, name, res, @file_name
91
+ end
92
+ res
93
+ end
94
+
95
+ def process_defn exp
96
+ name = exp.method_name
97
+
98
+ @current_method = name
99
+ res = Sexp.new :defn, name, exp.formal_args, *process_all!(exp.body)
100
+ res.line(exp.line)
101
+ @current_method = nil
102
+
103
+ if @current_class
104
+ @current_class.add_method @visibility, name, res, @file_name
105
+ elsif @current_module
106
+ @current_module.add_method @visibility, name, res, @file_name
107
+ end
108
+
109
+ res
110
+ end
111
+ end