brakeman 1.9.5 → 2.0.0.pre2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGES +27 -0
  3. data/README.md +5 -2
  4. data/bin/brakeman +20 -15
  5. data/lib/brakeman.rb +106 -80
  6. data/lib/brakeman/app_tree.rb +22 -11
  7. data/lib/brakeman/call_index.rb +4 -4
  8. data/lib/brakeman/checks/base_check.rb +33 -5
  9. data/lib/brakeman/checks/check_basic_auth.rb +2 -1
  10. data/lib/brakeman/checks/check_content_tag.rb +8 -29
  11. data/lib/brakeman/checks/check_cross_site_scripting.rb +10 -19
  12. data/lib/brakeman/checks/check_deserialize.rb +57 -0
  13. data/lib/brakeman/checks/check_execute.rb +3 -11
  14. data/lib/brakeman/checks/check_file_access.rb +1 -14
  15. data/lib/brakeman/checks/check_forgery_setting.rb +5 -4
  16. data/lib/brakeman/checks/check_link_to.rb +4 -15
  17. data/lib/brakeman/checks/check_link_to_href.rb +1 -8
  18. data/lib/brakeman/checks/check_mass_assignment.rb +6 -2
  19. data/lib/brakeman/checks/check_model_attributes.rb +1 -0
  20. data/lib/brakeman/checks/check_model_serialize.rb +2 -1
  21. data/lib/brakeman/checks/check_render.rb +2 -15
  22. data/lib/brakeman/checks/check_select_tag.rb +1 -1
  23. data/lib/brakeman/checks/check_select_vulnerability.rb +2 -2
  24. data/lib/brakeman/checks/check_send.rb +3 -0
  25. data/lib/brakeman/checks/check_session_settings.rb +2 -3
  26. data/lib/brakeman/checks/check_skip_before_filter.rb +5 -2
  27. data/lib/brakeman/checks/check_sql.rb +59 -50
  28. data/lib/brakeman/checks/check_symbol_dos.rb +5 -14
  29. data/lib/brakeman/checks/check_unsafe_reflection.rb +2 -15
  30. data/lib/brakeman/options.rb +14 -9
  31. data/lib/brakeman/processors/controller_alias_processor.rb +4 -10
  32. data/lib/brakeman/processors/controller_processor.rb +53 -14
  33. data/lib/brakeman/processors/lib/find_all_calls.rb +40 -40
  34. data/lib/brakeman/processors/lib/processor_helper.rb +5 -1
  35. data/lib/brakeman/processors/lib/rails3_config_processor.rb +8 -0
  36. data/lib/brakeman/processors/output_processor.rb +23 -1
  37. data/lib/brakeman/report.rb +28 -14
  38. data/lib/brakeman/scanner.rb +5 -3
  39. data/lib/brakeman/tracker.rb +7 -7
  40. data/lib/brakeman/util.rb +5 -3
  41. data/lib/brakeman/version.rb +1 -1
  42. data/lib/brakeman/warning.rb +12 -9
  43. data/lib/ruby_parser/bm_sexp.rb +5 -1
  44. data/lib/tasks/brakeman.rake +10 -0
  45. metadata +11 -9
  46. data/lib/brakeman/checks/check_yaml_load.rb +0 -55
@@ -57,6 +57,7 @@ class Brakeman::CheckModelAttributes < Brakeman::BaseCheck
57
57
  warn :model => name,
58
58
  :file => model[:file],
59
59
  :warning_type => "Attribute Restriction",
60
+ :warning_code => :no_attr_accessible,
60
61
  :message => "Mass assignment is not restricted using attr_accessible",
61
62
  :confidence => CONFIDENCE[:high]
62
63
  elsif not tracker.options[:ignore_attr_protected]
@@ -59,7 +59,8 @@ class Brakeman::CheckModelSerialize < Brakeman::BaseCheck
59
59
  :warning_code => :CVE_2013_0277,
60
60
  :message => "Serialized attributes are vulnerable in Rails #{tracker.config[:rails_version]}, upgrade to #{@upgrade_version} or patch.",
61
61
  :confidence => confidence,
62
- :link => "https://groups.google.com/d/topic/rubyonrails-security/KtmwSbEpzrU/discussion"
62
+ :link => "https://groups.google.com/d/topic/rubyonrails-security/KtmwSbEpzrU/discussion",
63
+ :file => model[:file]
63
64
  end
64
65
  end
65
66
  end
@@ -47,22 +47,9 @@ class Brakeman::CheckRender < Brakeman::BaseCheck
47
47
  return
48
48
  end
49
49
 
50
- message = "Render path contains "
51
-
52
- case input.type
53
- when :params
54
- message << "parameter value"
55
- when :cookies
56
- message << "cookie value"
57
- when :request
58
- message << "request value"
59
- when :model
60
- #Skip models
61
- return
62
- else
63
- message << "user input value"
64
- end
50
+ return if input.type == :model #skip models
65
51
 
52
+ message = "Render path contains #{friendly_type_of input}"
66
53
 
67
54
  warn :result => result,
68
55
  :warning_type => "Dynamic Render Path",
@@ -24,7 +24,7 @@ class Brakeman::CheckSelectTag < Brakeman::BaseCheck
24
24
  @message = "Upgrade to Rails #{suggested_version}, #{tracker.config[:rails_version]} select_tag is vulnerable (CVE-2012-3463)"
25
25
 
26
26
  calls = tracker.find_call(:target => nil, :method => :select_tag).select do |result|
27
- result[:location][0] == :template
27
+ result[:location][:type] == :template
28
28
  end
29
29
 
30
30
  calls.each do |result|
@@ -24,7 +24,7 @@ class Brakeman::CheckSelectVulnerability < Brakeman::BaseCheck
24
24
  @message = "Upgrade to Rails #{suggested_version}, #{tracker.config[:rails_version]} select() helper is vulnerable"
25
25
 
26
26
  calls = tracker.find_call(:target => nil, :method => :select).select do |result|
27
- result[:location][0] == :template
27
+ result[:location][:type] == :template
28
28
  end
29
29
 
30
30
  calls.each do |result|
@@ -47,7 +47,7 @@ class Brakeman::CheckSelectVulnerability < Brakeman::BaseCheck
47
47
  confidence = CONFIDENCE[:low]
48
48
  end
49
49
 
50
- warn :template => result[:location][1],
50
+ warn :template => result[:location][:template],
51
51
  :warning_type => "Cross Site Scripting",
52
52
  :warning_code => :select_options_vuln,
53
53
  :result => result,
@@ -16,6 +16,9 @@ class Brakeman::CheckSend < Brakeman::BaseCheck
16
16
  end
17
17
 
18
18
  def process_result result
19
+ return if duplicate? result or result[:call].original_line
20
+ add_result result
21
+
19
22
  process_call_args result[:call]
20
23
  target = process result[:call].target
21
24
 
@@ -17,9 +17,8 @@ class Brakeman::CheckSessionSettings < Brakeman::BaseCheck
17
17
  end
18
18
 
19
19
  def run_check
20
- settings = tracker.config[:rails] and
21
- tracker.config[:rails][:action_controller] and
22
- tracker.config[:rails][:action_controller][:session]
20
+ settings = tracker.config[:rails][:action_controller] &&
21
+ tracker.config[:rails][:action_controller][:session]
23
22
 
24
23
  check_for_issues settings, "#{tracker.options[:app_path]}/config/environment.rb"
25
24
 
@@ -30,7 +30,9 @@ class Brakeman::CheckSkipBeforeFilter < Brakeman::BaseCheck
30
30
  :warning_code => :csrf_blacklist,
31
31
  :message => "Use whitelist (:only => [..]) when skipping CSRF check",
32
32
  :code => filter,
33
- :confidence => CONFIDENCE[:med]
33
+ :confidence => CONFIDENCE[:med],
34
+ :file => controller[:file]
35
+
34
36
  when :login_required, :authenticate_user!, :require_user
35
37
  warn :controller => controller[:name],
36
38
  :warning_code => :auth_blacklist,
@@ -38,7 +40,8 @@ class Brakeman::CheckSkipBeforeFilter < Brakeman::BaseCheck
38
40
  :message => "Use whitelist (:only => [..]) when skipping authentication",
39
41
  :code => filter,
40
42
  :confidence => CONFIDENCE[:med],
41
- :link => "authentication_whitelist"
43
+ :link => "authentication_whitelist",
44
+ :file => controller[:file]
42
45
  end
43
46
  end
44
47
 
@@ -68,7 +68,7 @@ class Brakeman::CheckSQL < Brakeman::BaseCheck
68
68
  if model[:options][:named_scope]
69
69
  model[:options][:named_scope].each do |args|
70
70
  call = make_call(nil, :named_scope, args).line(args.line)
71
- scope_calls << { :call => call, :location => [:class, name ], :method => :named_scope }
71
+ scope_calls << { :call => call, :location => { :type => :class, :class => name }, :method => :named_scope }
72
72
  end
73
73
  end
74
74
  end
@@ -84,10 +84,10 @@ class Brakeman::CheckSQL < Brakeman::BaseCheck
84
84
  process_scope_with_block name, args
85
85
  elsif second_arg.node_type == :call
86
86
  call = second_arg
87
- scope_calls << { :call => call, :location => [:class, name ], :method => call.method }
87
+ scope_calls << { :call => call, :location => { :type => :class, :class => name }, :method => call.method }
88
88
  else
89
89
  call = make_call(nil, :scope, args).line(args.line)
90
- scope_calls << { :call => call, :location => [:class, name ], :method => :scope }
90
+ scope_calls << { :call => call, :location => { :type => :class, :class => name }, :method => :scope }
91
91
  end
92
92
  end
93
93
  end
@@ -98,64 +98,48 @@ class Brakeman::CheckSQL < Brakeman::BaseCheck
98
98
  end
99
99
 
100
100
  def check_rails_version_for_cve_2012_2660
101
- if version_between?("2.0.0", "2.3.14") || version_between?("3.0.0", "3.0.12") || version_between?("3.1.0", "3.1.4") || version_between?("3.2.0", "3.2.3")
102
- warn :warning_type => 'SQL Injection',
103
- :warning_code => :CVE_2012_2660,
104
- :message => 'All versions of Rails before 3.0.13, 3.1.5, and 3.2.5 contain a SQL Query Generation Vulnerability: CVE-2012-2660; Upgrade to 3.2.5, 3.1.5, 3.0.13',
105
- :confidence => CONFIDENCE[:high],
106
- :file => gemfile_or_environment,
107
- :link_path => "https://groups.google.com/d/topic/rubyonrails-security/8SA-M3as7A8/discussion"
108
- end
101
+ versions = [%w[2.0.0 2.3.14 2.3.17],
102
+ %w[3.0.0 3.0.12 3.0.13],
103
+ %w[3.1.0 3.1.4 3.1.5],
104
+ %w[3.2.0 3.2.3 3.2.4]]
105
+
106
+ cve_warning_for versions, "CVE-2012-2660", "https://groups.google.com/d/topic/rubyonrails-security/8SA-M3as7A8/discussion"
109
107
  end
110
108
 
111
109
  def check_rails_version_for_cve_2012_2661
112
- if version_between?("3.0.0", "3.0.12") || version_between?("3.1.0", "3.1.4") || version_between?("3.2.0", "3.2.3")
113
- warn :warning_type => 'SQL Injection',
114
- :warning_code => :CVE_2012_2661,
115
- :message => 'All versions of Rails before 3.0.13, 3.1.5, and 3.2.5 contain a SQL Injection Vulnerability: CVE-2012-2661; Upgrade to 3.2.5, 3.1.5, 3.0.13',
116
- :confidence => CONFIDENCE[:high],
117
- :file => gemfile_or_environment,
118
- :link_path => "https://groups.google.com/d/topic/rubyonrails-security/dUaiOOGWL1k/discussion"
119
- end
110
+ versions = [%w[3.0.0 3.0.12 3.0.13],
111
+ %w[3.1.0 3.1.4 3.1.5],
112
+ %w[3.2.0 3.2.3 3.2.5]]
113
+
114
+ cve_warning_for versions, "CVE-2012-2661", "https://groups.google.com/d/topic/rubyonrails-security/dUaiOOGWL1k/discussion"
120
115
  end
121
116
 
122
117
  def check_rails_version_for_cve_2012_2695
123
- if version_between?("2.0.0", "2.3.14") || version_between?("3.0.0", "3.0.13") || version_between?("3.1.0", "3.1.5") || version_between?("3.2.0", "3.2.5")
124
- warn :warning_type => 'SQL Injection',
125
- :warning_code => :CVE_2012_2695,
126
- :message => 'All versions of Rails before 3.0.14, 3.1.6, and 3.2.6 contain SQL Injection Vulnerabilities: CVE-2012-2694 and CVE-2012-2695; Upgrade to 3.2.6, 3.1.6, 3.0.14',
127
- :confidence => CONFIDENCE[:high],
128
- :file => gemfile_or_environment,
129
- :link_path => "https://groups.google.com/d/topic/rubyonrails-security/l4L0TEVAz1k/discussion"
130
- end
118
+ versions = [%w[2.0.0 2.3.14 2.3.15],
119
+ %w[3.0.0 3.0.13 3.0.14],
120
+ %w[3.1.0 3.1.5 3.1.6],
121
+ %w[3.2.0 3.2.5 3.2.6]]
122
+
123
+ cve_warning_for versions, "CVE-2012-2695", "https://groups.google.com/d/topic/rubyonrails-security/l4L0TEVAz1k/discussion"
131
124
  end
132
125
 
133
126
  def check_rails_version_for_cve_2012_5664
134
- if version_between?("2.0.0", "2.3.14") || version_between?("3.0.0", "3.0.17") || version_between?("3.1.0", "3.1.8") || version_between?("3.2.0", "3.2.9")
135
- warn :warning_type => 'SQL Injection',
136
- :warning_code => :CVE_2012_5664,
137
- :message => 'All versions of Rails before 3.0.18, 3.1.9, and 3.2.10 contain a SQL Injection Vulnerability: CVE-2012-5664; Upgrade to 3.2.10, 3.1.9, 3.0.18',
138
- :confidence => CONFIDENCE[:high],
139
- :file => gemfile_or_environment,
140
- :link_path => "https://groups.google.com/d/topic/rubyonrails-security/DCNTNp_qjFM/discussion"
141
- end
127
+ versions = [%w[2.0.0 2.3.14 2.3.15],
128
+ %w[3.0.0 3.0.17 3.0.18],
129
+ %w[3.1.0 3.1.8 3.1.9],
130
+ %w[3.2.0 3.2.9 3.2.18]]
131
+
132
+ cve_warning_for versions, "CVE-2012-5664", "https://groups.google.com/d/topic/rubyonrails-security/DCNTNp_qjFM/discussion"
142
133
  end
143
134
 
144
135
  def check_rails_version_for_cve_2013_0155
145
- if version_between?("3.0.0", "3.0.18") || version_between?("3.1.0", "3.1.9") || version_between?("3.2.0", "3.2.10")
146
- message = 'All versions of Rails before 3.0.19, 3.1.10, and 3.2.11 contain a SQL Injection Vulnerability: CVE-2013-0155; Upgrade to 3.2.11, 3.1.10, 3.0.19'
147
- elsif version_between?("2.0.0", "2.3.15")
148
- message = "Rails #{@rails_version} contains a SQL Injection Vulnerability: CVE-2013-0155; Upgrade to 2.3.16"
149
- end
136
+ versions = [%w[2.0.0 2.3.15 2.3.16],
137
+ %w[3.0.0 3.0.18 3.0.19],
138
+ %w[3.1.0 3.1.9 3.1.10],
139
+ %w[3.2.0 3.2.10 3.2.11]]
150
140
 
151
- if message
152
- warn :warning_type => 'SQL Injection',
153
- :warning_code => :CVE_2013_0155,
154
- :message => message,
155
- :confidence => CONFIDENCE[:high],
156
- :file => gemfile_or_environment,
157
- :link_path => "https://groups.google.com/d/topic/rubyonrails-security/c7jT-EeN9eI/discussion"
158
- end
141
+
142
+ cve_warning_for versions, "CVE-2013-0155", "https://groups.google.com/d/topic/rubyonrails-security/c7jT-EeN9eI/discussion"
159
143
  end
160
144
 
161
145
  def process_scope_with_block model_name, args
@@ -166,7 +150,7 @@ class Brakeman::CheckSQL < Brakeman::BaseCheck
166
150
  if block.node_type == :block
167
151
  find_calls = Brakeman::FindAllCalls.new tracker
168
152
 
169
- find_calls.process_source block, model_name, scope_name
153
+ find_calls.process_source block, :class => model_name, :method => scope_name
170
154
 
171
155
  find_calls.calls.each do |call|
172
156
  if @sql_targets.include? call[:method]
@@ -174,7 +158,8 @@ class Brakeman::CheckSQL < Brakeman::BaseCheck
174
158
  end
175
159
  end
176
160
  elsif block.node_type == :call
177
- process_result :target => block.target, :method => block.method, :call => block, :location => [:class, model_name, scope_name]
161
+ process_result :target => block.target, :method => block.method, :call => block,
162
+ :location => { :type => :class, :class => model_name, :method => scope_name }
178
163
  end
179
164
  end
180
165
 
@@ -618,4 +603,28 @@ class Brakeman::CheckSQL < Brakeman::BaseCheck
618
603
  call = result[:call]
619
604
  call? call.target and call.target.method == :constantize
620
605
  end
606
+
607
+ def upgrade_version? versions
608
+ versions.each do |low, high, upgrade|
609
+ if version_between? low, high
610
+ return upgrade
611
+ end
612
+ end
613
+
614
+ false
615
+ end
616
+
617
+ def cve_warning_for versions, cve, link
618
+ upgrade_version = upgrade_version? versions
619
+ return unless upgrade_version
620
+
621
+ code = cve.tr('-', '_').to_sym
622
+
623
+ warn :warning_type => 'SQL Injection',
624
+ :warning_code => code,
625
+ :message => "Rails #{tracker.config[:rails_version]} contains a SQL injection vulnerability (#{cve}). Upgrade to #{upgrade_version}",
626
+ :confidence => CONFIDENCE[:high],
627
+ :file => gemfile_or_environment,
628
+ :link_path => link
629
+ end
621
630
  end
@@ -33,8 +33,12 @@ class Brakeman::CheckSymbolDoS < Brakeman::BaseCheck
33
33
  end
34
34
 
35
35
  def check_unsafe_symbol_creation result
36
+ return if duplicate? result or result[:call].original_line
37
+
38
+ add_result result
36
39
 
37
40
  call = result[:call]
41
+
38
42
  if result[:method] == :to_sym
39
43
  args = [call.target]
40
44
  else
@@ -48,20 +52,7 @@ class Brakeman::CheckSymbolDoS < Brakeman::BaseCheck
48
52
  end
49
53
 
50
54
  if confidence
51
- input_type = case input.type
52
- when :params
53
- "parameter value"
54
- when :cookies
55
- "cookies value"
56
- when :request
57
- "request value"
58
- when :model
59
- "model attribute"
60
- else
61
- "user input"
62
- end
63
-
64
- message = "Symbol conversion from unsafe string (#{input_type})"
55
+ message = "Symbol conversion from unsafe string (#{friendly_type_of input})"
65
56
 
66
57
  warn :result => result,
67
58
  :warning_type => "Denial of Service",
@@ -18,7 +18,7 @@ class Brakeman::CheckUnsafeReflection < Brakeman::BaseCheck
18
18
  end
19
19
 
20
20
  def check_unsafe_reflection result
21
- return if duplicate? result
21
+ return if duplicate? result or result[:call].original_line
22
22
  add_result result
23
23
 
24
24
  call = result[:call]
@@ -38,20 +38,7 @@ class Brakeman::CheckUnsafeReflection < Brakeman::BaseCheck
38
38
  end
39
39
 
40
40
  if confidence
41
- input_type = case input.type
42
- when :params
43
- "parameter value"
44
- when :cookies
45
- "cookies value"
46
- when :request
47
- "request value"
48
- when :model
49
- "model attribute"
50
- else
51
- "user input"
52
- end
53
-
54
- message = "Unsafe Reflection method #{method} called with #{input_type}"
41
+ message = "Unsafe Reflection method #{method} called with #{friendly_type_of input}"
55
42
 
56
43
  warn :result => result,
57
44
  :warning_type => "Remote Code Execution",
@@ -91,13 +91,18 @@ module Brakeman::Options
91
91
  opts.on "--url-safe-methods method1,method2,etc", Array, "Do not warn of XSS if the link_to href parameter is wrapped in a safe method" do |methods|
92
92
  options[:url_safe_methods] ||= Set.new
93
93
  options[:url_safe_methods].merge methods.map {|e| e.to_sym }
94
- end
94
+ end
95
95
 
96
96
  opts.on "--skip-files file1,file2,etc", Array, "Skip processing of these files" do |files|
97
97
  options[:skip_files] ||= Set.new
98
98
  options[:skip_files].merge files
99
99
  end
100
100
 
101
+ opts.on "--only-files file1,file2,etc", Array, "Process only these files" do |files|
102
+ options[:only_files] ||= Set.new
103
+ options[:only_files].merge files
104
+ end
105
+
101
106
  opts.on "--skip-libs", "Skip processing lib directory" do
102
107
  options[:skip_libs] = true
103
108
  end
@@ -128,11 +133,11 @@ module Brakeman::Options
128
133
  opts.separator "Output options:"
129
134
 
130
135
  opts.on "-d", "--debug", "Lots of output" do
131
- options[:debug] = true
136
+ options[:debug] = true
132
137
  end
133
138
 
134
- opts.on "-f",
135
- "--format TYPE",
139
+ opts.on "-f",
140
+ "--format TYPE",
136
141
  [:pdf, :text, :html, :csv, :tabs, :json],
137
142
  "Specify output formats. Default is text" do |type|
138
143
 
@@ -173,13 +178,13 @@ module Brakeman::Options
173
178
  options[:summary_only] = true
174
179
  end
175
180
 
176
- opts.on "--relative-paths", "Output relative file paths in reports" do
177
- options[:relative_paths] = true
181
+ opts.on "--absolute-paths", "Output absolute file paths in reports" do
182
+ options[:absolute_paths] = true
178
183
  end
179
184
 
180
- opts.on "-w",
181
- "--confidence-level LEVEL",
182
- ["1", "2", "3"],
185
+ opts.on "-w",
186
+ "--confidence-level LEVEL",
187
+ ["1", "2", "3"],
183
188
  "Set minimal confidence level (1 - 3)" do |level|
184
189
 
185
190
  options[:min_confidence] = 3 - level.to_i
@@ -64,16 +64,9 @@ class Brakeman::ControllerAliasProcessor < Brakeman::AliasProcessor
64
64
  end
65
65
  end
66
66
 
67
- #Processes a class which is probably a controller.
68
- #(This method should be retired - only classes should ever be processed
69
- # and @current_module will never be set, leading to inaccurate class names)
67
+ #Skip it, must be an inner class
70
68
  def process_class exp
71
- @current_class = class_name(exp.class_name)
72
- if @current_module
73
- @current_class = ("#@current_module::#@current_class").to_sym
74
- end
75
-
76
- process_default exp
69
+ exp
77
70
  end
78
71
 
79
72
  #Processes a method definition, which may include
@@ -226,7 +219,8 @@ class Brakeman::ControllerAliasProcessor < Brakeman::AliasProcessor
226
219
  while controller
227
220
  filters = get_before_filters(method, controller) + filters
228
221
 
229
- controller = @tracker.controllers[controller[:parent]]
222
+ controller = @tracker.controllers[controller[:parent]] ||
223
+ @tracker.libs[controller[:parent]]
230
224
  end
231
225
 
232
226
  filters
@@ -24,15 +24,6 @@ class Brakeman::ControllerProcessor < Brakeman::BaseProcessor
24
24
  def process_class exp
25
25
  name = class_name(exp.class_name)
26
26
 
27
- if @controller
28
- Brakeman.debug "[Notice] Skipping inner class: #{name}"
29
- return ignore
30
- end
31
-
32
- if @current_module
33
- name = (@current_module.to_s + "::" + name.to_s).to_sym
34
- end
35
-
36
27
  begin
37
28
  parent = class_name exp.parent_name
38
29
  rescue StandardError => e
@@ -40,6 +31,59 @@ class Brakeman::ControllerProcessor < Brakeman::BaseProcessor
40
31
  parent = nil
41
32
  end
42
33
 
34
+ #If inside a real controller, treat any other classes as libraries.
35
+ #But if not inside a controller already, then the class may include
36
+ #a real controller, so we can't take this shortcut.
37
+ if @controller and @controller[:name].to_s.end_with? "Controller"
38
+ Brakeman.debug "[Notice] Treating inner class as library: #{name}"
39
+ Brakeman::LibraryProcessor.new(@tracker).process_library exp, @file_name
40
+ return exp
41
+ end
42
+
43
+ if not name.to_s.end_with? "Controller"
44
+ Brakeman.debug "[Notice] Adding noncontroller as library: #{name}"
45
+
46
+ current_controller = @controller
47
+
48
+ #Set the class to be a module in order to get the right namespacing.
49
+ #Add class to libraries, in case it is needed later (e.g. it's used
50
+ #as a parent class for a controller.)
51
+ #However, still want to process it in this class, so have to set
52
+ #@controller to this not-really-a-controller thing.
53
+ process_module exp do
54
+ name = @current_module
55
+
56
+ if @tracker.libs[name.to_sym]
57
+ @controller = @tracker.libs[name]
58
+ else
59
+ set_controller name, parent, exp
60
+ @tracker.libs[name.to_sym] = @controller
61
+ end
62
+
63
+ process_all exp.body
64
+ end
65
+
66
+ @controller = current_controller
67
+
68
+ return exp
69
+ end
70
+
71
+ if @current_module
72
+ name = (@current_module.to_s + "::" + name.to_s).to_sym
73
+ end
74
+
75
+ set_controller name, parent, exp
76
+
77
+ @tracker.controllers[@controller[:name]] = @controller
78
+
79
+ exp.body = process_all! exp.body
80
+ set_layout_name
81
+
82
+ @controller = nil
83
+ exp
84
+ end
85
+
86
+ def set_controller name, parent, exp
43
87
  @controller = { :name => name,
44
88
  :parent => parent,
45
89
  :includes => [],
@@ -49,11 +93,6 @@ class Brakeman::ControllerProcessor < Brakeman::BaseProcessor
49
93
  :options => {:before_filters => []},
50
94
  :src => exp,
51
95
  :file => @file_name }
52
- @tracker.controllers[@controller[:name]] = @controller
53
- exp.body = process_all! exp.body
54
- set_layout_name
55
- @controller = nil
56
- exp
57
96
  end
58
97
 
59
98
  #Look for specific calls inside the controller