brakeman 3.0.5 → 3.1.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.
- checksums.yaml +4 -4
- data/CHANGES +19 -0
- data/README.md +3 -13
- data/lib/brakeman.rb +3 -0
- data/lib/brakeman/checks/base_check.rb +19 -47
- data/lib/brakeman/checks/check_basic_auth.rb +3 -3
- data/lib/brakeman/checks/check_cross_site_scripting.rb +26 -12
- data/lib/brakeman/checks/check_default_routes.rb +1 -1
- data/lib/brakeman/checks/check_detailed_exceptions.rb +2 -2
- data/lib/brakeman/checks/check_evaluation.rb +3 -0
- data/lib/brakeman/checks/check_execute.rb +3 -3
- data/lib/brakeman/checks/check_file_disclosure.rb +2 -2
- data/lib/brakeman/checks/check_forgery_setting.rb +9 -12
- data/lib/brakeman/checks/check_header_dos.rb +1 -1
- data/lib/brakeman/checks/check_i18n_xss.rb +2 -2
- data/lib/brakeman/checks/check_jruby_xml.rb +1 -1
- data/lib/brakeman/checks/check_json_encoding.rb +1 -1
- data/lib/brakeman/checks/check_json_parsing.rb +3 -3
- data/lib/brakeman/checks/check_link_to.rb +1 -1
- data/lib/brakeman/checks/check_link_to_href.rb +9 -2
- data/lib/brakeman/checks/check_mass_assignment.rb +5 -2
- data/lib/brakeman/checks/check_model_attr_accessible.rb +4 -4
- data/lib/brakeman/checks/check_model_attributes.rb +7 -7
- data/lib/brakeman/checks/check_model_serialize.rb +6 -6
- data/lib/brakeman/checks/check_nested_attributes.rb +2 -2
- data/lib/brakeman/checks/check_number_to_currency.rb +2 -2
- data/lib/brakeman/checks/check_quote_table_name.rb +1 -1
- data/lib/brakeman/checks/check_redirect.rb +2 -10
- data/lib/brakeman/checks/check_render.rb +1 -1
- data/lib/brakeman/checks/check_render_dos.rb +1 -1
- data/lib/brakeman/checks/check_safe_buffer_manipulation.rb +1 -1
- data/lib/brakeman/checks/check_sanitize_methods.rb +1 -1
- data/lib/brakeman/checks/check_select_tag.rb +1 -1
- data/lib/brakeman/checks/check_select_vulnerability.rb +2 -2
- data/lib/brakeman/checks/check_session_settings.rb +1 -2
- data/lib/brakeman/checks/check_simple_format.rb +2 -2
- data/lib/brakeman/checks/check_single_quotes.rb +3 -3
- data/lib/brakeman/checks/check_skip_before_filter.rb +5 -7
- data/lib/brakeman/checks/check_sql.rb +10 -14
- data/lib/brakeman/checks/check_sql_cves.rb +4 -4
- data/lib/brakeman/checks/check_ssl_verify.rb +27 -9
- data/lib/brakeman/checks/check_strip_tags.rb +5 -5
- data/lib/brakeman/checks/check_symbol_dos_cve.rb +1 -1
- data/lib/brakeman/checks/check_translate_bug.rb +3 -4
- data/lib/brakeman/checks/check_unscoped_find.rb +1 -1
- data/lib/brakeman/checks/check_validation_regex.rb +2 -2
- data/lib/brakeman/checks/check_xml_dos.rb +1 -1
- data/lib/brakeman/checks/check_yaml_parsing.rb +1 -1
- data/lib/brakeman/file_parser.rb +1 -0
- data/lib/brakeman/parsers/template_parser.rb +6 -5
- data/lib/brakeman/processor.rb +7 -7
- data/lib/brakeman/processors/alias_processor.rb +30 -12
- data/lib/brakeman/processors/base_processor.rb +4 -8
- data/lib/brakeman/processors/controller_alias_processor.rb +33 -132
- data/lib/brakeman/processors/controller_processor.rb +29 -53
- data/lib/brakeman/processors/erb_template_processor.rb +4 -6
- data/lib/brakeman/processors/erubis_template_processor.rb +8 -11
- data/lib/brakeman/processors/gem_processor.rb +19 -35
- data/lib/brakeman/processors/haml_template_processor.rb +10 -12
- data/lib/brakeman/processors/lib/find_all_calls.rb +3 -5
- data/lib/brakeman/processors/lib/find_call.rb +2 -2
- data/lib/brakeman/processors/lib/find_return_value.rb +1 -1
- data/lib/brakeman/processors/lib/rails2_config_processor.rb +7 -8
- data/lib/brakeman/processors/lib/rails3_config_processor.rb +6 -7
- data/lib/brakeman/processors/lib/render_helper.rb +15 -14
- data/lib/brakeman/processors/lib/render_path.rb +11 -5
- data/lib/brakeman/processors/library_processor.rb +13 -35
- data/lib/brakeman/processors/model_processor.rb +22 -64
- data/lib/brakeman/processors/output_processor.rb +1 -37
- data/lib/brakeman/processors/slim_template_processor.rb +6 -8
- data/lib/brakeman/processors/template_alias_processor.rb +9 -9
- data/lib/brakeman/processors/template_processor.rb +5 -9
- data/lib/brakeman/report/report_base.rb +7 -7
- data/lib/brakeman/report/report_html.rb +5 -7
- data/lib/brakeman/report/report_markdown.rb +4 -6
- data/lib/brakeman/report/report_table.rb +4 -6
- data/lib/brakeman/rescanner.rb +29 -31
- data/lib/brakeman/scanner.rb +17 -8
- data/lib/brakeman/tracker.rb +24 -34
- data/lib/brakeman/tracker/collection.rb +77 -0
- data/lib/brakeman/tracker/config.rb +93 -0
- data/lib/brakeman/tracker/controller.rb +161 -0
- data/lib/brakeman/tracker/library.rb +17 -0
- data/lib/brakeman/tracker/model.rb +90 -0
- data/lib/brakeman/tracker/template.rb +33 -0
- data/lib/brakeman/util.rb +17 -9
- data/lib/brakeman/version.rb +1 -1
- data/lib/brakeman/warning.rb +8 -9
- data/lib/ruby_parser/bm_sexp.rb +16 -16
- data/lib/ruby_parser/bm_sexp_processor.rb +1 -120
- metadata +42 -31
- checksums.yaml.gz.sig +0 -1
- data.tar.gz.sig +0 -0
- metadata.gz.sig +0 -0
@@ -14,8 +14,6 @@ class Brakeman::CheckSQL < Brakeman::BaseCheck
|
|
14
14
|
@description = "Check for SQL injection"
|
15
15
|
|
16
16
|
def run_check
|
17
|
-
@rails_version = tracker.config[:rails_version]
|
18
|
-
|
19
17
|
@sql_targets = [:all, :average, :calculate, :count, :count_by_sql, :exists?, :delete_all, :destroy_all,
|
20
18
|
:find, :find_by_sql, :first, :last, :maximum, :minimum, :pluck, :sum, :update_all]
|
21
19
|
@sql_targets.concat [:from, :group, :having, :joins, :lock, :order, :reorder, :select, :where] if tracker.options[:rails3]
|
@@ -84,7 +82,7 @@ class Brakeman::CheckSQL < Brakeman::BaseCheck
|
|
84
82
|
def ar_scope_calls(symbol_name = :named_scope, &block)
|
85
83
|
return_array = []
|
86
84
|
active_record_models.each do |name, model|
|
87
|
-
model_args = model
|
85
|
+
model_args = model.options[symbol_name]
|
88
86
|
if model_args
|
89
87
|
model_args.each do |args|
|
90
88
|
yield name, args
|
@@ -257,7 +255,7 @@ class Brakeman::CheckSQL < Brakeman::BaseCheck
|
|
257
255
|
first_arg = arg[1]
|
258
256
|
|
259
257
|
if node_type? arg, :arglist
|
260
|
-
if arg.length > 2 and
|
258
|
+
if arg.length > 2 and string_interp? first_arg
|
261
259
|
# Model.where("blah = ?", blah)
|
262
260
|
return check_string_interp first_arg
|
263
261
|
else
|
@@ -368,7 +366,7 @@ class Brakeman::CheckSQL < Brakeman::BaseCheck
|
|
368
366
|
|
369
367
|
#Returns value if interpolated value is not something safe
|
370
368
|
def unsafe_string_interp? exp
|
371
|
-
if node_type? exp, :
|
369
|
+
if node_type? exp, :evstr
|
372
370
|
value = exp.value
|
373
371
|
else
|
374
372
|
value = exp
|
@@ -382,7 +380,7 @@ class Brakeman::CheckSQL < Brakeman::BaseCheck
|
|
382
380
|
case value.node_type
|
383
381
|
when :or
|
384
382
|
unsafe_string_interp?(value.lhs) || unsafe_string_interp?(value.rhs)
|
385
|
-
when :
|
383
|
+
when :dstr
|
386
384
|
if dangerous = check_string_interp(value)
|
387
385
|
return dangerous
|
388
386
|
end
|
@@ -421,7 +419,7 @@ class Brakeman::CheckSQL < Brakeman::BaseCheck
|
|
421
419
|
#
|
422
420
|
#and check first value
|
423
421
|
unsafe_sql? exp[1]
|
424
|
-
when :
|
422
|
+
when :dstr
|
425
423
|
check_string_interp exp
|
426
424
|
when :hash
|
427
425
|
check_hash_values exp unless ignore_hash
|
@@ -516,9 +514,7 @@ class Brakeman::CheckSQL < Brakeman::BaseCheck
|
|
516
514
|
end
|
517
515
|
|
518
516
|
def check_interp_target_or_arg target, arg
|
519
|
-
if
|
520
|
-
node_type? arg, :string_interp, :dstr
|
521
|
-
|
517
|
+
if string_interp? target or string_interp? arg
|
522
518
|
check_string_arg target and
|
523
519
|
check_string_arg arg
|
524
520
|
end
|
@@ -529,7 +525,7 @@ class Brakeman::CheckSQL < Brakeman::BaseCheck
|
|
529
525
|
nil
|
530
526
|
elsif string_building? exp
|
531
527
|
check_for_string_building exp
|
532
|
-
elsif
|
528
|
+
elsif string_interp? exp
|
533
529
|
check_string_interp exp
|
534
530
|
elsif call? exp and exp.method == :to_s
|
535
531
|
check_string_arg exp.target
|
@@ -541,8 +537,8 @@ class Brakeman::CheckSQL < Brakeman::BaseCheck
|
|
541
537
|
def string_building? exp
|
542
538
|
return false unless call? exp and STRING_METHODS.include? exp.method
|
543
539
|
|
544
|
-
node_type? exp.target, :str, :dstr
|
545
|
-
node_type? exp.first_arg, :str, :dstr
|
540
|
+
node_type? exp.target, :str, :dstr or
|
541
|
+
node_type? exp.first_arg, :str, :dstr or
|
546
542
|
string_building? exp.target or
|
547
543
|
string_building? exp.first_arg
|
548
544
|
end
|
@@ -614,7 +610,7 @@ class Brakeman::CheckSQL < Brakeman::BaseCheck
|
|
614
610
|
#
|
615
611
|
#http://www.rorsecurity.info/2008/09/08/sql-injection-issue-in-limit-and-offset-parameter/
|
616
612
|
def check_for_limit_or_offset_vulnerability options
|
617
|
-
return false if
|
613
|
+
return false if rails_version.nil? or rails_version >= "2.1.1" or not hash?(options)
|
618
614
|
|
619
615
|
return true if hash_access(options, :limit) or hash_access(options, :offset)
|
620
616
|
|
@@ -48,7 +48,7 @@ class Brakeman::CheckSQLCVEs < Brakeman::BaseCheck
|
|
48
48
|
}
|
49
49
|
end
|
50
50
|
|
51
|
-
if tracker.config
|
51
|
+
if tracker.config.has_gem? :pg
|
52
52
|
issues << {
|
53
53
|
:cve => "CVE-2014-3482",
|
54
54
|
:versions => [%w[2.0.0 2.9.9 3.2.19], %w[3.0.0 3.2.18 3.2.19], %w[4.0.0 4.0.6 4.0.7], %w[4.1.0 4.1.2 4.1.3]],
|
@@ -73,7 +73,7 @@ class Brakeman::CheckSQLCVEs < Brakeman::BaseCheck
|
|
73
73
|
|
74
74
|
warn :warning_type => 'SQL Injection',
|
75
75
|
:warning_code => code,
|
76
|
-
:message => "Rails #{
|
76
|
+
:message => "Rails #{rails_version} contains a SQL injection vulnerability (#{cve}). Upgrade to #{upgrade_version}",
|
77
77
|
:confidence => CONFIDENCE[:high],
|
78
78
|
:gem_info => gemfile_or_environment,
|
79
79
|
:link_path => link
|
@@ -89,11 +89,11 @@ class Brakeman::CheckSQLCVEs < Brakeman::BaseCheck
|
|
89
89
|
|
90
90
|
def check_cve_2014_0080
|
91
91
|
return unless version_between? "4.0.0", "4.0.2" and
|
92
|
-
@tracker.config
|
92
|
+
@tracker.config.has_gem? :pg
|
93
93
|
|
94
94
|
warn :warning_type => 'SQL Injection',
|
95
95
|
:warning_code => :CVE_2014_0080,
|
96
|
-
:message => "Rails #{
|
96
|
+
:message => "Rails #{rails_version} contains a SQL injection vulnerability (CVE-2014-0080) with PostgreSQL. Upgrade to 4.0.3",
|
97
97
|
:confidence => CONFIDENCE[:high],
|
98
98
|
:gem_info => gemfile_or_environment(:pg),
|
99
99
|
:link_path => "https://groups.google.com/d/msg/rubyonrails-security/Wu96YkTUR6s/pPLBMZrlwvYJ"
|
@@ -11,21 +11,39 @@ class Brakeman::CheckSSLVerify < Brakeman::BaseCheck
|
|
11
11
|
|
12
12
|
def run_check
|
13
13
|
check_open_ssl_verify_none
|
14
|
+
check_http_start
|
14
15
|
end
|
15
16
|
|
16
17
|
def check_open_ssl_verify_none
|
17
|
-
tracker.find_call(:method => :verify_mode=).each {|call|
|
18
|
+
tracker.find_call(:method => :verify_mode=).each {|call| process_verify_mode_result(call) }
|
18
19
|
end
|
19
20
|
|
20
|
-
def
|
21
|
-
return if duplicate?(result)
|
21
|
+
def process_verify_mode_result result
|
22
22
|
if result[:call].last_arg == SSL_VERIFY_NONE
|
23
|
-
|
24
|
-
warn :result => result,
|
25
|
-
:warning_type => "SSL Verification Bypass",
|
26
|
-
:warning_code => :ssl_verification_bypass,
|
27
|
-
:message => "SSL certificate verification was bypassed",
|
28
|
-
:confidence => CONFIDENCE[:high]
|
23
|
+
warn_about_ssl_verification_bypass result
|
29
24
|
end
|
30
25
|
end
|
26
|
+
|
27
|
+
def check_http_start
|
28
|
+
tracker.find_call(:target => :'Net::HTTP', :method => :start).each { |call| process_http_start_result call }
|
29
|
+
end
|
30
|
+
|
31
|
+
def process_http_start_result result
|
32
|
+
arg = result[:call].last_arg
|
33
|
+
|
34
|
+
if hash? arg and hash_access(arg, :verify_mode) == SSL_VERIFY_NONE
|
35
|
+
warn_about_ssl_verification_bypass result
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def warn_about_ssl_verification_bypass result
|
40
|
+
return if duplicate?(result)
|
41
|
+
add_result result
|
42
|
+
|
43
|
+
warn :result => result,
|
44
|
+
:warning_type => "SSL Verification Bypass",
|
45
|
+
:warning_code => :ssl_verification_bypass,
|
46
|
+
:message => "SSL certificate verification was bypassed",
|
47
|
+
:confidence => CONFIDENCE[:high]
|
48
|
+
end
|
31
49
|
end
|
@@ -19,7 +19,7 @@ class Brakeman::CheckStripTags < Brakeman::BaseCheck
|
|
19
19
|
|
20
20
|
def cve_2011_2931
|
21
21
|
if version_between?('2.0.0', '2.3.12') or version_between?('3.0.0', '3.0.9')
|
22
|
-
if
|
22
|
+
if rails_version =~ /^3/
|
23
23
|
message = "Versions before 3.0.10 have a vulnerability in strip_tags (CVE-2011-2931)"
|
24
24
|
else
|
25
25
|
message = "Versions before 2.3.13 have a vulnerability in strip_tags (CVE-2011-2931)"
|
@@ -36,14 +36,14 @@ class Brakeman::CheckStripTags < Brakeman::BaseCheck
|
|
36
36
|
|
37
37
|
def cve_2012_3465
|
38
38
|
case
|
39
|
-
when (version_between?('2.0.0', '2.3.14') and tracker.config
|
39
|
+
when (version_between?('2.0.0', '2.3.14') and tracker.config.escape_html?)
|
40
40
|
message = "All Rails 2.x versions have a vulnerability in strip_tags (CVE-2012-3465)"
|
41
41
|
when version_between?('3.0.10', '3.0.16')
|
42
|
-
message = "Rails #{
|
42
|
+
message = "Rails #{rails_version} has a vulnerability in strip_tags (CVE-2012-3465). Upgrade to 3.0.17"
|
43
43
|
when version_between?('3.1.0', '3.1.7')
|
44
|
-
message = "Rails #{
|
44
|
+
message = "Rails #{rails_version} has a vulnerability in strip_tags (CVE-2012-3465). Upgrade to 3.1.8"
|
45
45
|
when version_between?('3.2.0', '3.2.7')
|
46
|
-
message = "Rails #{
|
46
|
+
message = "Rails #{rails_version} has a vulnerability in strip_tags (CVE-2012-3465). Upgrade to 3.2.8"
|
47
47
|
else
|
48
48
|
return
|
49
49
|
end
|
@@ -20,7 +20,7 @@ class Brakeman::CheckSymbolDoSCVE < Brakeman::BaseCheck
|
|
20
20
|
if fix_version && active_record_models.any?
|
21
21
|
warn :warning_type => "Denial of Service",
|
22
22
|
:warning_code => :CVE_2013_1854,
|
23
|
-
:message => "Rails #{
|
23
|
+
:message => "Rails #{rails_version} has a denial of service vulnerability in ActiveRecord: upgrade to #{fix_version} or patch",
|
24
24
|
:confidence => CONFIDENCE[:med],
|
25
25
|
:gem_info => gemfile_or_environment,
|
26
26
|
:link => "https://groups.google.com/d/msg/rubyonrails-security/jgJ4cjjS8FE/BGbHRxnDRTIJ"
|
@@ -8,7 +8,7 @@ class Brakeman::CheckTranslateBug < Brakeman::BaseCheck
|
|
8
8
|
|
9
9
|
def run_check
|
10
10
|
return if lts_version? '2.3.18.6'
|
11
|
-
if (version_between?('2.3.0', '2.3.99') and tracker.config
|
11
|
+
if (version_between?('2.3.0', '2.3.99') and tracker.config.escape_html?) or
|
12
12
|
version_between?('3.0.0', '3.0.10') or
|
13
13
|
version_between?('3.1.0', '3.1.1')
|
14
14
|
|
@@ -18,12 +18,11 @@ class Brakeman::CheckTranslateBug < Brakeman::BaseCheck
|
|
18
18
|
CONFIDENCE[:med]
|
19
19
|
end
|
20
20
|
|
21
|
-
version = tracker.config[:rails_version]
|
22
21
|
description = "have a vulnerability in the translate helper with keys ending in _html"
|
23
22
|
|
24
|
-
message = if
|
23
|
+
message = if rails_version =~ /^3\.1/
|
25
24
|
"Versions before 3.1.2 #{description}."
|
26
|
-
elsif
|
25
|
+
elsif rails_version =~ /^3\.0/
|
27
26
|
"Versions before 3.0.11 #{description}."
|
28
27
|
else
|
29
28
|
"Rails 2.3.x using the rails_xss plugin #{description}."
|
@@ -10,7 +10,7 @@ class Brakeman::CheckUnscopedFind < Brakeman::BaseCheck
|
|
10
10
|
Brakeman.debug("Finding instances of #find on models with associations")
|
11
11
|
|
12
12
|
associated_model_names = active_record_models.keys.select do |name|
|
13
|
-
active_record_models[name]
|
13
|
+
active_record_models[name].associations[:belongs_to]
|
14
14
|
end
|
15
15
|
|
16
16
|
calls = tracker.find_call :method => [:find, :find_by_id, :find_by_id!],
|
@@ -18,7 +18,7 @@ class Brakeman::CheckValidationRegex < Brakeman::BaseCheck
|
|
18
18
|
def run_check
|
19
19
|
active_record_models.each do |name, model|
|
20
20
|
@current_model = name
|
21
|
-
format_validations = model
|
21
|
+
format_validations = model.options[:validates_format_of]
|
22
22
|
|
23
23
|
if format_validations
|
24
24
|
format_validations.each do |v|
|
@@ -26,7 +26,7 @@ class Brakeman::CheckValidationRegex < Brakeman::BaseCheck
|
|
26
26
|
end
|
27
27
|
end
|
28
28
|
|
29
|
-
validates = model
|
29
|
+
validates = model.options[:validates]
|
30
30
|
|
31
31
|
if validates
|
32
32
|
validates.each do |v|
|
@@ -6,7 +6,7 @@ class Brakeman::CheckXMLDoS < Brakeman::BaseCheck
|
|
6
6
|
@description = "Checks for XML denial of service (CVE-2015-3227)"
|
7
7
|
|
8
8
|
def run_check
|
9
|
-
version =
|
9
|
+
version = rails_version
|
10
10
|
|
11
11
|
fix_version = case
|
12
12
|
when version_between?("2.0.0", "3.2.21")
|
@@ -22,7 +22,7 @@ class Brakeman::CheckYAMLParsing < Brakeman::BaseCheck
|
|
22
22
|
"3.2.11"
|
23
23
|
end
|
24
24
|
|
25
|
-
message = "Rails #{
|
25
|
+
message = "Rails #{rails_version} has a remote code execution vulnerability: upgrade to #{new_version} or disable XML parsing"
|
26
26
|
|
27
27
|
warn :warning_type => "Remote Code Execution",
|
28
28
|
:warning_code => :CVE_2013_0156,
|
data/lib/brakeman/file_parser.rb
CHANGED
@@ -16,6 +16,7 @@ module Brakeman
|
|
16
16
|
type = path.match(KNOWN_TEMPLATE_EXTENSIONS)[1].to_sym
|
17
17
|
type = :erb if type == :rhtml
|
18
18
|
name = template_path_to_name path
|
19
|
+
Brakeman.debug "Parsing #{path}"
|
19
20
|
|
20
21
|
begin
|
21
22
|
src = case type
|
@@ -46,7 +47,7 @@ module Brakeman
|
|
46
47
|
end
|
47
48
|
|
48
49
|
def parse_erb text
|
49
|
-
if tracker.config
|
50
|
+
if tracker.config.escape_html?
|
50
51
|
if tracker.options[:rails3]
|
51
52
|
require 'brakeman/parsers/rails3_erubis'
|
52
53
|
Brakeman::Rails3Erubis.new(text).src
|
@@ -54,7 +55,7 @@ module Brakeman
|
|
54
55
|
require 'brakeman/parsers/rails2_xss_plugin_erubis'
|
55
56
|
Brakeman::Rails2XSSPluginErubis.new(text).src
|
56
57
|
end
|
57
|
-
elsif tracker.config
|
58
|
+
elsif tracker.config.erubis?
|
58
59
|
require 'brakeman/parsers/rails2_erubis'
|
59
60
|
Brakeman::ScannerErubis.new(text).src
|
60
61
|
else
|
@@ -66,8 +67,8 @@ module Brakeman
|
|
66
67
|
end
|
67
68
|
|
68
69
|
def erubis?
|
69
|
-
tracker.config
|
70
|
-
|
70
|
+
tracker.config.escape_html? or
|
71
|
+
tracker.config.erubis?
|
71
72
|
end
|
72
73
|
|
73
74
|
def parse_haml text
|
@@ -75,7 +76,7 @@ module Brakeman
|
|
75
76
|
Brakeman.load_brakeman_dependency 'sass'
|
76
77
|
|
77
78
|
Haml::Engine.new(text,
|
78
|
-
:escape_html =>
|
79
|
+
:escape_html => tracker.config.escape_html?).precompiled.gsub(/([^\\])\\n/, '\1')
|
79
80
|
end
|
80
81
|
|
81
82
|
def parse_slim text
|
data/lib/brakeman/processor.rb
CHANGED
@@ -27,8 +27,8 @@ module Brakeman
|
|
27
27
|
end
|
28
28
|
|
29
29
|
#Process Gemfile
|
30
|
-
def process_gems
|
31
|
-
GemProcessor.new(@tracker).process_gems
|
30
|
+
def process_gems gem_files
|
31
|
+
GemProcessor.new(@tracker).process_gems gem_files
|
32
32
|
end
|
33
33
|
|
34
34
|
#Process route file source
|
@@ -47,8 +47,8 @@ module Brakeman
|
|
47
47
|
|
48
48
|
#Process variable aliasing in controller source and save it in the
|
49
49
|
#tracker.
|
50
|
-
def process_controller_alias name, src, only_method = nil
|
51
|
-
ControllerAliasProcessor.new(@app_tree, @tracker, only_method).process_controller name, src
|
50
|
+
def process_controller_alias name, src, only_method = nil, file = nil
|
51
|
+
ControllerAliasProcessor.new(@app_tree, @tracker, only_method).process_controller name, src, file
|
52
52
|
end
|
53
53
|
|
54
54
|
#Process a model source
|
@@ -78,13 +78,13 @@ module Brakeman
|
|
78
78
|
name = ("#{name}.#{called_from}").to_sym
|
79
79
|
end
|
80
80
|
|
81
|
-
@tracker.templates[name]
|
82
|
-
@tracker.templates[name]
|
81
|
+
@tracker.templates[name].src = result
|
82
|
+
@tracker.templates[name].type = type
|
83
83
|
end
|
84
84
|
|
85
85
|
#Process any calls to render() within a template
|
86
86
|
def process_template_alias template
|
87
|
-
TemplateAliasProcessor.new(@tracker, template).process_safely template
|
87
|
+
TemplateAliasProcessor.new(@tracker, template).process_safely template.src
|
88
88
|
end
|
89
89
|
|
90
90
|
#Process source for initializing files
|
@@ -9,7 +9,7 @@ class Brakeman::AliasProcessor < Brakeman::SexpProcessor
|
|
9
9
|
include Brakeman::ProcessorHelper
|
10
10
|
include Brakeman::Util
|
11
11
|
|
12
|
-
attr_reader :result
|
12
|
+
attr_reader :result, :tracker
|
13
13
|
|
14
14
|
#Returns a new AliasProcessor with an empty environment.
|
15
15
|
#
|
@@ -74,9 +74,13 @@ class Brakeman::AliasProcessor < Brakeman::SexpProcessor
|
|
74
74
|
result
|
75
75
|
end
|
76
76
|
|
77
|
+
ARRAY_CONST = s(:const, :Array)
|
78
|
+
HASH_CONST = s(:const, :Hash)
|
79
|
+
|
77
80
|
#Process a method call.
|
78
81
|
def process_call exp
|
79
82
|
target_var = exp.target
|
83
|
+
target_var &&= target_var.deep_clone
|
80
84
|
exp = process_default exp
|
81
85
|
|
82
86
|
#In case it is replaced with something else
|
@@ -95,6 +99,10 @@ class Brakeman::AliasProcessor < Brakeman::SexpProcessor
|
|
95
99
|
if node_type? target, :or and [:+, :-, :*, :/].include? method
|
96
100
|
res = process_or_simple_operation(exp)
|
97
101
|
return res if res
|
102
|
+
elsif target == ARRAY_CONST and method == :new
|
103
|
+
return Sexp.new(:array, *exp.args)
|
104
|
+
elsif target == HASH_CONST and method == :new and first_arg.nil? and !node_type?(@exp_context.last, :iter)
|
105
|
+
return Sexp.new(:hash)
|
98
106
|
end
|
99
107
|
|
100
108
|
#See if it is possible to simplify some basic cases
|
@@ -159,21 +167,36 @@ class Brakeman::AliasProcessor < Brakeman::SexpProcessor
|
|
159
167
|
target.value << first_arg.value
|
160
168
|
env[target_var] = target
|
161
169
|
return target
|
170
|
+
elsif string? target and string_interp? first_arg
|
171
|
+
exp = Sexp.new(:dstr, target.value + first_arg[1]).concat(first_arg[2..-1])
|
172
|
+
env[target_var] = exp
|
173
|
+
elsif string? first_arg and string_interp? target
|
174
|
+
if string? target.last
|
175
|
+
target.last.value << first_arg.value
|
176
|
+
elsif target.last.is_a? String
|
177
|
+
target.last << first_arg.value
|
178
|
+
else
|
179
|
+
target << first_arg
|
180
|
+
end
|
181
|
+
env[target_var] = target
|
182
|
+
return first_arg
|
162
183
|
elsif array? target
|
163
184
|
target << first_arg
|
164
185
|
env[target_var] = target
|
165
186
|
return target
|
166
187
|
else
|
167
|
-
target = find_push_target
|
168
|
-
env[target] = exp unless target.nil? #Happens in TemplateAliasProcessor
|
188
|
+
target = find_push_target(target_var)
|
189
|
+
env[target] = exp unless target.nil? # Happens in TemplateAliasProcessor
|
169
190
|
end
|
170
191
|
end
|
171
192
|
|
172
193
|
exp
|
173
194
|
end
|
174
195
|
|
175
|
-
def
|
196
|
+
def process_iter exp
|
197
|
+
@exp_context.push exp
|
176
198
|
exp[1] = process exp.block_call
|
199
|
+
@exp_context.pop
|
177
200
|
|
178
201
|
env.scope do
|
179
202
|
exp.block_args.each do |e|
|
@@ -207,8 +230,6 @@ class Brakeman::AliasProcessor < Brakeman::SexpProcessor
|
|
207
230
|
exp
|
208
231
|
end
|
209
232
|
|
210
|
-
alias process_iter process_call_with_block
|
211
|
-
|
212
233
|
#Process a new scope.
|
213
234
|
def process_scope exp
|
214
235
|
env.scope do
|
@@ -225,7 +246,7 @@ class Brakeman::AliasProcessor < Brakeman::SexpProcessor
|
|
225
246
|
end
|
226
247
|
|
227
248
|
#Process a method definition.
|
228
|
-
def
|
249
|
+
def process_defn exp
|
229
250
|
meth_env do
|
230
251
|
exp.body = process_all! exp.body
|
231
252
|
end
|
@@ -245,7 +266,7 @@ class Brakeman::AliasProcessor < Brakeman::SexpProcessor
|
|
245
266
|
end
|
246
267
|
|
247
268
|
#Process a method definition on self.
|
248
|
-
def
|
269
|
+
def process_defs exp
|
249
270
|
env.scope do
|
250
271
|
set_env_defaults
|
251
272
|
exp.body = process_all! exp.body
|
@@ -253,9 +274,6 @@ class Brakeman::AliasProcessor < Brakeman::SexpProcessor
|
|
253
274
|
exp
|
254
275
|
end
|
255
276
|
|
256
|
-
alias process_defn process_methdef
|
257
|
-
alias process_defs process_selfdef
|
258
|
-
|
259
277
|
#Local assignment
|
260
278
|
# x = 1
|
261
279
|
def process_lasgn exp
|
@@ -821,7 +839,7 @@ class Brakeman::AliasProcessor < Brakeman::SexpProcessor
|
|
821
839
|
def top_target exp, last = nil
|
822
840
|
if call? exp
|
823
841
|
top_target exp.target, exp
|
824
|
-
elsif node_type? exp, :iter
|
842
|
+
elsif node_type? exp, :iter
|
825
843
|
top_target exp.block_call, last
|
826
844
|
else
|
827
845
|
exp || last
|