brakeman 1.6.2 → 1.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (33) hide show
  1. data/lib/brakeman/checks.rb +14 -5
  2. data/lib/brakeman/checks/base_check.rb +19 -7
  3. data/lib/brakeman/checks/check_digest_dos.rb +37 -0
  4. data/lib/brakeman/checks/check_escape_function.rb +2 -1
  5. data/lib/brakeman/checks/check_file_access.rb +40 -23
  6. data/lib/brakeman/checks/check_filter_skipping.rb +2 -1
  7. data/lib/brakeman/checks/check_forgery_setting.rb +7 -4
  8. data/lib/brakeman/checks/check_link_to.rb +6 -3
  9. data/lib/brakeman/checks/check_link_to_href.rb +4 -2
  10. data/lib/brakeman/checks/check_nested_attributes.rb +3 -2
  11. data/lib/brakeman/checks/check_quote_table_name.rb +2 -1
  12. data/lib/brakeman/checks/check_response_splitting.rb +2 -1
  13. data/lib/brakeman/checks/check_sql.rb +10 -7
  14. data/lib/brakeman/checks/check_strip_tags.rb +2 -1
  15. data/lib/brakeman/checks/check_validation_regex.rb +1 -1
  16. data/lib/brakeman/checks/check_without_protection.rb +2 -9
  17. data/lib/brakeman/format/style.css +4 -0
  18. data/lib/brakeman/processors/alias_processor.rb +10 -10
  19. data/lib/brakeman/processors/base_processor.rb +4 -11
  20. data/lib/brakeman/processors/controller_processor.rb +9 -1
  21. data/lib/brakeman/processors/lib/rails3_route_processor.rb +96 -31
  22. data/lib/brakeman/processors/lib/render_helper.rb +3 -2
  23. data/lib/brakeman/processors/lib/route_helper.rb +21 -0
  24. data/lib/brakeman/processors/library_processor.rb +10 -1
  25. data/lib/brakeman/processors/model_processor.rb +8 -1
  26. data/lib/brakeman/processors/template_processor.rb +0 -1
  27. data/lib/brakeman/report.rb +10 -0
  28. data/lib/brakeman/scanner.rb +2 -0
  29. data/lib/brakeman/util.rb +1 -2
  30. data/lib/brakeman/version.rb +1 -1
  31. data/lib/brakeman/warning.rb +19 -1
  32. data/lib/ruby_parser/bm_sexp_processor.rb +231 -0
  33. metadata +81 -79
@@ -14,17 +14,10 @@ class Brakeman::CheckWithoutProtection < Brakeman::BaseCheck
14
14
  return
15
15
  end
16
16
 
17
- models = []
18
- tracker.models.each do |name, m|
19
- if ancestor? m, :"ActiveRecord::Base"
20
- models << name
21
- end
22
- end
23
-
24
- return if models.empty?
17
+ return if active_record_models.empty?
25
18
 
26
19
  Brakeman.debug "Finding all mass assignments"
27
- calls = tracker.find_call :targets => models, :methods => [:new,
20
+ calls = tracker.find_call :targets => active_record_models.keys, :methods => [:new,
28
21
  :attributes=,
29
22
  :update_attributes,
30
23
  :update_attributes!,
@@ -5,6 +5,10 @@ body {
5
5
  color: #161616;
6
6
  }
7
7
 
8
+ a {
9
+ color: #161616;
10
+ }
11
+
8
12
  p {
9
13
  font-weight: bold;
10
14
  font-size: 11pt;
@@ -1,12 +1,11 @@
1
- require 'rubygems'
2
- require 'sexp_processor'
3
1
  require 'brakeman/util'
2
+ require 'ruby_parser/bm_sexp_processor'
4
3
  require 'brakeman/processors/lib/processor_helper'
5
4
 
6
5
  #Returns an s-expression with aliases replaced with their value.
7
6
  #This does not preserve semantics (due to side effects, etc.), but it makes
8
7
  #processing easier when searching for various things.
9
- class Brakeman::AliasProcessor < SexpProcessor
8
+ class Brakeman::AliasProcessor < Brakeman::SexpProcessor
10
9
  include Brakeman::ProcessorHelper
11
10
  include Brakeman::Util
12
11
 
@@ -19,11 +18,6 @@ class Brakeman::AliasProcessor < SexpProcessor
19
18
  # AliasProcessor.new.process_safely src
20
19
  def initialize tracker = nil
21
20
  super()
22
- self.strict = false
23
- self.auto_shift_type = false
24
- self.require_empty = false
25
- self.default_method = :process_default
26
- self.warn_on_default = false
27
21
  @env = SexpProcessor::Environment.new
28
22
  @inside_if = false
29
23
  @ignore_ifs = false
@@ -368,7 +362,11 @@ class Brakeman::AliasProcessor < SexpProcessor
368
362
  match = Sexp.new(:call, target, :[], Sexp.new(:arglist, index))
369
363
 
370
364
  unless env[match]
371
- env[match] = value
365
+ if request_value? target
366
+ env[match] = Sexp.new(:or, match, value)
367
+ else
368
+ env[match] = value
369
+ end
372
370
  end
373
371
 
374
372
  exp
@@ -452,7 +450,9 @@ class Brakeman::AliasProcessor < SexpProcessor
452
450
  def process_array_access target, args
453
451
  if args.length == 1 and integer? args[0]
454
452
  index = args[0][1]
455
- target[index + 1]
453
+
454
+ #Have to do this because first element is :array and we have to skip it
455
+ target[1..-1][index + 1]
456
456
  else
457
457
  nil
458
458
  end
@@ -1,10 +1,8 @@
1
- require 'rubygems'
2
- require 'sexp_processor'
3
1
  require 'brakeman/processors/lib/processor_helper'
4
2
  require 'brakeman/util'
5
3
 
6
4
  #Base processor for most processors.
7
- class Brakeman::BaseProcessor < SexpProcessor
5
+ class Brakeman::BaseProcessor < Brakeman::SexpProcessor
8
6
  include Brakeman::ProcessorHelper
9
7
  include Brakeman::Util
10
8
 
@@ -13,11 +11,6 @@ class Brakeman::BaseProcessor < SexpProcessor
13
11
  #Return a new Processor.
14
12
  def initialize tracker
15
13
  super()
16
- self.strict = false
17
- self.auto_shift_type = false
18
- self.require_empty = false
19
- self.default_method = :process_default
20
- self.warn_on_default = false
21
14
  @last = nil
22
15
  @tracker = tracker
23
16
  @ignore = Sexp.new :ignore
@@ -50,7 +43,7 @@ class Brakeman::BaseProcessor < SexpProcessor
50
43
  #Default processing.
51
44
  def process_default exp
52
45
  exp = exp.dup
53
- type = exp.shift
46
+
54
47
  exp.each_with_index do |e, i|
55
48
  if sexp? e and not e.empty?
56
49
  exp[i] = process e
@@ -58,8 +51,8 @@ class Brakeman::BaseProcessor < SexpProcessor
58
51
  e
59
52
  end
60
53
  end
61
- ensure
62
- exp.unshift type
54
+
55
+ exp
63
56
  end
64
57
 
65
58
  #Process an if statement.
@@ -30,8 +30,16 @@ class Brakeman::ControllerProcessor < Brakeman::BaseProcessor
30
30
  if @current_module
31
31
  name = (@current_module.to_s + "::" + name.to_s).to_sym
32
32
  end
33
+
34
+ begin
35
+ parent = class_name exp[2]
36
+ rescue StandardError => e
37
+ Brakeman.debug e
38
+ parent = nil
39
+ end
40
+
33
41
  @controller = { :name => name,
34
- :parent => class_name(exp[2]),
42
+ :parent => parent,
35
43
  :includes => [],
36
44
  :public => {},
37
45
  :private => {},
@@ -14,6 +14,7 @@ class Brakeman::Rails3RoutesProcessor < Brakeman::BaseProcessor
14
14
  @prefix = [] #Controller name prefix (a module name, usually)
15
15
  @current_controller = nil
16
16
  @with_options = nil #For use inside map.with_options
17
+ @controller_block = false
17
18
  end
18
19
 
19
20
  def process_routes exp
@@ -49,6 +50,8 @@ class Brakeman::Rails3RoutesProcessor < Brakeman::BaseProcessor
49
50
  process_resources_block exp
50
51
  when :scope
51
52
  process_scope_block exp
53
+ when :controller
54
+ process_controller_block exp
52
55
  else
53
56
  super
54
57
  end
@@ -71,11 +74,8 @@ class Brakeman::Rails3RoutesProcessor < Brakeman::BaseProcessor
71
74
  args = exp[3][1..-1]
72
75
 
73
76
  if value = hash_access(args[0], :to)
74
- if string? value[1]
75
- controller, action = extract_action v[1]
76
-
77
- self.current_controller = controller
78
- @tracker.routes[@current_controller] << action.to_sym
77
+ if string? value
78
+ add_route_from_string value
79
79
  end
80
80
  end
81
81
 
@@ -97,19 +97,36 @@ class Brakeman::Rails3RoutesProcessor < Brakeman::BaseProcessor
97
97
  return exp
98
98
  elsif matcher.include? ':action'
99
99
  action_variable = true
100
+ elsif args[1].nil? and in_controller_block? and not matcher.include? ":"
101
+ add_route matcher
100
102
  end
101
103
  end
102
104
 
103
105
  if hash? args[-1]
104
106
  hash_iterate args[-1] do |k, v|
105
- if string? k and string? v
106
- controller, action = extract_action v[1]
107
+ if string? k
108
+ if string? v
109
+ add_route_from_string v[1]
110
+ elsif in_controller_block? and symbol? v
111
+ add_route v
112
+ end
113
+ elsif symbol? k
114
+ case k[1]
115
+ when :action
116
+ if string? v
117
+ add_route_from_string v
118
+ else
119
+ add_route v
120
+ end
107
121
 
108
- self.current_controller = controller
109
- @tracker.routes[@current_controller] << action.to_sym if action
110
- elsif symbol? k and k[1] == :action
111
- @tracker.routes[@current_controller] << v[1].to_sym
112
122
  action_variable = false
123
+ when :to
124
+ if string? v
125
+ add_route_from_string v[1]
126
+ elsif in_controller_block? and symbol? v
127
+ add_route v
128
+ end
129
+ end
113
130
  end
114
131
  end
115
132
  end
@@ -118,44 +135,59 @@ class Brakeman::Rails3RoutesProcessor < Brakeman::BaseProcessor
118
135
  @tracker.routes[@current_controller] = :allow_all_actions
119
136
  end
120
137
 
138
+ @current_controller = nil unless in_controller_block?
121
139
  exp
122
140
  end
123
141
 
142
+ def add_route_from_string value
143
+ value = value[1] if string? value
144
+
145
+ controller, action = extract_action value
146
+
147
+ if action
148
+ add_route action, controller
149
+ elsif in_controller_block?
150
+ add_route value
151
+ end
152
+ end
153
+
124
154
  def process_verb exp
125
155
  args = exp[3][1..-1]
126
156
 
127
157
  if symbol? args[0] and not hash? args[1]
128
- @tracker.routes[@current_controller] << args[0][1]
158
+ add_route args[0]
129
159
  elsif hash? args[1]
130
160
  hash_iterate args[1] do |k, v|
131
- if symbol? k and k[1] == :to and string? v
132
- controller, action = extract_action v[1]
133
-
134
- self.current_controller = controller
135
- @tracker.routes[@current_controller] << action.to_sym
161
+ if symbol? k and k[1] == :to
162
+ if string? v
163
+ add_route_from_string v[1]
164
+ elsif in_controller_block? and symbol? v
165
+ add_route v
166
+ end
136
167
  end
137
168
  end
138
169
  elsif string? args[0]
139
170
  route = args[0][1].split "/"
140
171
  if route.length != 2
141
- @tracker.routes[@current_controller] << route[0].to_sym
172
+ add_route route[0]
142
173
  else
143
- self.current_controller = route[0]
144
- @tracker.routes[@current_controller] << route[1].to_sym
145
- @current_controller = nil
174
+ add_route route[1], route[0]
146
175
  end
176
+ elsif in_controller_block? and symbol? args[0]
177
+ add_route args[0]
147
178
  else hash? args[0]
148
179
  hash_iterate args[0] do |k, v|
149
- if string? v
150
- controller, action = extract_action v[1]
151
-
152
- self.current_controller = controller
153
- @tracker.routes[@current_controller] << action.to_sym
154
- break
180
+ if string? k
181
+ if string? v
182
+ add_route_from_string v
183
+ elsif in_controller_block?
184
+ add_route v
185
+ end
155
186
  end
156
187
  end
157
188
  end
158
189
 
190
+ @current_controller = nil unless in_controller_block?
159
191
  exp
160
192
  end
161
193
 
@@ -171,6 +203,7 @@ class Brakeman::Rails3RoutesProcessor < Brakeman::BaseProcessor
171
203
  end
172
204
  end
173
205
 
206
+ @current_controller = nil unless in_controller_block?
174
207
  exp
175
208
  end
176
209
 
@@ -186,18 +219,27 @@ class Brakeman::Rails3RoutesProcessor < Brakeman::BaseProcessor
186
219
  end
187
220
  end
188
221
 
222
+ @current_controller = nil unless in_controller_block?
189
223
  exp
190
224
  end
191
225
 
192
226
  def process_resources_block exp
193
- process_resources exp[1]
194
- process exp[3]
227
+ in_controller_block do
228
+ process_resources exp[1]
229
+ process exp[3]
230
+ end
231
+
232
+ @current_controller = nil
195
233
  exp
196
234
  end
197
235
 
198
236
  def process_resource_block exp
199
- process_resource exp[1]
200
- process exp[3]
237
+ in_controller_block do
238
+ process_resource exp[1]
239
+ process exp[3]
240
+ end
241
+
242
+ @current_controller = nil
201
243
  exp
202
244
  end
203
245
 
@@ -207,7 +249,30 @@ class Brakeman::Rails3RoutesProcessor < Brakeman::BaseProcessor
207
249
  exp
208
250
  end
209
251
 
252
+ def process_controller_block exp
253
+ args = exp[1][3]
254
+ self.current_controller = args[1][1]
255
+
256
+ in_controller_block do
257
+ process exp[-1] if exp[-1]
258
+ end
259
+
260
+ @current_controller = nil
261
+ exp
262
+ end
263
+
210
264
  def extract_action str
211
265
  str.split "#"
212
266
  end
267
+
268
+ def in_controller_block?
269
+ @controller_block
270
+ end
271
+
272
+ def in_controller_block
273
+ prev_block = @controller_block
274
+ @controller_block = true
275
+ yield
276
+ @controller_block = prev_block
277
+ end
213
278
  end
@@ -15,7 +15,6 @@ module Brakeman::RenderHelper
15
15
  process_template template_name, exp[3]
16
16
  rescue ArgumentError => e
17
17
  Brakeman.debug "Problem processing render: #{exp}"
18
- raise e
19
18
  end
20
19
  when :partial, :layout
21
20
  process_partial exp[2], exp[3]
@@ -48,7 +47,9 @@ module Brakeman::RenderHelper
48
47
 
49
48
  #Processes a given action
50
49
  def process_action name, args
51
- process_template template_name(name), args
50
+ if name.is_a? String or name.is_a? Symbol
51
+ process_template template_name(name), args
52
+ end
52
53
  end
53
54
 
54
55
  #Processes a template, adding any instance variables
@@ -21,6 +21,27 @@ module Brakeman::RouteHelper
21
21
  @tracker.routes[@current_controller] ||= Set.new
22
22
  end
23
23
 
24
+ #Add route to controller. If a controller is specified,
25
+ #the current controller will be set to that controller.
26
+ #If no controller is specified, uses current controller value.
27
+ def add_route route, controller = nil
28
+ if node_type? route, :str, :lit
29
+ route = route[1]
30
+ end
31
+
32
+ route = route.to_sym
33
+
34
+ if controller
35
+ self.current_controller = controller
36
+ end
37
+
38
+ routes = @tracker.routes[@current_controller]
39
+
40
+ if routes and routes != :allow_all_actions
41
+ routes << route
42
+ end
43
+ end
44
+
24
45
  #Add default routes
25
46
  def add_resources_routes
26
47
  existing_routes = @tracker.routes[@current_controller]
@@ -30,8 +30,15 @@ class Brakeman::LibraryProcessor < Brakeman::BaseProcessor
30
30
  if @tracker.libs[name]
31
31
  @current_class = @tracker.libs[name]
32
32
  else
33
+ begin
34
+ parent = class_name exp[2]
35
+ rescue StandardError => e
36
+ Brakeman.debug e
37
+ parent = nil
38
+ end
39
+
33
40
  @current_class = { :name => name,
34
- :parent => class_name(exp[2]),
41
+ :parent => parent,
35
42
  :includes => [],
36
43
  :public => {},
37
44
  :private => {},
@@ -91,6 +98,7 @@ class Brakeman::LibraryProcessor < Brakeman::BaseProcessor
91
98
  end
92
99
 
93
100
  def process_defn exp
101
+ exp = @alias_processor.process exp
94
102
  exp[0] = :methdef
95
103
 
96
104
  if @current_class
@@ -103,6 +111,7 @@ class Brakeman::LibraryProcessor < Brakeman::BaseProcessor
103
111
  end
104
112
 
105
113
  def process_defs exp
114
+ exp = @alias_processor.process exp
106
115
  exp[0] = :selfdef
107
116
 
108
117
  if @current_class
@@ -22,8 +22,15 @@ class Brakeman::ModelProcessor < Brakeman::BaseProcessor
22
22
  Brakeman.debug "[Notice] Skipping inner class: #{class_name exp[1]}"
23
23
  ignore
24
24
  else
25
+ begin
26
+ parent = class_name exp[2]
27
+ rescue StandardError => e
28
+ Brakeman.debug e
29
+ parent = nil
30
+ end
31
+
25
32
  @model = { :name => class_name(exp[1]),
26
- :parent => class_name(exp[2]),
33
+ :parent => parent,
27
34
  :includes => [],
28
35
  :public => {},
29
36
  :private => {},