brakeman 1.6.2 → 1.7.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 (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 => {},