brakeman 1.8.3 → 1.9.0.pre1

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 (63) hide show
  1. data/README.md +3 -27
  2. data/lib/brakeman.rb +36 -38
  3. data/lib/brakeman/app_tree.rb +90 -0
  4. data/lib/brakeman/call_index.rb +5 -38
  5. data/lib/brakeman/checks.rb +11 -11
  6. data/lib/brakeman/checks/base_check.rb +53 -29
  7. data/lib/brakeman/checks/check_cross_site_scripting.rb +11 -9
  8. data/lib/brakeman/checks/check_evaluation.rb +1 -1
  9. data/lib/brakeman/checks/check_execute.rb +3 -3
  10. data/lib/brakeman/checks/check_link_to.rb +15 -13
  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 +27 -13
  14. data/lib/brakeman/checks/check_redirect.rb +4 -4
  15. data/lib/brakeman/checks/check_select_tag.rb +1 -1
  16. data/lib/brakeman/checks/check_select_vulnerability.rb +1 -1
  17. data/lib/brakeman/checks/check_send.rb +2 -2
  18. data/lib/brakeman/checks/check_session_settings.rb +12 -5
  19. data/lib/brakeman/checks/check_single_quotes.rb +3 -3
  20. data/lib/brakeman/checks/check_skip_before_filter.rb +4 -3
  21. data/lib/brakeman/checks/check_sql.rb +30 -30
  22. data/lib/brakeman/checks/check_translate_bug.rb +11 -10
  23. data/lib/brakeman/checks/check_validation_regex.rb +36 -11
  24. data/lib/brakeman/checks/check_without_protection.rb +1 -1
  25. data/lib/brakeman/options.rb +6 -2
  26. data/lib/brakeman/processor.rb +6 -5
  27. data/lib/brakeman/processors/alias_processor.rb +153 -38
  28. data/lib/brakeman/processors/base_processor.rb +16 -21
  29. data/lib/brakeman/processors/controller_alias_processor.rb +24 -11
  30. data/lib/brakeman/processors/controller_processor.rb +25 -25
  31. data/lib/brakeman/processors/erb_template_processor.rb +6 -7
  32. data/lib/brakeman/processors/erubis_template_processor.rb +2 -3
  33. data/lib/brakeman/processors/gem_processor.rb +5 -4
  34. data/lib/brakeman/processors/haml_template_processor.rb +4 -6
  35. data/lib/brakeman/processors/lib/find_all_calls.rb +3 -3
  36. data/lib/brakeman/processors/lib/find_call.rb +2 -2
  37. data/lib/brakeman/processors/lib/find_return_value.rb +134 -0
  38. data/lib/brakeman/processors/lib/processor_helper.rb +24 -2
  39. data/lib/brakeman/processors/lib/rails2_config_processor.rb +13 -14
  40. data/lib/brakeman/processors/lib/rails2_route_processor.rb +9 -4
  41. data/lib/brakeman/processors/lib/rails3_config_processor.rb +8 -8
  42. data/lib/brakeman/processors/lib/rails3_route_processor.rb +23 -21
  43. data/lib/brakeman/processors/lib/render_helper.rb +2 -2
  44. data/lib/brakeman/processors/library_processor.rb +2 -2
  45. data/lib/brakeman/processors/model_processor.rb +16 -12
  46. data/lib/brakeman/processors/output_processor.rb +2 -1
  47. data/lib/brakeman/processors/template_alias_processor.rb +12 -8
  48. data/lib/brakeman/report.rb +28 -14
  49. data/lib/brakeman/rescanner.rb +5 -5
  50. data/lib/brakeman/scanner.rb +56 -94
  51. data/lib/brakeman/templates/header.html.erb +7 -2
  52. data/lib/brakeman/tracker.rb +14 -4
  53. data/lib/brakeman/util.rb +38 -17
  54. data/lib/brakeman/version.rb +1 -1
  55. data/lib/brakeman/warning.rb +14 -6
  56. data/lib/ruby_parser/bm_sexp.rb +157 -57
  57. data/lib/ruby_parser/bm_sexp_processor.rb +1 -2
  58. metadata +26 -25
  59. data/lib/ruby_parser/ruby18_parser.rb +0 -5544
  60. data/lib/ruby_parser/ruby19_parser.rb +0 -5756
  61. data/lib/ruby_parser/ruby_lexer.rb +0 -1349
  62. data/lib/ruby_parser/ruby_parser.rb +0 -5
  63. data/lib/ruby_parser/ruby_parser_extras.rb +0 -1057
@@ -92,7 +92,7 @@ module Brakeman::RenderHelper
92
92
 
93
93
  if hash? options[:locals]
94
94
  hash_iterate options[:locals] do |key, value|
95
- template_env[Sexp.new(:call, nil, key.value, Sexp.new(:arglist))] = value
95
+ template_env[Sexp.new(:call, nil, key.value)] = value
96
96
  end
97
97
  end
98
98
 
@@ -111,7 +111,7 @@ module Brakeman::RenderHelper
111
111
 
112
112
  collection = get_class_target(options[:collection]) || Brakeman::Tracker::UNKNOWN_MODEL
113
113
 
114
- template_env[Sexp.new(:call, nil, variable, Sexp.new(:arglist))] = Sexp.new(:call, Sexp.new(:const, collection), :new, Sexp.new(:arglist))
114
+ template_env[Sexp.new(:call, nil, variable)] = Sexp.new(:call, Sexp.new(:const, collection), :new)
115
115
  end
116
116
 
117
117
  #Set original_line for values so it is clear
@@ -49,7 +49,7 @@ class Brakeman::LibraryProcessor < Brakeman::BaseProcessor
49
49
  @tracker.libs[name] = @current_class
50
50
  end
51
51
 
52
- exp.body = process exp.body
52
+ exp.body = process_all! exp.body
53
53
 
54
54
  if outer_class
55
55
  @current_class = outer_class
@@ -86,7 +86,7 @@ class Brakeman::LibraryProcessor < Brakeman::BaseProcessor
86
86
  @tracker.libs[name] = @current_module
87
87
  end
88
88
 
89
- exp.body = process exp.body
89
+ exp.body = process_all! exp.body
90
90
 
91
91
  if outer_class
92
92
  @current_module = outer_class
@@ -19,7 +19,7 @@ class Brakeman::ModelProcessor < Brakeman::BaseProcessor
19
19
  process src
20
20
  end
21
21
 
22
- #s(:class, NAME, PARENT, s(:scope ...))
22
+ #s(:class, NAME, PARENT, BODY)
23
23
  def process_class exp
24
24
  name = class_name exp.class_name
25
25
 
@@ -44,9 +44,9 @@ class Brakeman::ModelProcessor < Brakeman::BaseProcessor
44
44
  :associations => {},
45
45
  :file => @file_name }
46
46
  @tracker.models[@model[:name]] = @model
47
- res = process exp.body
47
+ exp.body = process_all! exp.body
48
48
  @model = nil
49
- res
49
+ exp
50
50
  end
51
51
  end
52
52
 
@@ -60,12 +60,12 @@ class Brakeman::ModelProcessor < Brakeman::BaseProcessor
60
60
  end
61
61
 
62
62
  method = exp.method
63
- args = exp.args
63
+ first_arg = exp.first_arg
64
64
 
65
65
  #Methods called inside class definition
66
66
  #like attr_* and other settings
67
67
  if @current_method.nil? and target.nil?
68
- if args.empty?
68
+ if first_arg.nil?
69
69
  case method
70
70
  when :private, :protected, :public
71
71
  @visibility = method
@@ -77,11 +77,15 @@ class Brakeman::ModelProcessor < Brakeman::BaseProcessor
77
77
  else
78
78
  case method
79
79
  when :include
80
- @model[:includes] << class_name(args.first) if @model
80
+ @model[:includes] << class_name(first_arg) if @model
81
81
  when :attr_accessible
82
82
  @model[:attr_accessible] ||= []
83
- args = args.map do |e|
84
- e[1]
83
+ args = []
84
+
85
+ exp.each_arg do |e|
86
+ if node_type? e, :lit
87
+ args << e.value
88
+ end
85
89
  end
86
90
 
87
91
  @model[:attr_accessible].concat args
@@ -92,14 +96,14 @@ class Brakeman::ModelProcessor < Brakeman::BaseProcessor
92
96
  @model[:associations][method].concat exp.args
93
97
  else
94
98
  @model[:options][method] ||= []
95
- @model[:options][method] << exp.arglist
99
+ @model[:options][method] << exp.arglist.line(exp.line)
96
100
  end
97
101
  end
98
102
  end
99
103
  end
100
104
  ignore
101
105
  else
102
- call = Sexp.new :call, target, method, process(exp.arglist)
106
+ call = make_call target, method, process_all!(exp.args)
103
107
  call.line(exp.line)
104
108
  call
105
109
  end
@@ -111,7 +115,7 @@ class Brakeman::ModelProcessor < Brakeman::BaseProcessor
111
115
  name = exp.method_name
112
116
 
113
117
  @current_method = name
114
- res = Sexp.new :methdef, name, exp[2], process(exp.body.value)
118
+ res = Sexp.new :methdef, name, exp.formal_args, *process_all!(exp.body)
115
119
  res.line(exp.line)
116
120
  @current_method = nil
117
121
  if @model
@@ -133,7 +137,7 @@ class Brakeman::ModelProcessor < Brakeman::BaseProcessor
133
137
  end
134
138
 
135
139
  @current_method = name
136
- res = Sexp.new :selfdef, target, name, exp[3], process(exp.body.value)
140
+ res = Sexp.new :selfdef, target, name, exp.formal_args, *process_all!(exp.body)
137
141
  res.line(exp.line)
138
142
  @current_method = nil
139
143
  if @model
@@ -14,6 +14,7 @@ class Brakeman::OutputProcessor < Ruby2Ruby
14
14
  end
15
15
 
16
16
  alias process_safely format
17
+ alias process_methdef process_defn
17
18
 
18
19
  def process exp
19
20
  begin
@@ -100,7 +101,7 @@ class Brakeman::OutputProcessor < Ruby2Ruby
100
101
 
101
102
  def process_call_with_block exp
102
103
  call = process exp[0]
103
- block = process exp[1] if exp[1]
104
+ block = process_rlist exp[2..-1]
104
105
  out = "#{call} do\n #{block}\n end"
105
106
  exp.clear
106
107
  out
@@ -1,6 +1,7 @@
1
1
  require 'set'
2
2
  require 'brakeman/processors/alias_processor'
3
3
  require 'brakeman/processors/lib/render_helper'
4
+ require 'brakeman/tracker'
4
5
 
5
6
  #Processes aliasing in templates.
6
7
  #Handles calls to +render+.
@@ -37,32 +38,35 @@ class Brakeman::TemplateAliasProcessor < Brakeman::AliasProcessor
37
38
  name
38
39
  end
39
40
 
41
+ UNKNOWN_MODEL_CALL = Sexp.new(:call, Sexp.new(:const, Brakeman::Tracker::UNKNOWN_MODEL), :new)
42
+ FORM_BUILDER_CALL = Sexp.new(:call, Sexp.new(:const, :FormBuilder), :new)
43
+
40
44
  #Looks for form methods and iterating over collections of Models
41
45
  def process_call_with_block exp
42
46
  process_default exp
43
-
47
+
44
48
  call = exp.block_call
45
49
 
46
50
  if call? call
47
51
  target = call.target
48
52
  method = call.method
49
- args = exp.block_args
53
+ arg = exp.block_args.first_param
50
54
  block = exp.block
51
55
 
52
56
  #Check for e.g. Model.find.each do ... end
53
- if method == :each and args and block and model = get_model_target(target)
54
- if node_type? args, :lasgn
57
+ if method == :each and arg and block and model = get_model_target(target)
58
+ if arg.is_a? Symbol
55
59
  if model == target.target
56
- env[Sexp.new(:lvar, args.lhs)] = Sexp.new(:call, model, :new, Sexp.new(:arglist))
60
+ env[Sexp.new(:lvar, arg)] = Sexp.new(:call, model, :new)
57
61
  else
58
- env[Sexp.new(:lvar, args.lhs)] = Sexp.new(:call, Sexp.new(:const, Brakeman::Tracker::UNKNOWN_MODEL), :new, Sexp.new(:arglist))
62
+ env[Sexp.new(:lvar, arg)] = UNKNOWN_MODEL_CALL
59
63
  end
60
64
 
61
65
  process block if sexp? block
62
66
  end
63
67
  elsif FORM_METHODS.include? method
64
- if node_type? args, :lasgn
65
- env[Sexp.new(:lvar, args.lhs)] = Sexp.new(:call, Sexp.new(:const, :FormBuilder), :new, Sexp.new(:arglist))
68
+ if arg.is_a? Symbol
69
+ env[Sexp.new(:lvar, arg)] = FORM_BUILDER_CALL
66
70
 
67
71
  process block if sexp? block
68
72
  end
@@ -40,7 +40,8 @@ class Brakeman::Report
40
40
  "<span class='med-confidence'>Medium</span>",
41
41
  "<span class='weak-confidence'>Weak</span>" ]
42
42
 
43
- def initialize tracker
43
+ def initialize(app_tree, tracker)
44
+ @app_tree = app_tree
44
45
  @tracker = tracker
45
46
  @checks = tracker.checks
46
47
  @element_id = 0 #Used for HTML ids
@@ -158,7 +159,7 @@ class Brakeman::Report
158
159
  end
159
160
 
160
161
  return nil if warnings.empty?
161
-
162
+
162
163
  stabilizer = 0
163
164
  warnings = warnings.sort_by{|row| stabilizer += 1; [row["Confidence"], row["Warning Type"], row["Template"], stabilizer]}
164
165
  if html
@@ -232,7 +233,7 @@ class Brakeman::Report
232
233
  end
233
234
 
234
235
  return nil if warnings.empty?
235
-
236
+
236
237
  stabilizer = 0
237
238
  warnings = warnings.sort_by{|row| stabilizer +=1; [row["Confidence"], row["Warning Type"], row["Controller"], stabilizer]}
238
239
 
@@ -318,7 +319,7 @@ class Brakeman::Report
318
319
  else
319
320
  output = ''
320
321
  template_rows.each do |template|
321
- output << template.first.to_s << "\n\n"
322
+ output << template.first.to_s << "\n\n"
322
323
  table = Terminal::Table.new(:headings => ['Output']) do |t|
323
324
  # template[1] is an array of calls
324
325
  template[1].each do |v|
@@ -392,7 +393,7 @@ class Brakeman::Report
392
393
  res = generate_controller_warnings
393
394
  out << "\n\n\nController Warnings:\n\n" << truncate_table(res.to_s) if res
394
395
 
395
- res = generate_model_warnings
396
+ res = generate_model_warnings
396
397
  out << "\n\n\nModel Warnings:\n\n" << truncate_table(res.to_s) if res
397
398
 
398
399
  res = generate_template_warnings
@@ -404,8 +405,8 @@ class Brakeman::Report
404
405
 
405
406
  #Generate CSV output
406
407
  def to_csv
407
- output = csv_header
408
- output << "\nSUMMARY\n"
408
+ output = csv_header
409
+ output << "\nSUMMARY\n"
409
410
 
410
411
  output << table_to_csv(generate_overview) << "\n"
411
412
 
@@ -437,7 +438,7 @@ class Brakeman::Report
437
438
  output << table_to_csv(res) << "\n" if res
438
439
 
439
440
  output << "Model Warnings\n"
440
- res = generate_model_warnings
441
+ res = generate_model_warnings
441
442
  output << table_to_csv(res) << "\n" if res
442
443
 
443
444
  res = generate_template_warnings
@@ -475,7 +476,17 @@ class Brakeman::Report
475
476
 
476
477
  #Generate header for text output
477
478
  def text_header
478
- "\n+BRAKEMAN REPORT+\n\nApplication path: #{File.expand_path tracker.options[:app_path]}\nRails version: #{rails_version}\nGenerated at #{Time.now}\nChecks run: #{checks.checks_run.sort.join(", ")}\n"
479
+ <<-HEADER
480
+
481
+ +BRAKEMAN REPORT+
482
+
483
+ Application path: #{File.expand_path tracker.options[:app_path]}
484
+ Rails version: #{rails_version}
485
+ Brakeman version: #{Brakeman::Version}
486
+ Started at #{tracker.start_time}
487
+ Duration: #{tracker.duration} seconds
488
+ Checks run: #{checks.checks_run.sort.join(", ")}
489
+ HEADER
479
490
  end
480
491
 
481
492
  #Generate header for CSV output
@@ -532,11 +543,11 @@ class Brakeman::Report
532
543
 
533
544
  #Generate HTML for warnings, including context show/hidden via Javascript
534
545
  def with_context warning, message
535
- context = context_for warning
546
+ context = context_for(@app_tree, warning)
536
547
  full_message = nil
537
548
 
538
549
  if tracker.options[:message_limit] and
539
- tracker.options[:message_limit] > 0 and
550
+ tracker.options[:message_limit] > 0 and
540
551
  message.length > tracker.options[:message_limit]
541
552
 
542
553
  full_message = html_message(warning, message)
@@ -647,12 +658,12 @@ class Brakeman::Report
647
658
  else
648
659
  w.code = ""
649
660
  end
650
- w.context = context_for(w).join("\n")
661
+ w.context = context_for(@app_tree, w).join("\n")
651
662
  end
652
663
  end
653
664
 
654
665
  report[:config] = tracker.config
655
-
666
+
656
667
  report
657
668
  end
658
669
 
@@ -670,7 +681,10 @@ class Brakeman::Report
670
681
  :app_path => File.expand_path(tracker.options[:app_path]),
671
682
  :rails_version => rails_version,
672
683
  :security_warnings => all_warnings.length,
673
- :timestamp => Time.now.to_s,
684
+ :start_time => tracker.start_time.to_s,
685
+ :end_time => tracker.end_time.to_s,
686
+ :timestamp => tracker.end_time.to_s,
687
+ :duration => tracker.duration,
674
688
  :checks_performed => checks.checks_run.sort,
675
689
  :number_of_controllers =>tracker.controllers.length,
676
690
  # ignore the "fake" model
@@ -12,7 +12,7 @@ class Brakeman::Rescanner < Brakeman::Scanner
12
12
  def initialize options, processor, changed_files
13
13
  super(options, processor)
14
14
 
15
- @paths = changed_files.map {|f| File.expand_path f, tracker.options[:app_path] }
15
+ @paths = changed_files.map {|f| @app_tree.expand_path(f) }
16
16
  @old_results = tracker.checks #Old warnings from previous scan
17
17
  @changes = nil #True if files had to be rescanned
18
18
  @reindex = Set.new
@@ -66,7 +66,7 @@ class Brakeman::Rescanner < Brakeman::Scanner
66
66
  def rescan_file path, type = nil
67
67
  type ||= file_type path
68
68
 
69
- unless File.exist? path
69
+ unless @app_tree.path_exists?(path)
70
70
  return rescan_deleted_file path, type
71
71
  end
72
72
 
@@ -128,7 +128,7 @@ class Brakeman::Rescanner < Brakeman::Scanner
128
128
  end
129
129
 
130
130
  def rescan_template path
131
- return unless path.match KNOWN_TEMPLATE_EXTENSIONS and File.exist? path
131
+ return unless path.match KNOWN_TEMPLATE_EXTENSIONS and @app_tree.path_exists?(path)
132
132
 
133
133
  template_name = template_path_to_name(path)
134
134
 
@@ -177,7 +177,7 @@ class Brakeman::Rescanner < Brakeman::Scanner
177
177
  def rescan_model path
178
178
  num_models = tracker.models.length
179
179
  tracker.reset_model path
180
- process_model path if File.exists? path
180
+ process_model path if @app_tree.path_exists?(path)
181
181
 
182
182
  #Only need to rescan other things if a model is added or removed
183
183
  if num_models != tracker.models.length
@@ -190,7 +190,7 @@ class Brakeman::Rescanner < Brakeman::Scanner
190
190
  end
191
191
 
192
192
  def rescan_lib path
193
- process_lib path if File.exists? path
193
+ process_lib path if @app_tree.path_exists?(path)
194
194
 
195
195
  lib = nil
196
196
 
@@ -1,13 +1,7 @@
1
1
  require 'rubygems'
2
2
  begin
3
- if RUBY_VERSION =~ /^1\.9/
4
- #Load our own version of ruby_parser :'(
5
- require 'ruby_parser/ruby_parser.rb'
6
- else
7
- require 'ruby_parser'
8
- require 'ruby_parser/bm_sexp.rb'
9
- end
10
-
3
+ require 'ruby_parser'
4
+ require 'ruby_parser/bm_sexp.rb'
11
5
  require 'ruby_parser/bm_sexp_processor.rb'
12
6
 
13
7
  require 'haml'
@@ -15,6 +9,7 @@ begin
15
9
  require 'erb'
16
10
  require 'erubis'
17
11
  require 'brakeman/processor'
12
+ require 'brakeman/app_tree'
18
13
  require 'brakeman/parsers/rails2_erubis'
19
14
  require 'brakeman/parsers/rails2_xss_plugin_erubis'
20
15
  require 'brakeman/parsers/rails3_erubis'
@@ -34,23 +29,19 @@ class Brakeman::Scanner
34
29
  #Pass in path to the root of the Rails application
35
30
  def initialize options, processor = nil
36
31
  @options = options
37
- @report_progress = options[:report_progress]
38
- @path = options[:app_path]
39
- @app_path = File.join(@path, "app")
40
- @processor = processor || Brakeman::Processor.new(options)
41
- @skip_files = nil
42
-
43
- #Convert files into Regexp for matching
44
- if options[:skip_files]
45
- list = "(?:" << options[:skip_files].map { |f| Regexp.escape f }.join("|") << ")$"
46
- @skip_files = Regexp.new(list)
32
+ @app_tree = Brakeman::AppTree.from_options(options)
33
+
34
+ if !@app_tree.root || !@app_tree.exists?("app")
35
+ abort("Please supply the path to a Rails application.")
47
36
  end
48
37
 
49
- if RUBY_1_9
50
- @ruby_parser = ::Ruby19Parser
51
- else
52
- @ruby_parser = ::RubyParser
38
+ if @app_tree.exists?("script/rails")
39
+ options[:rails3] = true
40
+ Brakeman.notify "[Notice] Detected Rails 3 application"
53
41
  end
42
+
43
+ @ruby_parser = ::RubyParser
44
+ @processor = processor || Brakeman::Processor.new(@app_tree, options)
54
45
  end
55
46
 
56
47
  #Returns the Tracker generated from the scan
@@ -93,7 +84,7 @@ class Brakeman::Scanner
93
84
  process_config_file "gems.rb"
94
85
  end
95
86
 
96
- if File.exists? "#@path/vendor/plugins/rails_xss" or
87
+ if @app_tree.exists?("vendor/plugins/rails_xss") or
97
88
  options[:rails3] or options[:escape_html]
98
89
 
99
90
  tracker.config[:escape_html] = true
@@ -102,8 +93,10 @@ class Brakeman::Scanner
102
93
  end
103
94
 
104
95
  def process_config_file file
105
- if File.exists? "#@path/config/#{file}"
106
- @processor.process_config(parse_ruby(File.read("#@path/config/#{file}")))
96
+ path = "config/#{file}"
97
+
98
+ if @app_tree.exists?(path)
99
+ @processor.process_config(parse_ruby(@app_tree.read(path)))
107
100
  end
108
101
 
109
102
  rescue Exception => e
@@ -115,11 +108,11 @@ class Brakeman::Scanner
115
108
 
116
109
  #Process Gemfile
117
110
  def process_gems
118
- if File.exists? "#@path/Gemfile"
119
- if File.exists? "#@path/Gemfile.lock"
120
- @processor.process_gems(parse_ruby(File.read("#@path/Gemfile")), File.read("#@path/Gemfile.lock"))
111
+ if @app_tree.exists? "Gemfile"
112
+ if @app_tree.exists? "Gemfile.lock"
113
+ @processor.process_gems(parse_ruby(@app_tree.read("Gemfile")), @app_tree.read("Gemfile.lock"))
121
114
  else
122
- @processor.process_gems(parse_ruby(File.read("#@path/Gemfile")))
115
+ @processor.process_gems(parse_ruby(@app_tree.read("Gemfile")))
123
116
  end
124
117
  end
125
118
  rescue Exception => e
@@ -131,10 +124,7 @@ class Brakeman::Scanner
131
124
  #
132
125
  #Adds parsed information to tracker.initializers
133
126
  def process_initializers
134
- initializer_files = Dir.glob(@path + "/config/initializers/**/*.rb").sort
135
- initializer_files.reject! { |f| @skip_files.match f } if @skip_files
136
-
137
- initializer_files.each do |f|
127
+ @app_tree.initializer_paths.each do |f|
138
128
  process_initializer f
139
129
  end
140
130
  end
@@ -142,7 +132,7 @@ class Brakeman::Scanner
142
132
  #Process an initializer
143
133
  def process_initializer path
144
134
  begin
145
- @processor.process_initializer(path, parse_ruby(File.read(path)))
135
+ @processor.process_initializer(path, parse_ruby(@app_tree.read_path(path)))
146
136
  rescue Racc::ParseError => e
147
137
  tracker.error e, "could not parse #{path}. There is probably a typo in the file. Test it with 'ruby_parse #{path}'"
148
138
  rescue Exception => e
@@ -159,19 +149,13 @@ class Brakeman::Scanner
159
149
  return
160
150
  end
161
151
 
162
- lib_files = Dir.glob(@path + "/lib/**/*.rb").sort
163
- lib_files.reject! { |f| @skip_files.match f } if @skip_files
164
-
165
- total = lib_files.length
152
+ total = @app_tree.lib_paths.length
166
153
  current = 0
167
154
 
168
- lib_files.each do |f|
155
+ @app_tree.lib_paths.each do |f|
169
156
  Brakeman.debug "Processing #{f}"
170
- if @report_progress
171
- $stderr.print " #{current}/#{total} files processed\r"
172
- current += 1
173
- end
174
-
157
+ report_progress(current, total)
158
+ current += 1
175
159
  process_lib f
176
160
  end
177
161
  end
@@ -179,7 +163,7 @@ class Brakeman::Scanner
179
163
  #Process a library
180
164
  def process_lib path
181
165
  begin
182
- @processor.process_lib parse_ruby(File.read(path)), path
166
+ @processor.process_lib parse_ruby(@app_tree.read_path(path)), path
183
167
  rescue Racc::ParseError => e
184
168
  tracker.error e, "could not parse #{path}. There is probably a typo in the file. Test it with 'ruby_parse #{path}'"
185
169
  rescue Exception => e
@@ -191,9 +175,9 @@ class Brakeman::Scanner
191
175
  #
192
176
  #Adds parsed information to tracker.routes
193
177
  def process_routes
194
- if File.exists? "#@path/config/routes.rb"
178
+ if @app_tree.exists?("config/routes.rb")
195
179
  begin
196
- @processor.process_routes parse_ruby(File.read("#@path/config/routes.rb"))
180
+ @processor.process_routes parse_ruby(@app_tree.read("config/routes.rb"))
197
181
  rescue Exception => e
198
182
  tracker.error e.exception(e.message + "\nWhile processing routes.rb"), e.backtrace
199
183
  Brakeman.notify "[Notice] Error while processing routes - assuming all public controller methods are actions."
@@ -208,19 +192,13 @@ class Brakeman::Scanner
208
192
  #
209
193
  #Adds processed controllers to tracker.controllers
210
194
  def process_controllers
211
- controller_files = Dir.glob(@app_path + "/controllers/**/*.rb").sort
212
- controller_files.reject! { |f| @skip_files.match f } if @skip_files
213
-
214
- total = controller_files.length
195
+ total = @app_tree.controller_paths.length
215
196
  current = 0
216
197
 
217
- controller_files.each do |f|
198
+ @app_tree.controller_paths.each do |f|
218
199
  Brakeman.debug "Processing #{f}"
219
- if @report_progress
220
- $stderr.print " #{current}/#{total} files processed\r"
221
- current += 1
222
- end
223
-
200
+ report_progress(current, total)
201
+ current += 1
224
202
  process_controller f
225
203
  end
226
204
 
@@ -231,11 +209,8 @@ class Brakeman::Scanner
231
209
 
232
210
  tracker.controllers.sort_by{|name| name.to_s}.each do |name, controller|
233
211
  Brakeman.debug "Processing #{name}"
234
- if @report_progress
235
- $stderr.print " #{current}/#{total} controllers processed\r"
236
- current += 1
237
- end
238
-
212
+ report_progress(current, total, "controllers")
213
+ current += 1
239
214
  @processor.process_controller_alias name, controller[:src]
240
215
  end
241
216
 
@@ -245,7 +220,7 @@ class Brakeman::Scanner
245
220
 
246
221
  def process_controller path
247
222
  begin
248
- @processor.process_controller(parse_ruby(File.read(path)), path)
223
+ @processor.process_controller(parse_ruby(@app_tree.read_path(path)), path)
249
224
  rescue Racc::ParseError => e
250
225
  tracker.error e, "could not parse #{path}. There is probably a typo in the file. Test it with 'ruby_parse #{path}'"
251
226
  rescue Exception => e
@@ -257,23 +232,15 @@ class Brakeman::Scanner
257
232
  #
258
233
  #Adds processed views to tracker.views
259
234
  def process_templates
260
-
261
- views_path = @app_path + "/views/**/*.{html.erb,html.haml,rhtml,js.erb}"
262
235
  $stdout.sync = true
263
- count = 0
264
236
 
265
- template_files = Dir.glob(views_path).sort
266
- template_files.reject! { |f| @skip_files.match f } if @skip_files
267
-
268
- total = template_files.length
237
+ count = 0
238
+ total = @app_tree.template_paths.length
269
239
 
270
- template_files.each do |path|
240
+ @app_tree.template_paths.each do |path|
271
241
  Brakeman.debug "Processing #{path}"
272
- if @report_progress
273
- $stderr.print " #{count}/#{total} files processed\r"
274
- count += 1
275
- end
276
-
242
+ report_progress(count, total)
243
+ count += 1
277
244
  process_template path
278
245
  end
279
246
 
@@ -284,11 +251,8 @@ class Brakeman::Scanner
284
251
 
285
252
  tracker.templates.keys.dup.sort_by{|name| name.to_s}.each do |name|
286
253
  Brakeman.debug "Processing #{name}"
287
- if @report_progress
288
- count += 1
289
- $stderr.print " #{count}/#{total} templates processed\r"
290
- end
291
-
254
+ report_progress(count, total, "templates")
255
+ count += 1
292
256
  @processor.process_template_alias tracker.templates[name]
293
257
  end
294
258
  end
@@ -297,7 +261,7 @@ class Brakeman::Scanner
297
261
  type = path.match(KNOWN_TEMPLATE_EXTENSIONS)[1].to_sym
298
262
  type = :erb if type == :rhtml
299
263
  name = template_path_to_name path
300
- text = File.read path
264
+ text = @app_tree.read_path path
301
265
 
302
266
  begin
303
267
  if type == :erb
@@ -349,27 +313,20 @@ class Brakeman::Scanner
349
313
  #
350
314
  #Adds the processed models to tracker.models
351
315
  def process_models
352
- model_files = Dir.glob(@app_path + "/models/**/*.rb").sort
353
- model_files.reject! { |f| @skip_files.match f } if @skip_files
354
-
355
- total = model_files.length
316
+ total = @app_tree.model_paths.length
356
317
  current = 0
357
318
 
358
- model_files.each do |f|
319
+ @app_tree.model_paths.each do |f|
359
320
  Brakeman.debug "Processing #{f}"
360
- if @report_progress
361
- $stderr.print " #{current}/#{total} files processed\r"
362
- current += 1
363
- end
364
-
321
+ report_progress(current, total)
322
+ current += 1
365
323
  process_model f
366
-
367
324
  end
368
325
  end
369
326
 
370
327
  def process_model path
371
328
  begin
372
- @processor.process_model(parse_ruby(File.read(path)), path)
329
+ @processor.process_model(parse_ruby(@app_tree.read_path(path)), path)
373
330
  rescue Racc::ParseError => e
374
331
  tracker.error e, "could not parse #{path}"
375
332
  rescue Exception => e
@@ -377,6 +334,11 @@ class Brakeman::Scanner
377
334
  end
378
335
  end
379
336
 
337
+ def report_progress(current, total, type = "files")
338
+ return unless @options[:report_progress]
339
+ $stderr.print " #{current}/#{total} #{type} processed\r"
340
+ end
341
+
380
342
  def index_call_sites
381
343
  tracker.index_call_sites
382
344
  end