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
@@ -22,25 +22,21 @@ class Brakeman::FindAllCalls < Brakeman::BaseProcessor
22
22
 
23
23
  #Process body of method
24
24
  def process_methdef exp
25
- process exp[3]
25
+ process exp.body
26
26
  end
27
27
 
28
28
  #Process body of method
29
29
  def process_selfdef exp
30
- process exp[4]
30
+ process exp.body
31
31
  end
32
32
 
33
33
  #Process body of block
34
34
  def process_rlist exp
35
- exp[1..-1].each do |e|
36
- process e
37
- end
38
-
39
- exp
35
+ process_all exp
40
36
  end
41
37
 
42
38
  def process_call exp
43
- target = get_target exp[1]
39
+ target = get_target exp.target
44
40
 
45
41
  if call? target
46
42
  already_in_target = @in_target
@@ -49,8 +45,8 @@ class Brakeman::FindAllCalls < Brakeman::BaseProcessor
49
45
  @in_target = already_in_target
50
46
  end
51
47
 
52
- method = exp[2]
53
- process exp[3]
48
+ method = exp.method
49
+ process_all exp.args
54
50
 
55
51
  call = { :target => target, :method => method, :call => exp, :nested => @in_target, :chain => get_chain(exp) }
56
52
 
@@ -68,7 +64,7 @@ class Brakeman::FindAllCalls < Brakeman::BaseProcessor
68
64
  #Calls to render() are converted to s(:render, ...) but we would
69
65
  #like them in the call cache still for speed
70
66
  def process_render exp
71
- process exp[-1] if sexp? exp[-1]
67
+ process exp.last if sexp? exp.last
72
68
 
73
69
  call = { :target => nil, :method => :render, :call => exp, :nested => false }
74
70
 
@@ -86,7 +82,7 @@ class Brakeman::FindAllCalls < Brakeman::BaseProcessor
86
82
  #Technically, `` is call to Kernel#`
87
83
  #But we just need them in the call cache for speed
88
84
  def process_dxstr exp
89
- process exp[-1] if sexp? exp[-1]
85
+ process exp.last if sexp? exp.last
90
86
 
91
87
  call = { :target => nil, :method => :`, :call => exp, :nested => false }
92
88
 
@@ -113,12 +109,10 @@ class Brakeman::FindAllCalls < Brakeman::BaseProcessor
113
109
  def get_target exp
114
110
  if sexp? exp
115
111
  case exp.node_type
116
- when :ivar, :lvar, :const
117
- exp[1]
112
+ when :ivar, :lvar, :const, :lit
113
+ exp.value
118
114
  when :true, :false
119
115
  exp[0]
120
- when :lit
121
- exp[1]
122
116
  when :colon2
123
117
  begin
124
118
  class_name exp
@@ -139,7 +133,7 @@ class Brakeman::FindAllCalls < Brakeman::BaseProcessor
139
133
  #For example, User.human.alive.all would return [:User, :human, :alive, :all]
140
134
  def get_chain call
141
135
  if node_type? call, :call, :attrasgn
142
- get_chain(call[1]) + [call[2]]
136
+ get_chain(call.target) + [call.method]
143
137
  else
144
138
  [get_target(call)]
145
139
  end
@@ -1,6 +1,8 @@
1
1
  require 'brakeman/processors/base_processor'
2
2
 
3
3
  #Finds method calls matching the given target(s).
4
+ # #-- This should be deprecated --#
5
+ # #-- Do not use for new code --#
4
6
  #
5
7
  #Targets/methods can be:
6
8
  #
@@ -67,29 +69,22 @@ class Brakeman::FindCall < Brakeman::BaseProcessor
67
69
 
68
70
  #Process body of method
69
71
  def process_methdef exp
70
- process exp[3]
72
+ process exp.body
71
73
  end
72
74
 
73
- #Process body of method
74
- def process_selfdef exp
75
- process exp[4]
76
- end
75
+ alias :process_selfdef :process_methdef
77
76
 
78
77
  #Process body of block
79
78
  def process_rlist exp
80
- exp[1..-1].each do |e|
81
- process e
82
- end
83
-
84
- exp
79
+ process_all exp
85
80
  end
86
81
 
87
82
  #Look for matching calls and add them to results
88
83
  def process_call exp
89
- target = get_target exp[1]
90
- method = exp[2]
84
+ target = get_target exp.target
85
+ method = exp.method
91
86
 
92
- process exp[3]
87
+ process_all exp.args
93
88
 
94
89
  if match(@find_targets, target) and match(@find_methods, method)
95
90
 
@@ -107,8 +102,8 @@ class Brakeman::FindCall < Brakeman::BaseProcessor
107
102
  # User.find(:first, :conditions => "user = '#{params['user']}').name
108
103
  #
109
104
  #A search for User.find will not match this unless @in_depth is true.
110
- if @in_depth and node_type? exp[1], :call
111
- process exp[1]
105
+ if @in_depth and node_type? exp.target, :call
106
+ process exp.target
112
107
  end
113
108
 
114
109
  exp
@@ -126,12 +121,10 @@ class Brakeman::FindCall < Brakeman::BaseProcessor
126
121
  def get_target exp
127
122
  if sexp? exp
128
123
  case exp.node_type
129
- when :ivar, :lvar, :const
130
- exp[1]
124
+ when :ivar, :lvar, :const, :lit
125
+ exp.value
131
126
  when :true, :false
132
- exp[0]
133
- when :lit
134
- exp[1]
127
+ exp.node_type
135
128
  when :colon2
136
129
  class_name exp
137
130
  else
@@ -176,10 +169,10 @@ class Brakeman::FindCall < Brakeman::BaseProcessor
176
169
  #Checks if +item+ is an instance of +klass+ by looking for Klass.new
177
170
  def is_instance_of? item, klass
178
171
  if call? item
179
- if sexp? item[1]
180
- item[2] == :new and item[1].node_type == :const and item[1][1] == klass
172
+ if sexp? item.target
173
+ item.method == :new and item.target.node_type == :const and item.target.value == klass
181
174
  else
182
- item[2] == :new and item[1] == klass
175
+ item.method == :new and item.target == klass
183
176
  end
184
177
  else
185
178
  false
@@ -1,9 +1,15 @@
1
1
  #Contains a couple shared methods for Processors.
2
2
  module Brakeman::ProcessorHelper
3
+ def process_all exp
4
+ exp.each_sexp do |e|
5
+ process e
6
+ end
7
+ exp
8
+ end
3
9
 
4
10
  #Sets the current module.
5
11
  def process_module exp
6
- module_name = class_name(exp[1]).to_s
12
+ module_name = class_name(exp.class_name).to_s
7
13
  prev_module = @current_module
8
14
 
9
15
  if prev_module
@@ -12,7 +18,7 @@ module Brakeman::ProcessorHelper
12
18
  @current_module = module_name
13
19
  end
14
20
 
15
- process exp[2]
21
+ process exp.body
16
22
 
17
23
  @current_module = prev_module
18
24
 
@@ -25,13 +31,13 @@ module Brakeman::ProcessorHelper
25
31
  when Sexp
26
32
  case exp.node_type
27
33
  when :const
28
- exp[1]
34
+ exp.value
29
35
  when :lvar
30
- exp[1].to_sym
36
+ exp.value.to_sym
31
37
  when :colon2
32
38
  "#{class_name(exp[1])}::#{exp[2]}".to_sym
33
39
  when :colon3
34
- "::#{exp[1]}".to_sym
40
+ "::#{exp.value}".to_sym
35
41
  when :call
36
42
  process exp
37
43
  when :self
@@ -33,10 +33,10 @@ class Brakeman::Rails2ConfigProcessor < Brakeman::BaseProcessor
33
33
 
34
34
  #Check if config is set to use Erubis
35
35
  def process_call exp
36
- target = exp[1]
36
+ target = exp.target
37
37
  target = process target if sexp? target
38
38
 
39
- if exp[2] == :gem and exp[3][1][1] == "erubis"
39
+ if exp.method == :gem and exp.first_arg.value == "erubis"
40
40
  Brakeman.notify "[Notice] Using Erubis for ERB templates"
41
41
  @tracker.config[:erubis] = true
42
42
  end
@@ -46,14 +46,14 @@ class Brakeman::Rails2ConfigProcessor < Brakeman::BaseProcessor
46
46
 
47
47
  #Look for configuration settings
48
48
  def process_attrasgn exp
49
- if exp[1] == Brakeman::RAILS_CONFIG
49
+ if exp.target == Brakeman::RAILS_CONFIG
50
50
  #Get rid of '=' at end
51
- attribute = exp[2].to_s[0..-2].to_sym
52
- if exp[3].length > 2
51
+ attribute = exp.method.to_s[0..-2].to_sym
52
+ if exp.args.length > 1
53
53
  #Multiple arguments?...not sure if this will ever happen
54
- @tracker.config[:rails][attribute] = exp[3][1..-1]
54
+ @tracker.config[:rails][attribute] = exp.args
55
55
  else
56
- @tracker.config[:rails][attribute] = exp[3][1]
56
+ @tracker.config[:rails][attribute] = exp.first_arg
57
57
  end
58
58
  elsif include_rails_config? exp
59
59
  options = get_rails_config exp
@@ -63,7 +63,7 @@ class Brakeman::Rails2ConfigProcessor < Brakeman::BaseProcessor
63
63
  level = level[o]
64
64
  end
65
65
 
66
- level[options.last] = exp[3][1]
66
+ level[options.last] = exp.first_arg
67
67
  end
68
68
 
69
69
  exp
@@ -72,8 +72,8 @@ class Brakeman::Rails2ConfigProcessor < Brakeman::BaseProcessor
72
72
  #Check for Rails version
73
73
  def process_cdecl exp
74
74
  #Set Rails version required
75
- if exp[1] == :RAILS_GEM_VERSION
76
- @tracker.config[:rails_version] = exp[2][1]
75
+ if exp.lhs == :RAILS_GEM_VERSION
76
+ @tracker.config[:rails_version] = exp.rhs.value
77
77
  end
78
78
 
79
79
  exp
@@ -81,9 +81,9 @@ class Brakeman::Rails2ConfigProcessor < Brakeman::BaseProcessor
81
81
 
82
82
  #Check if an expression includes a call to set Rails config
83
83
  def include_rails_config? exp
84
- target = exp[1]
84
+ target = exp.target
85
85
  if call? target
86
- if target[1] == Brakeman::RAILS_CONFIG
86
+ if target.target == Brakeman::RAILS_CONFIG
87
87
  true
88
88
  else
89
89
  include_rails_config? target
@@ -104,13 +104,13 @@ class Brakeman::Rails2ConfigProcessor < Brakeman::BaseProcessor
104
104
  # [:action_controller, :session_store]
105
105
  def get_rails_config exp
106
106
  if node_type? exp, :attrasgn
107
- attribute = exp[2].to_s[0..-2].to_sym
108
- get_rails_config(exp[1]) << attribute
107
+ attribute = exp.method.to_s[0..-2].to_sym
108
+ get_rails_config(exp.target) << attribute
109
109
  elsif call? exp
110
- if exp[1] == Brakeman::RAILS_CONFIG
111
- [exp[2]]
110
+ if exp.target == Brakeman::RAILS_CONFIG
111
+ [exp.method]
112
112
  else
113
- get_rails_config(exp[1]) << exp[2]
113
+ get_rails_config(exp.target) << exp.method
114
114
  end
115
115
  else
116
116
  raise "WHAT"
@@ -131,11 +131,12 @@ class Brakeman::ConfigAliasProcessor < Brakeman::AliasProcessor
131
131
  #
132
132
  #and replace config with Brakeman::RAILS_CONFIG
133
133
  def process_iter exp
134
- target = exp[1][1]
135
- method = exp[1][2]
134
+ target = exp.block_call.target
135
+ method = exp.block_call.method
136
+
136
137
 
137
138
  if sexp? target and target == RAILS_INIT and method == :run
138
- exp[2][2] = Brakeman::RAILS_CONFIG
139
+ exp.block_args.rhs = Brakeman::RAILS_CONFIG
139
140
  end
140
141
 
141
142
  process_default exp
@@ -28,7 +28,7 @@ class Brakeman::Rails2RoutesProcessor < Brakeman::BaseProcessor
28
28
 
29
29
  #Looking for mapping of routes
30
30
  def process_call exp
31
- target = exp[1]
31
+ target = exp.target
32
32
 
33
33
  if target == map or (not target.nil? and target == nested)
34
34
  process_map exp
@@ -42,9 +42,9 @@ class Brakeman::Rails2RoutesProcessor < Brakeman::BaseProcessor
42
42
  #Process a map.something call
43
43
  #based on the method used
44
44
  def process_map exp
45
- args = exp[3][1..-1]
45
+ args = exp.args
46
46
 
47
- case exp[2]
47
+ case exp.method
48
48
  when :resource
49
49
  process_resource args
50
50
  when :resources
@@ -61,14 +61,16 @@ class Brakeman::Rails2RoutesProcessor < Brakeman::BaseProcessor
61
61
  #Look for map calls that take a block.
62
62
  #Otherwise, just do the default processing.
63
63
  def process_iter exp
64
- if exp[1][1] == map or exp[1][1] == nested
65
- method = exp[1][2]
64
+ target = exp.block_call.target
65
+
66
+ if target == map or target == nested
67
+ method = exp.block_call.method
66
68
  case method
67
69
  when :namespace
68
70
  process_namespace exp
69
71
  when :resources, :resource
70
- process_resources exp[1][3][1..-1]
71
- process_default exp[3] if exp[3]
72
+ process_resources exp.block_call.args
73
+ process_default exp.block if exp.block
72
74
  when :with_options
73
75
  process_with_options exp
74
76
  end
@@ -89,9 +91,9 @@ class Brakeman::Rails2RoutesProcessor < Brakeman::BaseProcessor
89
91
  else
90
92
  exp.each do |argument|
91
93
  if node_type? argument, :lit
92
- self.current_controller = exp[0][1]
94
+ self.current_controller = exp.first.value
93
95
  add_resources_routes
94
- process_resource_options exp[-1]
96
+ process_resource_options exp.last
95
97
  end
96
98
  end
97
99
  end
@@ -141,7 +143,7 @@ class Brakeman::Rails2RoutesProcessor < Brakeman::BaseProcessor
141
143
 
142
144
  if exp.node_type == :array
143
145
  exp[1..-1].each do |e|
144
- routes << e[1]
146
+ routes << e.value
145
147
  end
146
148
  end
147
149
  end
@@ -152,7 +154,7 @@ class Brakeman::Rails2RoutesProcessor < Brakeman::BaseProcessor
152
154
  routes = @tracker.routes[@current_controller]
153
155
 
154
156
  exp[1..-1].each do |e|
155
- routes.delete e[1]
157
+ routes.delete e.value
156
158
  end
157
159
  end
158
160
 
@@ -161,13 +163,13 @@ class Brakeman::Rails2RoutesProcessor < Brakeman::BaseProcessor
161
163
  controller = check_for_controller_name exp
162
164
  if controller
163
165
  self.current_controller = controller
164
- process_resource_options exp[-1]
166
+ process_resource_options exp.last
165
167
  else
166
168
  exp.each do |argument|
167
169
  if node_type? argument, :lit
168
- self.current_controller = pluralize(exp[0][1].to_s)
170
+ self.current_controller = pluralize(exp.first.value.to_s)
169
171
  add_resource_routes
170
- process_resource_options exp[-1]
172
+ process_resource_options exp.last
171
173
  end
172
174
  end
173
175
  end
@@ -180,10 +182,10 @@ class Brakeman::Rails2RoutesProcessor < Brakeman::BaseProcessor
180
182
  self.current_controller = controller if controller
181
183
 
182
184
  #Check for default route
183
- if string? exp[0]
184
- if exp[0][1] == ":controller/:action/:id"
185
- @tracker.routes[:allow_all_actions] = exp[0]
186
- elsif exp[0][1].include? ":action"
185
+ if string? exp.first
186
+ if exp.first.value == ":controller/:action/:id"
187
+ @tracker.routes[:allow_all_actions] = exp.first
188
+ elsif exp.first.value.include? ":action"
187
189
  @tracker.routes[@current_controller] = [:allow_all_actions, exp.line]
188
190
  return
189
191
  end
@@ -193,9 +195,9 @@ class Brakeman::Rails2RoutesProcessor < Brakeman::BaseProcessor
193
195
  #to a controller which already allows them all
194
196
  return if @tracker.routes[@current_controller].is_a? Array and @tracker.routes[@current_controller][0] == :allow_all_actions
195
197
 
196
- exp[-1].each_with_index do |e,i|
197
- if symbol? e and e[1] == :action
198
- @tracker.routes[@current_controller] << exp[-1][i + 1][1].to_sym
198
+ exp.last.each_with_index do |e,i|
199
+ if symbol? e and e.value == :action
200
+ @tracker.routes[@current_controller] << exp.last[i + 1].value.to_sym
199
201
  return
200
202
  end
201
203
  end
@@ -205,13 +207,13 @@ class Brakeman::Rails2RoutesProcessor < Brakeman::BaseProcessor
205
207
  # something.resources :blah
206
208
  # end
207
209
  def process_with_options exp
208
- @with_options = exp[1][3][-1]
209
- @nested = Sexp.new(:lvar, exp[2][1])
210
+ @with_options = exp.block_call.args.last
211
+ @nested = Sexp.new(:lvar, exp.block_args.lhs)
210
212
 
211
- self.current_controller = check_for_controller_name exp[1][3]
213
+ self.current_controller = check_for_controller_name exp.block_call.args
212
214
 
213
215
  #process block
214
- process exp[3]
216
+ process exp.block
215
217
 
216
218
  @with_options = nil
217
219
  @nested = nil
@@ -221,13 +223,15 @@ class Brakeman::Rails2RoutesProcessor < Brakeman::BaseProcessor
221
223
  # something.resources :blah
222
224
  # end
223
225
  def process_namespace exp
224
- call = exp[1]
225
- formal_args = exp[2]
226
- block = exp[3]
226
+ call = exp.block_call
227
+ formal_args = exp.block_args
228
+ block = exp.block
227
229
 
228
- @prefix << camelize(call[3][1][1])
230
+ @prefix << camelize(call.first_arg.value)
229
231
 
230
- @nested = Sexp.new(:lvar, formal_args[1])
232
+ if formal_args
233
+ @nested = Sexp.new(:lvar, formal_args.lhs)
234
+ end
231
235
 
232
236
  process block
233
237
 
@@ -246,7 +250,7 @@ class Brakeman::Rails2RoutesProcessor < Brakeman::BaseProcessor
246
250
  routes = @tracker.routes[@current_controller]
247
251
 
248
252
  hash_iterate(exp) do |action, type|
249
- routes << action[1]
253
+ routes << action.value
250
254
  end
251
255
  end
252
256
 
@@ -259,7 +263,7 @@ class Brakeman::Rails2RoutesProcessor < Brakeman::BaseProcessor
259
263
  def check_for_controller_name args
260
264
  args.each do |a|
261
265
  if hash? a and value = hash_access(a, :controller)
262
- return value[1]
266
+ return value.value if string? value or symbol? value
263
267
  end
264
268
  end
265
269
 
@@ -278,8 +282,8 @@ class Brakeman::RouteAliasProcessor < Brakeman::AliasProcessor
278
282
  def process_call exp
279
283
  process_default exp
280
284
 
281
- if hash? exp[1] and exp[2] == :keys
282
- keys = get_keys exp[1]
285
+ if hash? exp.target and exp.method == :keys
286
+ keys = get_keys exp.target
283
287
  exp.clear
284
288
  keys.each_with_index do |e,i|
285
289
  exp[i] = e