brakeman-min 2.6.1 → 2.6.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. checksums.yaml +15 -0
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/CHANGES +14 -0
  5. data/bin/brakeman +3 -3
  6. data/lib/brakeman.rb +17 -4
  7. data/lib/brakeman/app_tree.rb +1 -1
  8. data/lib/brakeman/checks.rb +8 -1
  9. data/lib/brakeman/checks/base_check.rb +1 -2
  10. data/lib/brakeman/checks/check_create_with.rb +75 -0
  11. data/lib/brakeman/checks/check_default_routes.rb +3 -3
  12. data/lib/brakeman/checks/check_i18n_xss.rb +1 -1
  13. data/lib/brakeman/checks/check_json_parsing.rb +1 -1
  14. data/lib/brakeman/checks/check_redirect.rb +0 -1
  15. data/lib/brakeman/checks/check_send.rb +17 -4
  16. data/lib/brakeman/checks/check_session_settings.rb +14 -11
  17. data/lib/brakeman/checks/check_sql.rb +22 -13
  18. data/lib/brakeman/checks/check_sql_cves.rb +1 -1
  19. data/lib/brakeman/checks/check_symbol_dos.rb +10 -1
  20. data/lib/brakeman/options.rb +11 -1
  21. data/lib/brakeman/parsers/rails3_erubis.rb +0 -8
  22. data/lib/brakeman/parsers/template_parser.rb +1 -1
  23. data/lib/brakeman/processors/gem_processor.rb +9 -3
  24. data/lib/brakeman/processors/output_processor.rb +0 -7
  25. data/lib/brakeman/report/report_base.rb +10 -3
  26. data/lib/brakeman/report/report_csv.rb +1 -1
  27. data/lib/brakeman/report/report_hash.rb +1 -0
  28. data/lib/brakeman/report/report_json.rb +1 -2
  29. data/lib/brakeman/report/report_markdown.rb +1 -1
  30. data/lib/brakeman/report/report_table.rb +1 -1
  31. data/lib/brakeman/report/templates/header.html.erb +1 -1
  32. data/lib/brakeman/scanner.rb +16 -9
  33. data/lib/brakeman/tracker.rb +5 -1
  34. data/lib/brakeman/util.rb +3 -3
  35. data/lib/brakeman/version.rb +1 -1
  36. data/lib/brakeman/warning_codes.rb +2 -0
  37. data/lib/ruby_parser/bm_sexp.rb +8 -1
  38. metadata +30 -22
  39. metadata.gz.sig +0 -0
checksums.yaml ADDED
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ NWQwMWVmZTI2M2Y5MzlkNjhjYTEyMjQ5NmEyZmNkYjIzNGNlNTZjYw==
5
+ data.tar.gz: !binary |-
6
+ MDk0MTg3MzczNjgwNDRjNGI4YWIwNDc2NDQzOGVmNzIyNzM4MGY0Mw==
7
+ SHA512:
8
+ metadata.gz: !binary |-
9
+ MGQ4N2ZlZmMwM2U5N2JhOTgxN2I5ZDA5ZWYxNjk1MmJkYWM0M2FjZTgwMGYx
10
+ ODAwNmNjY2UxYTQ5ZGFkNzViODhiYzU5MzBkYjNiNDQxZmE0NmYyYmU4NTZi
11
+ MWY0YTg2MGJkMGIwNmE0NjgxZjM2MTdlNTVhNmM4ZWYxYzMxMzY=
12
+ data.tar.gz: !binary |-
13
+ MTQ5ODk2ZDViMDVmNGQ0OTgwZTU4N2ZkYTI5MGU0NGMwMGQ2ZmQ5YTI1YWFj
14
+ ZDMwMzJjZWZhNDViYjgwNTU3ZTRhNjUxN2VjYjA4ZjM3ZjVmOTljZWJhZjY1
15
+ Mjc1OGMwNzdiNDExODlkNDcxYjZiZTQ5YTRjMDM2ZGFlMTlkYzY=
checksums.yaml.gz.sig ADDED
Binary file
data.tar.gz.sig CHANGED
Binary file
data/CHANGES CHANGED
@@ -1,3 +1,17 @@
1
+ # 2.6.2
2
+
3
+ * Add check for CVE-2014-3415
4
+ * Avoid warning about symbolizing safe parameters
5
+ * Update ruby2ruby dependency to 2.1.1
6
+ * Expand app path in one place instead of all over (Jeff Rafter)
7
+ * Add `--add-checks-path` option for external checks (Clint Gibler)
8
+ * Fix SQL injection detection in deep nested string building
9
+ * Add `-4` option to force Rails 4 mode
10
+ * Check entire call for `send`
11
+ * Check for .gitignore of secrets in subdirectories
12
+ * Fix block statment endings in Erubis
13
+ * Fix undefined variable in controller processing error (Jason Barnabe)
14
+
1
15
  # 2.6.1
2
16
 
3
17
  * Add check for CVE-2014-3482 and CVE-2014-3483
data/bin/brakeman CHANGED
@@ -17,7 +17,7 @@ end
17
17
 
18
18
  #Exit early for these options
19
19
  if options[:list_checks]
20
- Brakeman.list_checks
20
+ Brakeman.list_checks options
21
21
  exit
22
22
  elsif options[:create_config]
23
23
  Brakeman.dump_config options
@@ -36,9 +36,9 @@ end
36
36
  #Set application path according to the commandline arguments
37
37
  unless options[:app_path]
38
38
  if ARGV[-1].nil?
39
- options[:app_path] = File.expand_path "."
39
+ options[:app_path] = "."
40
40
  else
41
- options[:app_path] = File.expand_path ARGV[-1]
41
+ options[:app_path] = ARGV[-1]
42
42
  end
43
43
  end
44
44
 
data/lib/brakeman.rb CHANGED
@@ -76,7 +76,6 @@ module Brakeman
76
76
  options[:quiet] = true
77
77
  end
78
78
 
79
- options[:app_path] = File.expand_path(options[:app_path])
80
79
  options[:output_formats] = get_output_formats options
81
80
  options[:github_url] = get_github_url options
82
81
 
@@ -215,8 +214,11 @@ module Brakeman
215
214
  private_class_method :get_github_url
216
215
 
217
216
  #Output list of checks (for `-k` option)
218
- def self.list_checks
217
+ def self.list_checks options
219
218
  require 'brakeman/scanner'
219
+
220
+ add_external_checks options
221
+
220
222
  format_length = 30
221
223
 
222
224
  $stderr.puts "Available Checks:"
@@ -301,11 +303,14 @@ module Brakeman
301
303
  raise NoBrakemanError, "Cannot find lib/ directory."
302
304
  end
303
305
 
306
+ add_external_checks options
307
+
304
308
  #Start scanning
305
309
  scanner = Scanner.new options
310
+ tracker = scanner.tracker
306
311
 
307
- notify "Processing application in #{options[:app_path]}"
308
- tracker = scanner.process
312
+ notify "Processing application in #{tracker.app_path}"
313
+ scanner.process
309
314
 
310
315
  if options[:parallel_checks]
311
316
  notify "Running checks in parallel..."
@@ -383,6 +388,8 @@ module Brakeman
383
388
  require 'brakeman/differ'
384
389
  raise ArgumentError.new("Comparison file doesn't exist") unless File.exists? options[:previous_results_json]
385
390
 
391
+ add_external_checks options
392
+
386
393
  begin
387
394
  previous_results = MultiJson.load(File.read(options[:previous_results_json]), :symbolize_keys => true)[:warnings]
388
395
  rescue MultiJson::DecodeError
@@ -437,6 +444,12 @@ module Brakeman
437
444
  tracker.ignored_filter = config
438
445
  end
439
446
 
447
+ def self.add_external_checks options
448
+ options[:additional_checks_path].each do |path|
449
+ Brakeman::Checks.initialize_checks path
450
+ end if options[:additional_checks_path]
451
+ end
452
+
440
453
  class DependencyError < RuntimeError; end
441
454
  class RakeInstallError < RuntimeError; end
442
455
  class NoBrakemanError < RuntimeError; end
@@ -5,7 +5,7 @@ module Brakeman
5
5
  attr_reader :root
6
6
 
7
7
  def self.from_options(options)
8
- root = options[:app_path]
8
+ root = File.expand_path options[:app_path]
9
9
 
10
10
  # Convert files into Regexp for matching
11
11
  init_options = {}
@@ -13,13 +13,20 @@ class Brakeman::Checks
13
13
 
14
14
  #Add a check. This will call +_klass_.new+ when running tests
15
15
  def self.add klass
16
- @checks << klass
16
+ @checks << klass unless @checks.include? klass
17
17
  end
18
18
 
19
19
  def self.checks
20
20
  @checks
21
21
  end
22
22
 
23
+ def self.initialize_checks check_directory = ""
24
+ #Load all files in check_directory
25
+ Dir.glob(File.join(check_directory, "*.rb")).sort.each do |f|
26
+ require f
27
+ end
28
+ end
29
+
23
30
  #No need to use this directly.
24
31
  def initialize options = { }
25
32
  if options[:min_confidence]
@@ -177,7 +177,7 @@ class Brakeman::BaseCheck < Brakeman::SexpProcessor
177
177
  tracker.config[:rails][:active_record][:whitelist_attributes] == Sexp.new(:true)
178
178
 
179
179
  @mass_assign_disabled = true
180
- elsif version_between?("4.0.0", "4.9.9") && (!tracker.config[:gems][:protected_attributes] || (tracker.config[:rails][:active_record] &&
180
+ elsif tracker.options[:rails4] && (!tracker.config[:gems][:protected_attributes] || (tracker.config[:rails][:active_record] &&
181
181
  tracker.config[:rails][:active_record][:whitelist_attributes] == Sexp.new(:true)))
182
182
 
183
183
  @mass_assign_disabled = true
@@ -481,7 +481,6 @@ class Brakeman::BaseCheck < Brakeman::SexpProcessor
481
481
  end
482
482
 
483
483
  def lts_version? version
484
- tracker.config[:gems] and
485
484
  tracker.config[:gems][:'railslts-version'] and
486
485
  version_between? version, "2.3.18.99", tracker.config[:gems][:'railslts-version']
487
486
  end
@@ -0,0 +1,75 @@
1
+ require 'brakeman/checks/base_check'
2
+
3
+ class Brakeman::CheckCreateWith < Brakeman::BaseCheck
4
+ Brakeman::Checks.add self
5
+
6
+ @description = "Checks for strong params bypass in CVE-2014-3514"
7
+
8
+ def run_check
9
+ @warned = false
10
+
11
+ if version_between? "4.0.0", "4.0.8"
12
+ suggested_version = "4.0.9"
13
+ elsif version_between? "4.1.0", "4.1.4"
14
+ suggested_version = "4.1.5"
15
+ else
16
+ return
17
+ end
18
+
19
+ @message = "create_with is vulnerable to strong params bypass. Upgrade to Rails #{suggested_version} or patch"
20
+
21
+ tracker.find_call(:method => :create_with, :nested => true).each do |result|
22
+ process_result result
23
+ end
24
+
25
+ generic_warning unless @warned
26
+ end
27
+
28
+ def process_result result
29
+ return if duplicate? result
30
+ add_result result
31
+ arg = result[:call].first_arg
32
+
33
+ confidence = danger_level arg
34
+
35
+ if confidence
36
+ @warned = true
37
+
38
+ warn :warning_type => "Mass Assignment",
39
+ :warning_code => :CVE_2014_3514_call,
40
+ :result => result,
41
+ :message => @message,
42
+ :confidence => confidence,
43
+ :link_path => "https://groups.google.com/d/msg/rubyonrails-security/M4chq5Sb540/CC1Fh0Y_NWwJ"
44
+ end
45
+ end
46
+
47
+ #For a given create_with call, set confidence level.
48
+ #Ignore calls that use permit()
49
+ def danger_level exp
50
+ return unless sexp? exp
51
+
52
+ if call? exp and exp.method == :permit
53
+ nil
54
+ elsif request_value? exp
55
+ CONFIDENCE[:high]
56
+ elsif hash? exp
57
+ nil
58
+ elsif has_immediate_user_input?(exp)
59
+ CONFIDENCE[:high]
60
+ elsif include_user_input? exp
61
+ CONFIDENCE[:med]
62
+ else
63
+ CONFIDENCE[:low]
64
+ end
65
+ end
66
+
67
+ def generic_warning
68
+ warn :warning_type => "Mass Assignment",
69
+ :warning_code => :CVE_2014_3514,
70
+ :message => @message,
71
+ :file => gemfile_or_environment,
72
+ :confidence => CONFIDENCE[:med],
73
+ :link_path => "https://groups.google.com/d/msg/rubyonrails-security/M4chq5Sb540/CC1Fh0Y_NWwJ"
74
+ end
75
+ end
@@ -22,7 +22,7 @@ class Brakeman::CheckDefaultRoutes < Brakeman::BaseCheck
22
22
  :message => "All public methods in controllers are available as actions in routes.rb",
23
23
  :line => tracker.routes[:allow_all_actions].line,
24
24
  :confidence => CONFIDENCE[:high],
25
- :file => "#{tracker.options[:app_path]}/config/routes.rb"
25
+ :file => "#{tracker.app_path}/config/routes.rb"
26
26
  end
27
27
  end
28
28
 
@@ -44,7 +44,7 @@ class Brakeman::CheckDefaultRoutes < Brakeman::BaseCheck
44
44
  :message => "Any public method in #{name} can be used as an action for #{verb} requests.",
45
45
  :line => actions[2],
46
46
  :confidence => CONFIDENCE[:med],
47
- :file => "#{tracker.options[:app_path]}/config/routes.rb"
47
+ :file => "#{tracker.app_path}/config/routes.rb"
48
48
  end
49
49
  end
50
50
  end
@@ -76,7 +76,7 @@ class Brakeman::CheckDefaultRoutes < Brakeman::BaseCheck
76
76
  :warning_code => :CVE_2014_0130,
77
77
  :message => "Rails #{tracker.config[:rails_version]} with globbing routes is vulnerable to directory traversal and remote code execution. Patch or upgrade to #{upgrade}",
78
78
  :confidence => confidence,
79
- :file => "#{tracker.options[:app_path]}/config/routes.rb",
79
+ :file => "#{tracker.app_path}/config/routes.rb",
80
80
  :link => "http://matasano.com/research/AnatomyOfRailsVuln-CVE-2014-0130.pdf"
81
81
  end
82
82
 
@@ -9,7 +9,7 @@ class Brakeman::CheckI18nXSS < Brakeman::BaseCheck
9
9
  if (version_between? "3.0.6", "3.2.15" or version_between? "4.0.0", "4.0.1") and not has_workaround?
10
10
  message = "Rails #{tracker.config[:rails_version]} has an XSS vulnerability in i18n (CVE-2013-4491). Upgrade to Rails version "
11
11
 
12
- i18n_gem = tracker.config[:gems] && tracker.config[:gems][:i18n]
12
+ i18n_gem = tracker.config[:gems][:i18n]
13
13
 
14
14
  if version_between? "3.0.6", "3.1.99" and version_before i18n_gem, "0.5.1"
15
15
  message << "3.2.16 or i18n 0.5.1"
@@ -33,7 +33,7 @@ class Brakeman::CheckJSONParsing < Brakeman::BaseCheck
33
33
 
34
34
  #Check if `yajl` is included in Gemfile
35
35
  def uses_yajl?
36
- tracker.config[:gems] and tracker.config[:gems][:yajl]
36
+ tracker.config[:gems][:yajl]
37
37
  end
38
38
 
39
39
  #Check for `ActiveSupport::JSON.backend = "JSONGem"`
@@ -184,7 +184,6 @@ class Brakeman::CheckRedirect < Brakeman::BaseCheck
184
184
  if node_type? exp, :or
185
185
  decorated_model? exp.lhs or decorated_model? exp.rhs
186
186
  else
187
- tracker.config[:gems] and
188
187
  tracker.config[:gems][:draper] and
189
188
  call? exp and
190
189
  node_type?(exp.target, :const) and
@@ -7,8 +7,9 @@ class Brakeman::CheckSend < Brakeman::BaseCheck
7
7
  @description = "Check for unsafe use of Object#send"
8
8
 
9
9
  def run_check
10
+ @send_methods = [:send, :try, :__send__, :public_send]
10
11
  Brakeman.debug("Finding instances of #send")
11
- calls = tracker.find_call :methods => [:send, :try, :__send__, :public_send]
12
+ calls = tracker.find_call :methods => @send_methods, :nested => true
12
13
 
13
14
  calls.each do |call|
14
15
  process_result call
@@ -19,10 +20,11 @@ class Brakeman::CheckSend < Brakeman::BaseCheck
19
20
  return if duplicate? result or result[:call].original_line
20
21
  add_result result
21
22
 
22
- process_call_args result[:call]
23
- target = process result[:call].target
23
+ send_call = get_send result[:call]
24
+ process_call_args send_call
25
+ target = process send_call.target
24
26
 
25
- if input = has_immediate_user_input?(result[:call].first_arg)
27
+ if input = has_immediate_user_input?(send_call.first_arg)
26
28
  warn :result => result,
27
29
  :warning_type => "Dangerous Send",
28
30
  :warning_code => :dangerous_send,
@@ -32,4 +34,15 @@ class Brakeman::CheckSend < Brakeman::BaseCheck
32
34
  :confidence => CONFIDENCE[:high]
33
35
  end
34
36
  end
37
+
38
+ # Recursively check call chain for send call
39
+ def get_send exp
40
+ if call? exp
41
+ if @send_methods.include? exp.method
42
+ return exp
43
+ else
44
+ get_send exp.target
45
+ end
46
+ end
47
+ end
35
48
  end
@@ -20,7 +20,7 @@ class Brakeman::CheckSessionSettings < Brakeman::BaseCheck
20
20
  settings = tracker.config[:rails][:action_controller] &&
21
21
  tracker.config[:rails][:action_controller][:session]
22
22
 
23
- check_for_issues settings, "#{tracker.options[:app_path]}/config/environment.rb"
23
+ check_for_issues settings, "#{tracker.app_path}/config/environment.rb"
24
24
 
25
25
  ["session_store.rb", "secret_token.rb"].each do |file|
26
26
  if tracker.initializers[file] and not ignored? file
@@ -39,15 +39,15 @@ class Brakeman::CheckSessionSettings < Brakeman::BaseCheck
39
39
  #in Rails 4.x apps
40
40
  def process_attrasgn exp
41
41
  if not tracker.options[:rails3] and exp.target == @session_settings and exp.method == :session=
42
- check_for_issues exp.first_arg, "#{tracker.options[:app_path]}/config/initializers/session_store.rb"
42
+ check_for_issues exp.first_arg, "#{tracker.app_path}/config/initializers/session_store.rb"
43
43
  end
44
44
 
45
45
  if tracker.options[:rails3] and settings_target?(exp.target) and
46
46
  (exp.method == :secret_token= or exp.method == :secret_key_base=) and string? exp.first_arg
47
47
 
48
- warn_about_secret_token exp, "#{tracker.options[:app_path]}/config/initializers/secret_token.rb"
48
+ warn_about_secret_token exp, "#{tracker.app_path}/config/initializers/secret_token.rb"
49
49
  end
50
-
50
+
51
51
  exp
52
52
  end
53
53
 
@@ -55,9 +55,9 @@ class Brakeman::CheckSessionSettings < Brakeman::BaseCheck
55
55
  #in Rails 3.x apps
56
56
  def process_call exp
57
57
  if tracker.options[:rails3] and settings_target?(exp.target) and exp.method == :session_store
58
- check_for_rails3_issues exp.second_arg, "#{tracker.options[:app_path]}/config/initializers/session_store.rb"
58
+ check_for_rails3_issues exp.second_arg, "#{tracker.app_path}/config/initializers/session_store.rb"
59
59
  end
60
-
60
+
61
61
  exp
62
62
  end
63
63
 
@@ -134,12 +134,15 @@ class Brakeman::CheckSessionSettings < Brakeman::BaseCheck
134
134
  end
135
135
 
136
136
  def ignored? file
137
- if @app_tree.exists? ".gitignore"
138
- input = @app_tree.read(".gitignore")
137
+ [".", "config", "config/initializers"].each do |dir|
138
+ ignore_file = "#{dir}/.gitignore"
139
+ if @app_tree.exists? ignore_file
140
+ input = @app_tree.read(ignore_file)
139
141
 
140
- input.include? file
141
- else
142
- false
142
+ return true if input.include? file
143
+ end
143
144
  end
145
+
146
+ false
144
147
  end
145
148
  end
@@ -19,7 +19,7 @@ class Brakeman::CheckSQL < Brakeman::BaseCheck
19
19
  @sql_targets = [:all, :average, :calculate, :count, :count_by_sql, :exists?, :delete_all, :destroy_all,
20
20
  :find, :find_by_sql, :first, :last, :maximum, :minimum, :pluck, :sum, :update_all]
21
21
  @sql_targets.concat [:from, :group, :having, :joins, :lock, :order, :reorder, :select, :where] if tracker.options[:rails3]
22
- @sql_targets << :find_by << :find_by! if version_between? "4.0.0", "9.9.9"
22
+ @sql_targets << :find_by << :find_by! if tracker.options[:rails4]
23
23
 
24
24
  @connection_calls = [:delete, :execute, :insert, :select_all, :select_one,
25
25
  :select_rows, :select_value, :select_values]
@@ -496,23 +496,32 @@ class Brakeman::CheckSQL < Brakeman::BaseCheck
496
496
  arg = exp.first_arg
497
497
 
498
498
  if STRING_METHODS.include? method
499
- if string? target
500
- check_string_arg arg
501
- elsif string? arg
502
- check_string_arg target
503
- elsif call? target
504
- check_for_string_building target
505
- elsif node_type? target, :string_interp, :dstr or
506
- node_type? arg, :string_interp, :dstr
507
-
508
- check_string_arg target and
509
- check_string_arg arg
510
- end
499
+ check_str_target_or_arg(target, arg) or
500
+ check_interp_target_or_arg(target, arg) or
501
+ check_for_string_building(target) or
502
+ check_for_string_building(arg)
511
503
  else
512
504
  nil
513
505
  end
514
506
  end
515
507
 
508
+ def check_str_target_or_arg target, arg
509
+ if string? target
510
+ check_string_arg arg
511
+ elsif string? arg
512
+ check_string_arg target
513
+ end
514
+ end
515
+
516
+ def check_interp_target_or_arg target, arg
517
+ if node_type? target, :string_interp, :dstr or
518
+ node_type? arg, :string_interp, :dstr
519
+
520
+ check_string_arg target and
521
+ check_string_arg arg
522
+ end
523
+ end
524
+
516
525
  def check_string_arg exp
517
526
  if safe_value? exp
518
527
  nil
@@ -48,7 +48,7 @@ class Brakeman::CheckSQLCVEs < Brakeman::BaseCheck
48
48
  }
49
49
  end
50
50
 
51
- if tracker.config[:gems] and tracker.config[:gems][:pg]
51
+ if tracker.config[:gems][: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]],
@@ -54,6 +54,8 @@ class Brakeman::CheckSymbolDoS < Brakeman::BaseCheck
54
54
  end
55
55
 
56
56
  if confidence
57
+ return if safe_parameter? input.match
58
+
57
59
  message = "Symbol conversion from unsafe string (#{friendly_type_of input})"
58
60
 
59
61
  warn :result => result,
@@ -63,7 +65,14 @@ class Brakeman::CheckSymbolDoS < Brakeman::BaseCheck
63
65
  :user_input => input.match,
64
66
  :confidence => confidence
65
67
  end
66
-
67
68
  end
68
69
 
70
+ def safe_parameter? input
71
+ return unless params? input
72
+
73
+ call? input and
74
+ input.method == :[] and
75
+ symbol? input.first_arg and
76
+ [:controller, :action].include? input.first_arg.value
77
+ end
69
78
  end
@@ -32,7 +32,7 @@ module Brakeman::Options
32
32
  end
33
33
 
34
34
  opts.on "-p", "--path PATH", "Specify path to Rails application" do |path|
35
- options[:app_path] = File.expand_path path
35
+ options[:app_path] = path
36
36
  end
37
37
 
38
38
  opts.on "-q", "--[no-]quiet", "Suppress informational messages" do |quiet|
@@ -47,6 +47,11 @@ module Brakeman::Options
47
47
  options[:rails3] = true
48
48
  end
49
49
 
50
+ opts.on "-4", "--rails4", "Force Rails 4 mode" do
51
+ options[:rails3] = true
52
+ options[:rails4] = true
53
+ end
54
+
50
55
  opts.separator ""
51
56
  opts.separator "Scanning options:"
52
57
 
@@ -133,6 +138,11 @@ module Brakeman::Options
133
138
  end
134
139
  end
135
140
 
141
+ opts.on "--add-checks-path path1,path2,etc", Array, "A directory containing additional out-of-tree checks to run" do |paths|
142
+ options[:additional_checks_path] ||= Set.new
143
+ options[:additional_checks_path].merge paths.map {|p| File.expand_path p}
144
+ end
145
+
136
146
  opts.separator ""
137
147
  opts.separator "Output options:"
138
148
 
@@ -39,14 +39,6 @@ class Brakeman::Rails3Erubis < ::Erubis::Eruby
39
39
  end
40
40
  end
41
41
 
42
- def add_stmt(src, code)
43
- if code =~ BLOCK_EXPR
44
- src << '@output_buffer.append_if_string= ' << code
45
- else
46
- super
47
- end
48
- end
49
-
50
42
  def add_expr_escaped(src, code)
51
43
  if code =~ BLOCK_EXPR
52
44
  src << "@output_buffer.safe_append= " << code
@@ -27,7 +27,7 @@ module Brakeman
27
27
  when :slim
28
28
  parse_slim text
29
29
  else
30
- tracker.error "Unkown template type in #{path}"
30
+ tracker.error "Unknown template type in #{path}"
31
31
  nil
32
32
  end
33
33
 
@@ -19,9 +19,15 @@ class Brakeman::GemProcessor < Brakeman::BaseProcessor
19
19
  @tracker.config[:rails_version] = $1
20
20
  end
21
21
 
22
- if @tracker.config[:rails_version] =~ /^(3|4)\./ and not @tracker.options[:rails3]
23
- @tracker.options[:rails3] = true
24
- Brakeman.notify "[Notice] Detected Rails #$1 application"
22
+ if @tracker.options[:rails3].nil? and @tracker.options[:rails4].nil? and @tracker.config[:rails_version]
23
+ if @tracker.config[:rails_version].start_with? "3"
24
+ @tracker.options[:rails3] = true
25
+ Brakeman.notify "[Notice] Detected Rails 3 application"
26
+ elsif @tracker.config[:rails_version].start_with? "4"
27
+ @tracker.options[:rails3] = true
28
+ @tracker.options[:rails4] = true
29
+ Brakeman.notify "[Notice] Detected Rails 4 application"
30
+ end
25
31
  end
26
32
 
27
33
  if @tracker.config[:gems][:rails_xss]
@@ -1,10 +1,3 @@
1
- #Temporary fix for https://github.com/seattlerb/ruby_parser/issues/154
2
- class Regexp
3
- [:ENC_NONE, :ENC_EUC, :ENC_SJIS, :ENC_UTF8].each do |enc|
4
- remove_const enc if const_defined? enc
5
- end
6
- end
7
-
8
1
  require 'ruby2ruby'
9
2
  require 'brakeman/util'
10
3
 
@@ -262,9 +262,16 @@ class Brakeman::Report::Base
262
262
  end
263
263
 
264
264
  def rails_version
265
- return tracker.config[:rails_version] if tracker.config[:rails_version]
266
- return "3.x" if tracker.options[:rails3]
267
- "Unknown"
265
+ case
266
+ when tracker.config[:rails_version]
267
+ tracker.config[:rails_version]
268
+ when tracker.options[:rails4]
269
+ "4.x"
270
+ when tracker.options[:rails3]
271
+ "3.x"
272
+ else
273
+ "Unknown"
274
+ end
268
275
  end
269
276
 
270
277
  #Escape warning message and highlight user input in text output
@@ -50,7 +50,7 @@ class Brakeman::Report::CSV < Brakeman::Report::Table
50
50
  #Generate header for CSV output
51
51
  def csv_header
52
52
  header = CSV.generate_line(["Application Path", "Report Generation Time", "Checks Performed", "Rails Version"])
53
- header << CSV.generate_line([File.expand_path(tracker.options[:app_path]), Time.now.to_s, checks.checks_run.sort.join(", "), rails_version])
53
+ header << CSV.generate_line([File.expand_path(tracker.app_path), Time.now.to_s, checks.checks_run.sort.join(", "), rails_version])
54
54
  "BRAKEMAN REPORT\n\n" + header
55
55
  end
56
56
  end
@@ -16,6 +16,7 @@ class Brakeman::Report::Hash < Brakeman::Report::Base
16
16
  end
17
17
 
18
18
  report[:config] = tracker.config
19
+ report[:checks_run] = tracker.checks.checks_run
19
20
 
20
21
  report
21
22
  end
@@ -4,14 +4,13 @@ require 'brakeman/report/initializers/multi_json'
4
4
  class Brakeman::Report::JSON < Brakeman::Report::Base
5
5
  def generate_report
6
6
  errors = tracker.errors.map{|e| { :error => e[:error], :location => e[:backtrace][0] }}
7
- app_path = tracker.options[:app_path]
8
7
 
9
8
  warnings = convert_to_hashes all_warnings
10
9
 
11
10
  ignored = convert_to_hashes ignored_warnings
12
11
 
13
12
  scan_info = {
14
- :app_path => File.expand_path(tracker.options[:app_path]),
13
+ :app_path => tracker.app_path,
15
14
  :rails_version => rails_version,
16
15
  :security_warnings => all_warnings.length,
17
16
  :start_time => tracker.start_time.to_s,
@@ -66,7 +66,7 @@ class Brakeman::Report::Markdown < Brakeman::Report::Base
66
66
  ['Application path', 'Rails version', 'Brakeman version', 'Started at', 'Duration']
67
67
  ) do |t|
68
68
  t.add_row([
69
- File.expand_path(tracker.options[:app_path]),
69
+ tracker.app_path,
70
70
  rails_version,
71
71
  Brakeman::Version,
72
72
  tracker.start_time,
@@ -98,7 +98,7 @@ class Brakeman::Report::Table < Brakeman::Report::Base
98
98
 
99
99
  +BRAKEMAN REPORT+
100
100
 
101
- Application path: #{File.expand_path tracker.options[:app_path]}
101
+ Application path: #{tracker.app_path}
102
102
  Rails version: #{rails_version}
103
103
  Brakeman version: #{Brakeman::Version}
104
104
  Started at #{tracker.start_time}
@@ -31,7 +31,7 @@
31
31
  <th>Checks Performed</th>
32
32
  </tr>
33
33
  <tr>
34
- <td><%= File.expand_path tracker.options[:app_path] %></td>
34
+ <td><%= tracker.app_path %></td>
35
35
  <td><%= rails_version %></td>
36
36
  <td><%= brakeman_version %>
37
37
  <td>
@@ -28,14 +28,6 @@ class Brakeman::Scanner
28
28
  raise Brakeman::NoApplication, "Please supply the path to a Rails application."
29
29
  end
30
30
 
31
- if @app_tree.exists?("script/rails")
32
- options[:rails3] = true
33
- Brakeman.notify "[Notice] Detected Rails 3 application"
34
- elsif not @app_tree.exists?("script")
35
- options[:rails3] = true # Probably need to do some refactoring
36
- Brakeman.notify "[Notice] Detected Rails 4 application"
37
- end
38
-
39
31
  @processor = processor || Brakeman::Processor.new(@app_tree, options)
40
32
  end
41
33
 
@@ -48,6 +40,7 @@ class Brakeman::Scanner
48
40
  def process
49
41
  Brakeman.notify "Processing gems..."
50
42
  process_gems
43
+ guess_rails_version
51
44
  Brakeman.notify "Processing configuration..."
52
45
  process_config
53
46
  Brakeman.notify "Parsing files..."
@@ -147,6 +140,20 @@ class Brakeman::Scanner
147
140
  tracker.error e.exception(e.message + "\nWhile processing Gemfile"), e.backtrace
148
141
  end
149
142
 
143
+ #Set :rails3/:rails4 option if version was not determined from Gemfile
144
+ def guess_rails_version
145
+ unless tracker.options[:rails3] or tracker.options[:rails4]
146
+ if @app_tree.exists?("script/rails")
147
+ tracker.options[:rails3] = true
148
+ Brakeman.notify "[Notice] Detected Rails 3 application"
149
+ elsif not @app_tree.exists?("script")
150
+ tracker.options[:rails3] = true # Probably need to do some refactoring
151
+ tracker.options[:rails4] = true
152
+ Brakeman.notify "[Notice] Detected Rails 4 application"
153
+ end
154
+ end
155
+ end
156
+
150
157
  #Process all the .rb files in config/initializers/
151
158
  #
152
159
  #Adds parsed information to tracker.initializers
@@ -227,7 +234,7 @@ class Brakeman::Scanner
227
234
  begin
228
235
  @processor.process_controller(astfile.ast, astfile.path)
229
236
  rescue => e
230
- tracker.error e.exception(e.message + "\nWhile processing #{path}"), e.backtrace
237
+ tracker.error e.exception(e.message + "\nWhile processing #{astfile.path}"), e.backtrace
231
238
  end
232
239
  end
233
240
 
@@ -25,7 +25,7 @@ class Brakeman::Tracker
25
25
  @processor = processor
26
26
  @options = options
27
27
 
28
- @config = { :rails => {} }
28
+ @config = { :rails => {}, :gems => {} }
29
29
  @templates = {}
30
30
  @controllers = {}
31
31
  #Initialize models with the unknown model so
@@ -77,6 +77,10 @@ class Brakeman::Tracker
77
77
  @checks
78
78
  end
79
79
 
80
+ def app_path
81
+ @app_path ||= File.expand_path @options[:app_path]
82
+ end
83
+
80
84
  #Iterate over all methods in controllers and models.
81
85
  def each_method
82
86
  [self.controllers, self.models].each do |set|
data/lib/brakeman/util.rb CHANGED
@@ -274,7 +274,7 @@ module Brakeman::Util
274
274
  end
275
275
 
276
276
  if warning.file
277
- File.expand_path warning.file, tracker.options[:app_path]
277
+ File.expand_path warning.file, tracker.app_path
278
278
  elsif warning.template.is_a? Hash and warning.template[:file]
279
279
  warning.template[:file]
280
280
  else
@@ -314,7 +314,7 @@ module Brakeman::Util
314
314
  end
315
315
  end
316
316
 
317
- path = tracker.options[:app_path]
317
+ path = tracker.app_path
318
318
 
319
319
  case type
320
320
  when :controller
@@ -377,7 +377,7 @@ module Brakeman::Util
377
377
 
378
378
  def relative_path file
379
379
  if file and not file.empty? and file.start_with? '/'
380
- Pathname.new(file).relative_path_from(Pathname.new(@tracker.options[:app_path])).to_s
380
+ Pathname.new(file).relative_path_from(Pathname.new(@tracker.app_path)).to_s
381
381
  else
382
382
  file
383
383
  end
@@ -1,3 +1,3 @@
1
1
  module Brakeman
2
- Version = "2.6.1"
2
+ Version = "2.6.2"
3
3
  end
@@ -81,6 +81,8 @@ module Brakeman::WarningCodes
81
81
  :CVE_2014_0130 => 77,
82
82
  :CVE_2014_3482 => 78,
83
83
  :CVE_2014_3483 => 79,
84
+ :CVE_2014_3514 => 80,
85
+ :CVE_2014_3514_call => 81,
84
86
  }
85
87
 
86
88
  def self.code name
@@ -12,7 +12,14 @@ class Sexp
12
12
  #
13
13
  #The original functionality calls find_node and optionally
14
14
  #deletes the node if found.
15
- raise NoMethodError.new("No method '#{name}' for Sexp", name, args)
15
+ #
16
+ #Defining a method named "return" seems like a bad idea, so we have to
17
+ #check for it here instead
18
+ if name == :return
19
+ find_node name, *args
20
+ else
21
+ raise NoMethodError.new("No method '#{name}' for Sexp", name, args)
22
+ end
16
23
  end
17
24
 
18
25
  #Create clone of Sexp and nested Sexps but not their non-Sexp contents.
metadata CHANGED
@@ -1,8 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: brakeman-min
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.6.1
5
- prerelease:
4
+ version: 2.6.2
6
5
  platform: ruby
7
6
  authors:
8
7
  - Justin Collins
@@ -36,41 +35,50 @@ cert_chain:
36
35
  Q0c3bUZaNnhnaDAxZXFuWlVzTmQ4dk0rNlY2djIzVnUKamsydE1qRlQ0TDFk
37
36
  QTNNRXN6MytNUDE0NFBEaFBDaDd0UGU2eXk4MUJPdnlZVFZrS3pyQWtnS3dI
38
37
  RDFDdXZzSApiZHc9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
39
- date: 2014-07-02 00:00:00.000000000 Z
38
+ date: 2014-08-18 00:00:00.000000000 Z
40
39
  dependencies:
41
40
  - !ruby/object:Gem::Dependency
42
41
  name: ruby_parser
43
- requirement: &70097644561700 !ruby/object:Gem::Requirement
44
- none: false
42
+ requirement: !ruby/object:Gem::Requirement
45
43
  requirements:
46
44
  - - ~>
47
45
  - !ruby/object:Gem::Version
48
46
  version: 3.5.0
49
47
  type: :runtime
50
48
  prerelease: false
51
- version_requirements: *70097644561700
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ~>
52
+ - !ruby/object:Gem::Version
53
+ version: 3.5.0
52
54
  - !ruby/object:Gem::Dependency
53
55
  name: ruby2ruby
54
- requirement: &70097644561180 !ruby/object:Gem::Requirement
55
- none: false
56
+ requirement: !ruby/object:Gem::Requirement
56
57
  requirements:
57
58
  - - ~>
58
59
  - !ruby/object:Gem::Version
59
- version: 2.0.5
60
+ version: 2.1.1
60
61
  type: :runtime
61
62
  prerelease: false
62
- version_requirements: *70097644561180
63
+ version_requirements: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ~>
66
+ - !ruby/object:Gem::Version
67
+ version: 2.1.1
63
68
  - !ruby/object:Gem::Dependency
64
69
  name: multi_json
65
- requirement: &70097644560680 !ruby/object:Gem::Requirement
66
- none: false
70
+ requirement: !ruby/object:Gem::Requirement
67
71
  requirements:
68
72
  - - ~>
69
73
  - !ruby/object:Gem::Version
70
74
  version: '1.2'
71
75
  type: :runtime
72
76
  prerelease: false
73
- version_requirements: *70097644560680
77
+ version_requirements: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ~>
80
+ - !ruby/object:Gem::Version
81
+ version: '1.2'
74
82
  description: Brakeman detects security vulnerabilities in Ruby on Rails applications
75
83
  via static analysis. This version of the gem only requires the minimum number of
76
84
  dependencies. Use the 'brakeman' gem for a full install.
@@ -80,17 +88,20 @@ executables:
80
88
  extensions: []
81
89
  extra_rdoc_files: []
82
90
  files:
83
- - bin/brakeman
84
91
  - CHANGES
85
- - WARNING_TYPES
86
92
  - FEATURES
87
93
  - README.md
94
+ - WARNING_TYPES
95
+ - bin/brakeman
96
+ - lib/brakeman.rb
88
97
  - lib/brakeman/app_tree.rb
89
98
  - lib/brakeman/brakeman.rake
90
99
  - lib/brakeman/call_index.rb
100
+ - lib/brakeman/checks.rb
91
101
  - lib/brakeman/checks/base_check.rb
92
102
  - lib/brakeman/checks/check_basic_auth.rb
93
103
  - lib/brakeman/checks/check_content_tag.rb
104
+ - lib/brakeman/checks/check_create_with.rb
94
105
  - lib/brakeman/checks/check_cross_site_scripting.rb
95
106
  - lib/brakeman/checks/check_default_routes.rb
96
107
  - lib/brakeman/checks/check_deserialize.rb
@@ -141,7 +152,6 @@ files:
141
152
  - lib/brakeman/checks/check_validation_regex.rb
142
153
  - lib/brakeman/checks/check_without_protection.rb
143
154
  - lib/brakeman/checks/check_yaml_parsing.rb
144
- - lib/brakeman/checks.rb
145
155
  - lib/brakeman/differ.rb
146
156
  - lib/brakeman/file_parser.rb
147
157
  - lib/brakeman/format/style.css
@@ -177,6 +187,7 @@ files:
177
187
  - lib/brakeman/processors/slim_template_processor.rb
178
188
  - lib/brakeman/processors/template_alias_processor.rb
179
189
  - lib/brakeman/processors/template_processor.rb
190
+ - lib/brakeman/report.rb
180
191
  - lib/brakeman/report/ignore/config.rb
181
192
  - lib/brakeman/report/ignore/interactive.rb
182
193
  - lib/brakeman/report/initializers/faster_csv.rb
@@ -201,7 +212,6 @@ files:
201
212
  - lib/brakeman/report/templates/template_overview.html.erb
202
213
  - lib/brakeman/report/templates/view_warnings.html.erb
203
214
  - lib/brakeman/report/templates/warning_overview.html.erb
204
- - lib/brakeman/report.rb
205
215
  - lib/brakeman/rescanner.rb
206
216
  - lib/brakeman/scanner.rb
207
217
  - lib/brakeman/tracker.rb
@@ -209,32 +219,30 @@ files:
209
219
  - lib/brakeman/version.rb
210
220
  - lib/brakeman/warning.rb
211
221
  - lib/brakeman/warning_codes.rb
212
- - lib/brakeman.rb
213
222
  - lib/ruby_parser/bm_sexp.rb
214
223
  - lib/ruby_parser/bm_sexp_processor.rb
215
224
  homepage: http://brakemanscanner.org
216
225
  licenses:
217
226
  - MIT
227
+ metadata: {}
218
228
  post_install_message:
219
229
  rdoc_options: []
220
230
  require_paths:
221
231
  - lib
222
232
  required_ruby_version: !ruby/object:Gem::Requirement
223
- none: false
224
233
  requirements:
225
234
  - - ! '>='
226
235
  - !ruby/object:Gem::Version
227
236
  version: '0'
228
237
  required_rubygems_version: !ruby/object:Gem::Requirement
229
- none: false
230
238
  requirements:
231
239
  - - ! '>='
232
240
  - !ruby/object:Gem::Version
233
241
  version: '0'
234
242
  requirements: []
235
243
  rubyforge_project:
236
- rubygems_version: 1.8.9
244
+ rubygems_version: 2.3.0
237
245
  signing_key:
238
- specification_version: 3
246
+ specification_version: 4
239
247
  summary: Security vulnerability scanner for Ruby on Rails.
240
248
  test_files: []
metadata.gz.sig CHANGED
Binary file