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.
- data/README.md +3 -27
- data/lib/brakeman.rb +36 -38
- data/lib/brakeman/app_tree.rb +90 -0
- data/lib/brakeman/call_index.rb +5 -38
- data/lib/brakeman/checks.rb +11 -11
- data/lib/brakeman/checks/base_check.rb +53 -29
- data/lib/brakeman/checks/check_cross_site_scripting.rb +11 -9
- data/lib/brakeman/checks/check_evaluation.rb +1 -1
- data/lib/brakeman/checks/check_execute.rb +3 -3
- data/lib/brakeman/checks/check_link_to.rb +15 -13
- data/lib/brakeman/checks/check_link_to_href.rb +1 -1
- data/lib/brakeman/checks/check_mail_to.rb +1 -1
- data/lib/brakeman/checks/check_mass_assignment.rb +27 -13
- data/lib/brakeman/checks/check_redirect.rb +4 -4
- data/lib/brakeman/checks/check_select_tag.rb +1 -1
- data/lib/brakeman/checks/check_select_vulnerability.rb +1 -1
- data/lib/brakeman/checks/check_send.rb +2 -2
- data/lib/brakeman/checks/check_session_settings.rb +12 -5
- data/lib/brakeman/checks/check_single_quotes.rb +3 -3
- data/lib/brakeman/checks/check_skip_before_filter.rb +4 -3
- data/lib/brakeman/checks/check_sql.rb +30 -30
- data/lib/brakeman/checks/check_translate_bug.rb +11 -10
- data/lib/brakeman/checks/check_validation_regex.rb +36 -11
- data/lib/brakeman/checks/check_without_protection.rb +1 -1
- data/lib/brakeman/options.rb +6 -2
- data/lib/brakeman/processor.rb +6 -5
- data/lib/brakeman/processors/alias_processor.rb +153 -38
- data/lib/brakeman/processors/base_processor.rb +16 -21
- data/lib/brakeman/processors/controller_alias_processor.rb +24 -11
- data/lib/brakeman/processors/controller_processor.rb +25 -25
- data/lib/brakeman/processors/erb_template_processor.rb +6 -7
- data/lib/brakeman/processors/erubis_template_processor.rb +2 -3
- data/lib/brakeman/processors/gem_processor.rb +5 -4
- data/lib/brakeman/processors/haml_template_processor.rb +4 -6
- data/lib/brakeman/processors/lib/find_all_calls.rb +3 -3
- data/lib/brakeman/processors/lib/find_call.rb +2 -2
- data/lib/brakeman/processors/lib/find_return_value.rb +134 -0
- data/lib/brakeman/processors/lib/processor_helper.rb +24 -2
- data/lib/brakeman/processors/lib/rails2_config_processor.rb +13 -14
- data/lib/brakeman/processors/lib/rails2_route_processor.rb +9 -4
- data/lib/brakeman/processors/lib/rails3_config_processor.rb +8 -8
- data/lib/brakeman/processors/lib/rails3_route_processor.rb +23 -21
- data/lib/brakeman/processors/lib/render_helper.rb +2 -2
- data/lib/brakeman/processors/library_processor.rb +2 -2
- data/lib/brakeman/processors/model_processor.rb +16 -12
- data/lib/brakeman/processors/output_processor.rb +2 -1
- data/lib/brakeman/processors/template_alias_processor.rb +12 -8
- data/lib/brakeman/report.rb +28 -14
- data/lib/brakeman/rescanner.rb +5 -5
- data/lib/brakeman/scanner.rb +56 -94
- data/lib/brakeman/templates/header.html.erb +7 -2
- data/lib/brakeman/tracker.rb +14 -4
- data/lib/brakeman/util.rb +38 -17
- data/lib/brakeman/version.rb +1 -1
- data/lib/brakeman/warning.rb +14 -6
- data/lib/ruby_parser/bm_sexp.rb +157 -57
- data/lib/ruby_parser/bm_sexp_processor.rb +1 -2
- metadata +26 -25
- data/lib/ruby_parser/ruby18_parser.rb +0 -5544
- data/lib/ruby_parser/ruby19_parser.rb +0 -5756
- data/lib/ruby_parser/ruby_lexer.rb +0 -1349
- data/lib/ruby_parser/ruby_parser.rb +0 -5
- 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
|
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
|
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 =
|
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 =
|
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,
|
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
|
-
|
47
|
+
exp.body = process_all! exp.body
|
48
48
|
@model = nil
|
49
|
-
|
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
|
-
|
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
|
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(
|
80
|
+
@model[:includes] << class_name(first_arg) if @model
|
81
81
|
when :attr_accessible
|
82
82
|
@model[:attr_accessible] ||= []
|
83
|
-
args =
|
84
|
-
|
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 =
|
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
|
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
|
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 =
|
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
|
-
|
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
|
54
|
-
if
|
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,
|
60
|
+
env[Sexp.new(:lvar, arg)] = Sexp.new(:call, model, :new)
|
57
61
|
else
|
58
|
-
env[Sexp.new(:lvar,
|
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
|
65
|
-
env[Sexp.new(:lvar,
|
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
|
data/lib/brakeman/report.rb
CHANGED
@@ -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
|
-
|
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
|
-
:
|
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
|
data/lib/brakeman/rescanner.rb
CHANGED
@@ -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|
|
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
|
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
|
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
|
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
|
193
|
+
process_lib path if @app_tree.path_exists?(path)
|
194
194
|
|
195
195
|
lib = nil
|
196
196
|
|
data/lib/brakeman/scanner.rb
CHANGED
@@ -1,13 +1,7 @@
|
|
1
1
|
require 'rubygems'
|
2
2
|
begin
|
3
|
-
|
4
|
-
|
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
|
-
@
|
38
|
-
|
39
|
-
|
40
|
-
|
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
|
50
|
-
|
51
|
-
|
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
|
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
|
-
|
106
|
-
|
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
|
119
|
-
if
|
120
|
-
@processor.process_gems(parse_ruby(
|
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(
|
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
|
-
|
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(
|
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
|
-
|
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
|
-
|
155
|
+
@app_tree.lib_paths.each do |f|
|
169
156
|
Brakeman.debug "Processing #{f}"
|
170
|
-
|
171
|
-
|
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(
|
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
|
178
|
+
if @app_tree.exists?("config/routes.rb")
|
195
179
|
begin
|
196
|
-
@processor.process_routes parse_ruby(
|
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
|
-
|
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
|
-
|
198
|
+
@app_tree.controller_paths.each do |f|
|
218
199
|
Brakeman.debug "Processing #{f}"
|
219
|
-
|
220
|
-
|
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
|
-
|
235
|
-
|
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(
|
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
|
-
|
266
|
-
|
267
|
-
|
268
|
-
total = template_files.length
|
237
|
+
count = 0
|
238
|
+
total = @app_tree.template_paths.length
|
269
239
|
|
270
|
-
|
240
|
+
@app_tree.template_paths.each do |path|
|
271
241
|
Brakeman.debug "Processing #{path}"
|
272
|
-
|
273
|
-
|
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
|
-
|
288
|
-
|
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 =
|
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
|
-
|
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
|
-
|
319
|
+
@app_tree.model_paths.each do |f|
|
359
320
|
Brakeman.debug "Processing #{f}"
|
360
|
-
|
361
|
-
|
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(
|
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
|