brakeman-lib 5.0.4 → 5.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGES.md +49 -1
  3. data/README.md +1 -1
  4. data/lib/brakeman/app_tree.rb +1 -1
  5. data/lib/brakeman/checks/base_check.rb +10 -0
  6. data/lib/brakeman/checks/check_detailed_exceptions.rb +1 -1
  7. data/lib/brakeman/checks/check_eol_rails.rb +23 -0
  8. data/lib/brakeman/checks/check_eol_ruby.rb +26 -0
  9. data/lib/brakeman/checks/check_evaluation.rb +1 -1
  10. data/lib/brakeman/checks/check_execute.rb +10 -0
  11. data/lib/brakeman/checks/check_json_parsing.rb +1 -1
  12. data/lib/brakeman/checks/check_render.rb +15 -1
  13. data/lib/brakeman/checks/check_sql.rb +58 -7
  14. data/lib/brakeman/checks/check_symbol_dos.rb +1 -1
  15. data/lib/brakeman/checks/check_verb_confusion.rb +1 -1
  16. data/lib/brakeman/checks/eol_check.rb +47 -0
  17. data/lib/brakeman/file_parser.rb +45 -15
  18. data/lib/brakeman/options.rb +15 -2
  19. data/lib/brakeman/processors/alias_processor.rb +91 -9
  20. data/lib/brakeman/processors/controller_alias_processor.rb +6 -43
  21. data/lib/brakeman/processors/gem_processor.rb +3 -0
  22. data/lib/brakeman/processors/haml_template_processor.rb +9 -0
  23. data/lib/brakeman/processors/lib/call_conversion_helper.rb +12 -6
  24. data/lib/brakeman/processors/lib/rails3_route_processor.rb +2 -0
  25. data/lib/brakeman/processors/library_processor.rb +9 -0
  26. data/lib/brakeman/processors/model_processor.rb +32 -0
  27. data/lib/brakeman/report/ignore/config.rb +1 -1
  28. data/lib/brakeman/report/ignore/interactive.rb +1 -1
  29. data/lib/brakeman/report/report_csv.rb +1 -1
  30. data/lib/brakeman/report/report_github.rb +31 -0
  31. data/lib/brakeman/report/report_sarif.rb +22 -3
  32. data/lib/brakeman/report/report_text.rb +1 -1
  33. data/lib/brakeman/report.rb +4 -1
  34. data/lib/brakeman/rescanner.rb +1 -1
  35. data/lib/brakeman/scanner.rb +19 -14
  36. data/lib/brakeman/tracker/collection.rb +57 -7
  37. data/lib/brakeman/tracker/config.rb +8 -1
  38. data/lib/brakeman/tracker/method_info.rb +70 -0
  39. data/lib/brakeman/tracker.rb +33 -4
  40. data/lib/brakeman/util.rb +34 -18
  41. data/lib/brakeman/version.rb +1 -1
  42. data/lib/brakeman/warning_codes.rb +2 -0
  43. data/lib/brakeman.rb +8 -2
  44. data/lib/ruby_parser/bm_sexp.rb +24 -0
  45. metadata +24 -5
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2bc22b69b0b137fe9f223c2469fe6e3857054b0b98621645b52ed94af7fa4886
4
- data.tar.gz: 183f206e691c8251adef49319ca76939a4bf079cf5b14ead1f3f7923754ff9ff
3
+ metadata.gz: cf18736db7a992849a30cccc66f741442e05b695f9ad1bd27fe06f6bc25db849
4
+ data.tar.gz: a884f20cc12305c0856bcc296ddae3aea746b024c232bf11d7988d4e37bd96a3
5
5
  SHA512:
6
- metadata.gz: b902bcfbc2be499f0a892534bf443d88ce92f5a0b47edd31b7ac01a964e9ec13230f03f5ba8bb246dcdee27a7e6bd72b873d2826ce2f6b2486f64999f45b52e8
7
- data.tar.gz: 62f878559fd4aa1f2d96c35742d0c490c0d57c53e07d9a3619675f6519c0fafbaace29e0b616c217ea796132e7810b51b3f06cf1ff60a3a28a34ae9482069f32
6
+ metadata.gz: be93f9f9ba9d808989cbed1bfd450b29c272e806d84707ab0420a8a86b8c797f88d4338f22a1124a462be43ac7bfea605566779321a72d772e9c39d216ded8c3
7
+ data.tar.gz: cf9aa7f34fa5cc737b2e7bbecf625025b50f72f1b3c43ab8f346832145e3cab2245d2af79fd021584ab0aa5fdbb2f854dd41fee8f5a5c891197f1f1e8a570a65
data/CHANGES.md CHANGED
@@ -1,3 +1,51 @@
1
+ # 5.2.0 - 2021-12-15
2
+
3
+ * Initial Rails 7 support
4
+ * Require Ruby 2.5.0+
5
+ * Fix issue with calls to `foo.root` in routes
6
+ * Ignore `I18n.locale` in SQL queries
7
+ * Do not treat `sanitize_sql_like` as safe
8
+ * Add new checks for unsupported Ruby and Rails versions
9
+
10
+ # 5.1.2 - 2021-10-28
11
+
12
+ * Handle cases where enums are not symbols
13
+ * Support newer Haml with ::Haml::AttributeBuilder.build
14
+ * Fix issue where the previous output is still visible (Jason Frey)
15
+ * Fix warning sorting with nil line numbers
16
+ * Update for latest RubyParser (Ryan Davis)
17
+
18
+ # 5.1.1 - 2021-07-19
19
+
20
+ * Unrefactor IgnoreConfig's use of `Brakeman::FilePath`
21
+
22
+ # 5.1.0 - 2021-07-19
23
+
24
+ * Initial support for ActiveRecord enums
25
+ * Support `Hash#include?`
26
+ * Interprocedural dataflow from very simple class methods
27
+ * Fix SARIF report when checks have no description (Eli Block)
28
+ * Add ignored warnings to SARIF report (Eli Block)
29
+ * Add `--sql-safe-methods` option (Esty Scheiner)
30
+ * Update SQL injection check for Rails 6.0/6.1
31
+ * Fix false positive in command injection with `Open3.capture` (Richard Fitzgerald)
32
+ * Fix infinite loop on mixin self-includes (Andrew Szczepanski)
33
+ * Ignore dates in SQL
34
+ * Refactor `cookie?`/`param?` methods (Keenan Brock)
35
+ * Ignore renderables in dynamic render path check (Brad Parker)
36
+ * Support `Array#push`
37
+ * Better `Array#join` support
38
+ * Adjust copy of `--interactive` menu (Elia Schito)
39
+ * Support `Array#*`
40
+ * Better method definition tracking and lookup
41
+ * Support `Hash#values` and `Hash#values_at`
42
+ * Check for user-controlled evaluation even if it's a call target
43
+ * Support `Array#fetch` and `Hash#fetch`
44
+ * Ignore `sanitize_sql_like` in SQL
45
+ * Ignore method calls on numbers in SQL
46
+ * Add GitHub Actions format (Klaus Badelt)
47
+ * Read and parse files in parallel
48
+
1
49
  # 5.0.4 - 2021-06-08
2
50
 
3
51
  (brakeman gem release only)
@@ -418,7 +466,7 @@
418
466
  * Delay loading vendored gems and modifying load path
419
467
  * Avoid warning about SQL injection with `quoted_primary_key`
420
468
  * Support more safe `&.` operations
421
- * Allow multile line regex in `validates_format_of` (Dmitrij Fedorenko)
469
+ * Allow multiple line regex in `validates_format_of` (Dmitrij Fedorenko)
422
470
  * Only consider `if` branches in templates
423
471
  * Avoid overwriting instance/class methods with same name (Tim Wade)
424
472
  * Add `--force-scan` option (Neil Matatall)
data/README.md CHANGED
@@ -66,7 +66,7 @@ Outside of Rails root (note that the output file is relative to path/to/rails/ap
66
66
 
67
67
  Brakeman should work with any version of Rails from 2.3.x to 6.x.
68
68
 
69
- Brakeman can analyze code written with Ruby 1.8 syntax and newer, but requires at least Ruby 2.3.0 to run.
69
+ Brakeman can analyze code written with Ruby 1.8 syntax and newer, but requires at least Ruby 2.4.0 to run.
70
70
 
71
71
  # Basic Options
72
72
 
@@ -28,7 +28,7 @@ module Brakeman
28
28
  # Accepts an array of filenames and paths with the following format and
29
29
  # returns a Regexp to match them:
30
30
  # * "path1/file1.rb" - Matches a specific filename in the project directory.
31
- # * "path1/" - Matches any path that conatains "path1" in the project directory.
31
+ # * "path1/" - Matches any path that contains "path1" in the project directory.
32
32
  # * "/path1/ - Matches any path that is rooted at "path1" in the project directory.
33
33
  #
34
34
  def self.regex_for_paths(paths)
@@ -513,4 +513,14 @@ class Brakeman::BaseCheck < Brakeman::SexpProcessor
513
513
  string_building? exp.target or
514
514
  string_building? exp.first_arg
515
515
  end
516
+
517
+ I18N_CLASS = s(:const, :I18n)
518
+
519
+ def locale_call? exp
520
+ return unless call? exp
521
+
522
+ (exp.target == I18N_CLASS and
523
+ exp.method == :locale) or
524
+ locale_call? exp.target
525
+ end
516
526
  end
@@ -26,7 +26,7 @@ class Brakeman::CheckDetailedExceptions < Brakeman::BaseCheck
26
26
  def check_detailed_exceptions
27
27
  tracker.controllers.each do |_name, controller|
28
28
  controller.methods_public.each do |method_name, definition|
29
- src = definition[:src]
29
+ src = definition.src
30
30
  body = src.body.last
31
31
  next unless body
32
32
 
@@ -0,0 +1,23 @@
1
+ require_relative 'eol_check'
2
+
3
+ class Brakeman::CheckEOLRails < Brakeman::EOLCheck
4
+ Brakeman::Checks.add self
5
+
6
+ @description = "Checks for unsupported versions of Rails"
7
+
8
+ def run_check
9
+ return unless tracker.config.rails_version
10
+
11
+ check_eol_version :rails, RAILS_EOL_DATES
12
+ end
13
+
14
+ RAILS_EOL_DATES = {
15
+ ['2.0.0', '2.3.99'] => Date.new(2013, 6, 25),
16
+ ['3.0.0', '3.2.99'] => Date.new(2016, 6, 30),
17
+ ['4.0.0', '4.2.99'] => Date.new(2017, 4, 27),
18
+ ['5.0.0', '5.0.99'] => Date.new(2018, 5, 9),
19
+ ['5.1.0', '5.1.99'] => Date.new(2019, 8, 25),
20
+ ['5.2.0', '5.2.99'] => Date.new(2022, 6, 1),
21
+ ['6.0.0', '6.0.99'] => Date.new(2023, 6, 1),
22
+ }
23
+ end
@@ -0,0 +1,26 @@
1
+ require_relative 'eol_check'
2
+
3
+ class Brakeman::CheckEOLRuby < Brakeman::EOLCheck
4
+ Brakeman::Checks.add self
5
+
6
+ @description = "Checks for unsupported versions of Ruby"
7
+
8
+ def run_check
9
+ return unless tracker.config.ruby_version
10
+
11
+ check_eol_version :ruby, RUBY_EOL_DATES
12
+ end
13
+
14
+ RUBY_EOL_DATES = {
15
+ ['0.0.0', '1.9.3'] => Date.new(2015, 2, 23),
16
+ ['2.0.0', '2.0.99'] => Date.new(2016, 2, 24),
17
+ ['2.1.0', '2.1.99'] => Date.new(2017, 3, 31),
18
+ ['2.2.0', '2.2.99'] => Date.new(2018, 3, 31),
19
+ ['2.3.0', '2.3.99'] => Date.new(2019, 3, 31),
20
+ ['2.4.0', '2.4.99'] => Date.new(2020, 3, 31),
21
+ ['2.5.0', '2.5.99'] => Date.new(2021, 3, 31),
22
+ ['2.6.0', '2.6.99'] => Date.new(2022, 3, 31),
23
+ ['2.7.0', '2.7.99'] => Date.new(2023, 3, 31),
24
+ ['3.0.0', '2.8.99'] => Date.new(2024, 3, 31),
25
+ }
26
+ end
@@ -10,7 +10,7 @@ class Brakeman::CheckEvaluation < Brakeman::BaseCheck
10
10
  #Process calls
11
11
  def run_check
12
12
  Brakeman.debug "Finding eval-like calls"
13
- calls = tracker.find_call :method => [:eval, :instance_eval, :class_eval, :module_eval]
13
+ calls = tracker.find_call methods: [:eval, :instance_eval, :class_eval, :module_eval], nested: true
14
14
 
15
15
  Brakeman.debug "Processing eval-like calls"
16
16
  calls.each do |call|
@@ -87,6 +87,16 @@ class Brakeman::CheckExecute < Brakeman::BaseCheck
87
87
  dangerous_interp?(first_arg) ||
88
88
  dangerous_string_building?(first_arg)
89
89
  end
90
+ when :capture2, :capture2e, :capture3
91
+ # Open3 capture methods can take a :stdin_data argument which is used as the
92
+ # the input to the called command so it is not succeptable to command injection.
93
+ # As such if the last argument is a hash (and therefore execution options) it
94
+ # should be ignored
95
+
96
+ args.pop if hash?(args.last) && args.length > 2
97
+ failure = include_user_input?(args) ||
98
+ dangerous_interp?(args) ||
99
+ dangerous_string_building?(args)
90
100
  else
91
101
  failure = include_user_input?(args) ||
92
102
  dangerous_interp?(args) ||
@@ -74,7 +74,7 @@ class Brakeman::CheckJSONParsing < Brakeman::BaseCheck
74
74
  warning_type = "Denial of Service"
75
75
  confidence = :medium
76
76
  gem_name = "#{name} gem"
77
- message = msg(msg_version(version, gem_name), " has a symbol creation vulnerablity. Upgrade to ")
77
+ message = msg(msg_version(version, gem_name), " has a symbol creation vulnerability. Upgrade to ")
78
78
 
79
79
  if version >= "1.7.0"
80
80
  confidence = :high
@@ -33,6 +33,7 @@ class Brakeman::CheckRender < Brakeman::BaseCheck
33
33
  view = result[:call][2]
34
34
 
35
35
  if sexp? view and original? result
36
+ return if renderable?(view)
36
37
 
37
38
  if input = has_immediate_user_input?(view)
38
39
  if string_interp? view
@@ -94,4 +95,17 @@ class Brakeman::CheckRender < Brakeman::BaseCheck
94
95
  end
95
96
  end
96
97
  end
97
- end
98
+
99
+ def renderable? exp
100
+ return false unless call?(exp) and constant?(exp.target)
101
+
102
+ target_class_name = class_name(exp.target)
103
+ known_renderable_class?(target_class_name) or tracker.find_method(:render_in, target_class_name)
104
+ end
105
+
106
+ def known_renderable_class? class_name
107
+ klass = tracker.find_class(class_name)
108
+ return false if klass.nil?
109
+ klass.ancestor? :"ViewComponent::Base"
110
+ end
111
+ end
@@ -22,7 +22,19 @@ class Brakeman::CheckSQL < Brakeman::BaseCheck
22
22
  :find_by_sql, :maximum, :minimum, :pluck, :sum, :update_all]
23
23
  @sql_targets.concat [:from, :group, :having, :joins, :lock, :order, :reorder, :where] if tracker.options[:rails3]
24
24
  @sql_targets.concat [:find_by, :find_by!, :find_or_create_by, :find_or_create_by!, :find_or_initialize_by, :not] if tracker.options[:rails4]
25
- @sql_targets << :delete_by << :destroy_by if tracker.options[:rails6]
25
+
26
+ if tracker.options[:rails6]
27
+ @sql_targets.concat [:delete_by, :destroy_by, :rewhere, :reselect]
28
+
29
+ @sql_targets.delete :delete_all
30
+ @sql_targets.delete :destroy_all
31
+ end
32
+
33
+ if version_between?("6.1.0", "9.9.9")
34
+ @sql_targets.delete :order
35
+ @sql_targets.delete :reorder
36
+ @sql_targets.delete :pluck
37
+ end
26
38
 
27
39
  if version_between?("2.0.0", "3.9.9") or tracker.config.rails_version.nil?
28
40
  @sql_targets << :first << :last << :all
@@ -185,7 +197,7 @@ class Brakeman::CheckSQL < Brakeman::BaseCheck
185
197
  else
186
198
  check_find_arguments call.last_arg
187
199
  end
188
- when :where, :having, :find_by, :find_by!, :find_or_create_by, :find_or_create_by!, :find_or_initialize_by,:not, :delete_by, :destroy_by
200
+ when :where, :rewhere, :having, :find_by, :find_by!, :find_or_create_by, :find_or_create_by!, :find_or_initialize_by,:not, :delete_by, :destroy_by
189
201
  check_query_arguments call.arglist
190
202
  when :order, :group, :reorder
191
203
  check_order_arguments call.arglist
@@ -199,7 +211,7 @@ class Brakeman::CheckSQL < Brakeman::BaseCheck
199
211
  unsafe_sql? call.first_arg
200
212
  when :sql
201
213
  unsafe_sql? call.first_arg
202
- when :update_all, :select
214
+ when :update_all, :select, :reselect
203
215
  check_update_all_arguments call.args
204
216
  when *@connection_calls
205
217
  check_by_sql_arguments call.first_arg
@@ -579,6 +591,10 @@ class Brakeman::CheckSQL < Brakeman::BaseCheck
579
591
  :where_values_hash, :foreign_key, :uuid
580
592
  ]
581
593
 
594
+ def ignore_methods_in_sql
595
+ @ignore_methods_in_sql ||= IGNORE_METHODS_IN_SQL + (tracker.options[:sql_safe_methods] || [])
596
+ end
597
+
582
598
  def safe_value? exp
583
599
  return true unless sexp? exp
584
600
 
@@ -589,10 +605,7 @@ class Brakeman::CheckSQL < Brakeman::BaseCheck
589
605
  if exp.method == :to_s or exp.method == :to_sym
590
606
  safe_value? exp.target
591
607
  else
592
- IGNORE_METHODS_IN_SQL.include? exp.method or
593
- quote_call? exp or
594
- arel? exp or
595
- exp.method.to_s.end_with? "_id"
608
+ ignore_call? exp
596
609
  end
597
610
  when :if
598
611
  safe_value? exp.then_clause and safe_value? exp.else_clause
@@ -607,6 +620,18 @@ class Brakeman::CheckSQL < Brakeman::BaseCheck
607
620
  end
608
621
  end
609
622
 
623
+ def ignore_call? exp
624
+ return unless call? exp
625
+
626
+ ignore_methods_in_sql.include? exp.method or
627
+ quote_call? exp or
628
+ arel? exp or
629
+ exp.method.to_s.end_with? "_id" or
630
+ number_target? exp or
631
+ date_target? exp or
632
+ locale_call? exp
633
+ end
634
+
610
635
  QUOTE_METHODS = [:quote, :quote_column_name, :quoted_date, :quote_string, :quote_table_name]
611
636
 
612
637
  def quote_call? exp
@@ -695,4 +720,30 @@ class Brakeman::CheckSQL < Brakeman::BaseCheck
695
720
  active_record_models.include? klass
696
721
  end
697
722
  end
723
+
724
+ def number_target? exp
725
+ return unless call? exp
726
+
727
+ if number? exp.target
728
+ true
729
+ elsif call? exp.target
730
+ number_target? exp.target
731
+ else
732
+ false
733
+ end
734
+ end
735
+
736
+ DATE_CLASS = s(:const, :Date)
737
+
738
+ def date_target? exp
739
+ return unless call? exp
740
+
741
+ if exp.target == DATE_CLASS
742
+ true
743
+ elsif call? exp.target
744
+ date_target? exp.target
745
+ else
746
+ false
747
+ end
748
+ end
698
749
  end
@@ -9,7 +9,7 @@ class Brakeman::CheckSymbolDoS < Brakeman::BaseCheck
9
9
 
10
10
  def run_check
11
11
  return if rails_version and rails_version >= "5.0.0"
12
- return if tracker.config.ruby_version >= "2.2"
12
+ return if tracker.config.ruby_version and tracker.config.ruby_version >= "2.2"
13
13
 
14
14
  tracker.find_call(:methods => UNSAFE_METHODS, :nested => true).each do |result|
15
15
  check_unsafe_symbol_creation(result)
@@ -32,7 +32,7 @@ class Brakeman::CheckVerbConfusion < Brakeman::BaseCheck
32
32
  return
33
33
  end
34
34
 
35
- process method[:src]
35
+ process method.src
36
36
  end
37
37
 
38
38
  def process_if exp
@@ -0,0 +1,47 @@
1
+ require 'date'
2
+ require 'brakeman/checks/base_check'
3
+
4
+ # Not used directly - base check for EOLRails and EOLRuby
5
+ class Brakeman::EOLCheck < Brakeman::BaseCheck
6
+ def check_eol_version library, eol_dates
7
+ version = case library
8
+ when :rails
9
+ tracker.config.rails_version
10
+ when :ruby
11
+ tracker.config.ruby_version
12
+ else
13
+ raise 'Implement using tracker.config.gem_version'
14
+ end
15
+
16
+ eol_dates.each do |(start_version, end_version), eol_date|
17
+ if version_between? start_version, end_version, version
18
+ case
19
+ when Date.today >= eol_date
20
+ warn_about_unsupported_version library, eol_date, version
21
+ when (Date.today + 30) >= eol_date
22
+ warn_about_soon_unsupported_version library, eol_date, version, :medium
23
+ when (Date.today + 60) >= eol_date
24
+ warn_about_soon_unsupported_version library, eol_date, version, :low
25
+ end
26
+
27
+ break
28
+ end
29
+ end
30
+ end
31
+
32
+ def warn_about_soon_unsupported_version library, eol_date, version, confidence
33
+ warn warning_type: 'Unmaintained Dependency',
34
+ warning_code: :"pending_eol_#{library}",
35
+ message: msg("Support for ", msg_version(version, library.capitalize), " ends on #{eol_date}"),
36
+ confidence: confidence,
37
+ gem_info: gemfile_or_environment
38
+ end
39
+
40
+ def warn_about_unsupported_version library, eol_date, version
41
+ warn warning_type: 'Unmaintained Dependency',
42
+ warning_code: :"eol_#{library}",
43
+ message: msg("Support for ", msg_version(version, library.capitalize), " ended on #{eol_date}"),
44
+ confidence: :high,
45
+ gem_info: gemfile_or_environment
46
+ end
47
+ end
@@ -1,3 +1,5 @@
1
+ require 'parallel'
2
+
1
3
  module Brakeman
2
4
  ASTFile = Struct.new(:path, :ast)
3
5
 
@@ -5,29 +7,62 @@ module Brakeman
5
7
  class FileParser
6
8
  attr_reader :file_list, :errors
7
9
 
8
- def initialize app_tree, timeout
10
+ def initialize app_tree, timeout, parallel = true
9
11
  @app_tree = app_tree
10
12
  @timeout = timeout
11
13
  @file_list = []
12
14
  @errors = []
15
+ @parallel = parallel
13
16
  end
14
17
 
15
18
  def parse_files list
16
- read_files list do |path, contents|
17
- if ast = parse_ruby(contents, path.relative)
18
- ASTFile.new(path, ast)
19
+ if @parallel
20
+ parallel_options = {}
21
+ else
22
+ # Disable parallelism
23
+ parallel_options = { in_threads: 0 }
24
+ end
25
+
26
+ # Parse the files in parallel.
27
+ # By default, the parsing will be in separate processes.
28
+ # So we map the result to ASTFiles and/or Exceptions
29
+ # then partition them into ASTFiles and Exceptions
30
+ # and add the Exceptions to @errors
31
+ #
32
+ # Basically just a funky way to deal with two possible
33
+ # return types that are returned from isolated processes.
34
+ #
35
+ # Note this method no longer uses read_files
36
+ @file_list, new_errors = Parallel.map(list, parallel_options) do |file_name|
37
+ file_path = @app_tree.file_path(file_name)
38
+ contents = file_path.read
39
+
40
+ begin
41
+ if ast = parse_ruby(contents, file_path.relative)
42
+ ASTFile.new(file_name, ast)
43
+ end
44
+ rescue Exception => e
45
+ e
19
46
  end
47
+ end.compact.partition do |result|
48
+ result.is_a? ASTFile
20
49
  end
50
+
51
+ errors.concat new_errors
21
52
  end
22
53
 
23
54
  def read_files list
24
55
  list.each do |path|
25
56
  file = @app_tree.file_path(path)
26
57
 
27
- result = yield file, file.read
58
+ begin
59
+ result = yield file, file.read
28
60
 
29
- if result
30
- @file_list << result
61
+ if result
62
+ @file_list << result
63
+ end
64
+ rescue Exception => e
65
+ @errors << e
31
66
  end
32
67
  end
33
68
  end
@@ -42,17 +77,12 @@ module Brakeman
42
77
  Brakeman.debug "Parsing #{path}"
43
78
  RubyParser.new.parse input, path, @timeout
44
79
  rescue Racc::ParseError => e
45
- error e.exception(e.message + "\nCould not parse #{path}")
80
+ raise e.exception(e.message + "\nCould not parse #{path}")
46
81
  rescue Timeout::Error => e
47
- error Exception.new("Parsing #{path} took too long (> #{@timeout} seconds). Try increasing the limit with --parser-timeout")
82
+ raise Exception.new("Parsing #{path} took too long (> #{@timeout} seconds). Try increasing the limit with --parser-timeout")
48
83
  rescue => e
49
- error e.exception(e.message + "\nWhile processing #{path}")
84
+ raise e.exception(e.message + "\nWhile processing #{path}")
50
85
  end
51
86
  end
52
-
53
- def error exception
54
- @errors << exception
55
- nil
56
- end
57
87
  end
58
88
  end
@@ -39,7 +39,7 @@ module Brakeman::Options
39
39
  OptionParser.new do |opts|
40
40
  opts.banner = "Usage: brakeman [options] rails/root/path"
41
41
 
42
- opts.on "-n", "--no-threads", "Run checks sequentially" do
42
+ opts.on "-n", "--no-threads", "Run checks and file parsing sequentially" do
43
43
  options[:parallel_checks] = false
44
44
  end
45
45
 
@@ -93,6 +93,14 @@ module Brakeman::Options
93
93
  options[:rails6] = true
94
94
  end
95
95
 
96
+ opts.on "-7", "--rails7", "Force Rails 7 mode" do
97
+ options[:rails3] = true
98
+ options[:rails4] = true
99
+ options[:rails5] = true
100
+ options[:rails6] = true
101
+ options[:rails7] = true
102
+ end
103
+
96
104
  opts.separator ""
97
105
  opts.separator "Scanning options:"
98
106
 
@@ -151,6 +159,11 @@ module Brakeman::Options
151
159
  options[:safe_methods].merge methods.map {|e| e.to_sym }
152
160
  end
153
161
 
162
+ opts.on "--sql-safe-methods meth1,meth2,etc", Array, "Do not warn of SQL if the input is wrapped in a safe method" do |methods|
163
+ options[:sql_safe_methods] ||= Set.new
164
+ options[:sql_safe_methods].merge methods.map {|e| e.to_sym }
165
+ end
166
+
154
167
  opts.on "--url-safe-methods method1,method2,etc", Array, "Do not warn of XSS if the link_to href parameter is wrapped in a safe method" do |methods|
155
168
  options[:url_safe_methods] ||= Set.new
156
169
  options[:url_safe_methods].merge methods.map {|e| e.to_sym }
@@ -233,7 +246,7 @@ module Brakeman::Options
233
246
 
234
247
  opts.on "-f",
235
248
  "--format TYPE",
236
- [:pdf, :text, :html, :csv, :tabs, :json, :markdown, :codeclimate, :cc, :plain, :table, :junit, :sarif, :sonar],
249
+ [:pdf, :text, :html, :csv, :tabs, :json, :markdown, :codeclimate, :cc, :plain, :table, :junit, :sarif, :sonar, :github],
237
250
  "Specify output formats. Default is text" do |type|
238
251
 
239
252
  type = "s" if type == :text