brakeman-lib 3.3.2 → 3.3.3

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 (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