brakeman-min 6.1.1 → 6.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9bda2b7f2e2e83fd353b042c9c11857eb8d7bae3a3d2f3eb6facc97f58f3df06
4
- data.tar.gz: ae4fd6a45a603d654ac5a8477810b5a79ee4041ed73e6f3bb59aea75bdf890a5
3
+ metadata.gz: 9a6b0a21e0bcd1760b239f11c2350abd2b3aeef743925e568313f73fe7d04723
4
+ data.tar.gz: 054611dc13f667e53b68ec0491973a85d29ed2d47015e0ea7fa623f47b28672f
5
5
  SHA512:
6
- metadata.gz: 933fa4eebb2014b09c59e9bc946db21717cd9ba0b30eeeb3423fff4b8288f686161a5e33fa9e4c97f538e7aaaddc960e9826af77bc8f87dbe2dcfb846b915f7d
7
- data.tar.gz: 131ddf8b1c80d4d113f8255dd2d10101d3e11c904f8ac364dfdca00d63ebd38c477abd7a0f606f3de293a55e4aaf27b61affdd8c1de86d0c26d6653d3a1904ec
6
+ metadata.gz: 821a08146a597fbb48cd08312d3310e2d20401bd4d53403beb74615ec2c3cce261ea9f672a42243ffdd5c748a3abec65acf14930fb3f8f59014aabfae6ea65ee
7
+ data.tar.gz: a4c29407ad9ac73dba0c93f7f3d5e08056e00351ffc3406c01390e2f64386982053382f50d65c41b94613eaecae28180cb1001c9afce554d265fb7c1fb25b5ce
data/CHANGES.md CHANGED
@@ -1,3 +1,27 @@
1
+ # 6.2.0 - 2024-08-22
2
+
3
+ * Add `--show-ignored` option (Gabriel Zayas)
4
+ * Add optional support for Prism parser
5
+ * Warn about unscoped finds with `find_by!`
6
+ * Treat `::X` and `X` the same, for now (Jill Klang)
7
+ * Fix compatibility with default frozen string literals (Jean Boussier)
8
+ * Remediation advice for command injection (Nicholas Barone)
9
+ * Fix Ruby warnings in test suite (Jean Boussier)
10
+ * Support YAML aliases in secret configs (Chedli Bourguiba)
11
+ * Add initial Rails 8 support (Ron Shinall)
12
+ * Handle mass assignment with splats
13
+ * Add support for symbolic links (Lu Zhu)
14
+
15
+ # 6.1.2 - 2024-02-01
16
+
17
+ * Update Highline to 3.0
18
+ * Add EOL date for Ruby 3.3.0
19
+ * Avoid copying Sexps that are too large
20
+ * Avoid detecting `ViewComponentContrib::Base` as dynamic render paths (vividmuimui)
21
+ * Remove deprecated use of `Kernel#open("|...")`
22
+ * Remove `safe_yaml` gem dependency
23
+ * Avoid detecting Phlex components as dynamic render paths (Máximo Mussini)
24
+
1
25
  # 6.1.1 - 2023-12-24
2
26
 
3
27
  * Handle racc as a default gem in Ruby 3.3.0
data/README.md CHANGED
@@ -18,7 +18,7 @@ Using Bundler:
18
18
 
19
19
  ```ruby
20
20
  group :development do
21
- gem 'brakeman'
21
+ gem 'brakeman', require: false
22
22
  end
23
23
  ```
24
24
 
@@ -133,6 +133,10 @@ To create and manage this file, use:
133
133
 
134
134
  brakeman -I
135
135
 
136
+ If you want to temporarily see the warnings you ignored without affecting the exit code, use:
137
+
138
+ brakeman --show-ignored
139
+
136
140
  # Warning information
137
141
 
138
142
  See [warning\_types](docs/warning_types) for more information on the warnings reported by this tool.
@@ -50,7 +50,7 @@ module Brakeman
50
50
  "#{Regexp.escape f}\\z"
51
51
  end
52
52
  end
53
- Regexp.new("(?:" << path_regexes.join("|") << ")")
53
+ Regexp.new("(?:#{path_regexes.join("|")})")
54
54
  end
55
55
  private_class_method(:regex_for_paths)
56
56
 
@@ -161,9 +161,21 @@ module Brakeman
161
161
  end
162
162
 
163
163
  def glob_files(directory, name, extensions = ".rb")
164
- pattern = "#{root_search_pattern}#{directory}/**/#{name}#{extensions}"
164
+ root_directory = "#{root_search_pattern}#{directory}"
165
+ patterns = ["#{root_directory}/**/#{name}#{extensions}"]
166
+
167
+ Dir.glob("#{root_directory}/**/*", File::FNM_DOTMATCH).each do |path|
168
+ if File.symlink?(path) && File.directory?(path)
169
+ symlink_target = File.readlink(path)
170
+ if Pathname.new(symlink_target).relative?
171
+ symlink_target = File.join(File.dirname(path), symlink_target)
172
+ end
173
+ patterns << "#{search_pattern(symlink_target)}/**/#{name}#{extensions}"
174
+ end
175
+ end
165
176
 
166
- Dir.glob(pattern)
177
+ files = patterns.flat_map { |pattern| Dir.glob(pattern) }
178
+ files.uniq
167
179
  end
168
180
 
169
181
  def select_files(paths)
@@ -237,13 +249,16 @@ module Brakeman
237
249
 
238
250
  def root_search_pattern
239
251
  return @root_search_pattern if @root_search_pattern
252
+ @root_search_pattern = search_pattern(@root)
253
+ end
240
254
 
255
+ def search_pattern(root_dir)
241
256
  abs = @absolute_engine_paths.to_a.map { |path| path.gsub(/#{File::SEPARATOR}+$/, '') }
242
257
  rel = @relative_engine_paths.to_a.map { |path| path.gsub(/#{File::SEPARATOR}+$/, '') }
243
258
 
244
- roots = ([@root] + abs).join(",")
259
+ roots = ([root_dir] + abs).join(",")
245
260
  rel_engines = (rel + [""]).join("/,")
246
- @root_search_pattern = "{#{roots}}/{#{rel_engines}}"
261
+ "{#{roots}}/{#{rel_engines}}"
247
262
  end
248
263
 
249
264
  def prioritize_concerns paths
@@ -24,5 +24,6 @@ class Brakeman::CheckEOLRuby < Brakeman::EOLCheck
24
24
  ['3.0.0', '3.0.99'] => Date.new(2024, 3, 31),
25
25
  ['3.1.0', '3.1.99'] => Date.new(2025, 3, 31),
26
26
  ['3.2.0', '3.2.99'] => Date.new(2026, 3, 31),
27
+ ['3.3.0', '3.3.99'] => Date.new(2027, 3, 31),
27
28
  }
28
29
  end
@@ -108,6 +108,11 @@ class Brakeman::CheckRender < Brakeman::BaseCheck
108
108
  def known_renderable_class? class_name
109
109
  klass = tracker.find_class(class_name)
110
110
  return false if klass.nil?
111
- klass.ancestor? :"ViewComponent::Base"
111
+ knowns = [
112
+ :"ViewComponent::Base",
113
+ :"ViewComponentContrib::Base",
114
+ :"Phlex::HTML"
115
+ ]
116
+ knowns.any? { |k| klass.ancestor? k }
112
117
  end
113
118
  end
@@ -116,10 +116,9 @@ class Brakeman::CheckSessionSettings < Brakeman::BaseCheck
116
116
 
117
117
  if secrets_file.exists? and not ignored? "secrets.yml" and not ignored? "config/*.yml"
118
118
  yaml = secrets_file.read
119
- require 'date' # https://github.com/dtao/safe_yaml/issues/80
120
- require 'safe_yaml/load'
119
+ require 'yaml'
121
120
  begin
122
- secrets = SafeYAML.load yaml
121
+ secrets = YAML.safe_load yaml, aliases: true
123
122
  rescue Psych::SyntaxError, RuntimeError => e
124
123
  Brakeman.notify "[Notice] #{self.class}: Unable to parse `#{secrets_file}`"
125
124
  Brakeman.debug "Failed to parse #{secrets_file}: #{e.inspect}"
@@ -24,7 +24,7 @@ class Brakeman::CheckUnscopedFind < Brakeman::BaseCheck
24
24
  process_result call
25
25
  end
26
26
 
27
- tracker.find_call(:method => :find_by, :targets => associated_model_names).each do |result|
27
+ tracker.find_call(:methods => [:find_by, :find_by!], :targets => associated_model_names).each do |result|
28
28
  arg = result[:call].first_arg
29
29
 
30
30
  if hash? arg and hash_access(arg, :id)
@@ -7,7 +7,18 @@ module Brakeman
7
7
  class FileParser
8
8
  attr_reader :file_list, :errors
9
9
 
10
- def initialize app_tree, timeout, parallel = true
10
+ def initialize app_tree, timeout, parallel = true, use_prism = false
11
+ @use_prism = use_prism
12
+
13
+ if @use_prism
14
+ begin
15
+ require 'prism'
16
+ rescue LoadError => e
17
+ Brakeman.debug "Asked to use Prism, but failed to load: #{e}"
18
+ @use_prism = false
19
+ end
20
+ end
21
+
11
22
  @app_tree = app_tree
12
23
  @timeout = timeout
13
24
  @file_list = []
@@ -73,8 +84,29 @@ module Brakeman
73
84
  path = path.relative
74
85
  end
75
86
 
87
+ Brakeman.debug "Parsing #{path}"
88
+
89
+ if @use_prism
90
+ begin
91
+ parse_with_prism input, path
92
+ rescue => e
93
+ Brakeman.debug "Prism failed to parse #{path}: #{e}"
94
+
95
+ parse_with_ruby_parser input, path
96
+ end
97
+ else
98
+ parse_with_ruby_parser input, path
99
+ end
100
+ end
101
+
102
+ private
103
+
104
+ def parse_with_prism input, path
105
+ Prism::Translation::RubyParser.parse(input, path)
106
+ end
107
+
108
+ def parse_with_ruby_parser input, path
76
109
  begin
77
- Brakeman.debug "Parsing #{path}"
78
110
  RubyParser.new.parse input, path, @timeout
79
111
  rescue Racc::ParseError => e
80
112
  raise e.exception(e.message + "\nCould not parse #{path}")
@@ -101,6 +101,15 @@ module Brakeman::Options
101
101
  options[:rails7] = true
102
102
  end
103
103
 
104
+ opts.on "-8", "--rails8", "Force Rails 8 mode" do
105
+ options[:rails3] = true
106
+ options[:rails4] = true
107
+ options[:rails5] = true
108
+ options[:rails6] = true
109
+ options[:rails7] = true
110
+ options[:rails8] = true
111
+ end
112
+
104
113
  opts.separator ""
105
114
  opts.separator "Scanning options:"
106
115
 
@@ -150,6 +159,23 @@ module Brakeman::Options
150
159
  options[:parser_timeout] = timeout
151
160
  end
152
161
 
162
+ opts.on "--[no-]prism", "Use the Prism parser" do |use_prism|
163
+ if use_prism
164
+ prism_version = '0.30'
165
+
166
+ begin
167
+ # Specifying minimum version here,
168
+ # since it can't be in the gem dependency list because it is optional
169
+ gem 'prism', "~>#{prism_version}"
170
+ rescue Gem::MissingSpecVersionError, Gem::MissingSpecError, Gem::LoadError => e
171
+ $stderr.puts "Please install `prism` version #{prism_version} or newer:"
172
+ raise e
173
+ end
174
+ end
175
+
176
+ options[:use_prism] = use_prism
177
+ end
178
+
153
179
  opts.on "-r", "--report-direct", "Only report direct use of untrusted data" do |option|
154
180
  options[:check_arguments] = !option
155
181
  end
@@ -202,7 +228,7 @@ module Brakeman::Options
202
228
  if check.start_with? "Check"
203
229
  check
204
230
  else
205
- "Check" << check
231
+ "Check#{check}"
206
232
  end
207
233
  end
208
234
 
@@ -213,7 +239,7 @@ module Brakeman::Options
213
239
  opts.on "-t", "--test Check1,Check2,etc", Array, "Only run the specified checks" do |checks|
214
240
  checks.each_with_index do |s, index|
215
241
  if s[0,5] != "Check"
216
- checks[index] = "Check" << s
242
+ checks[index] = "Check#{s}"
217
243
  end
218
244
  end
219
245
 
@@ -224,7 +250,7 @@ module Brakeman::Options
224
250
  opts.on "-x", "--except Check1,Check2,etc", Array, "Skip the specified checks" do |skip|
225
251
  skip.each do |s|
226
252
  if s[0,5] != "Check"
227
- s = "Check" << s
253
+ s = "Check#{s}"
228
254
  end
229
255
 
230
256
  options[:skip_checks] ||= Set.new
@@ -254,7 +280,7 @@ module Brakeman::Options
254
280
  "Specify output formats. Default is text" do |type|
255
281
 
256
282
  type = "s" if type == :text
257
- options[:output_format] = ("to_" << type.to_s).to_sym
283
+ options[:output_format] = :"to_#{type}"
258
284
  end
259
285
 
260
286
  opts.on "--css-file CSSFile", "Specify CSS to use for HTML output" do |file|
@@ -269,6 +295,10 @@ module Brakeman::Options
269
295
  options[:interactive_ignore] = true
270
296
  end
271
297
 
298
+ opts.on "--show-ignored", "Show files that are usually ignored by the ignore configuration file" do
299
+ options[:show_ignored] = true
300
+ end
301
+
272
302
  opts.on "-l", "--[no-]combine-locations", "Combine warning locations (Default)" do |combine|
273
303
  options[:combine_locations] = combine
274
304
  end
@@ -0,0 +1,11 @@
1
+ module Brakeman::ErubisPatch
2
+ # Simple patch to make `erubis` compatible with frozen string literals
3
+ def convert(input)
4
+ codebuf = +"" # Modified line, the rest is identitical
5
+ @preamble.nil? ? add_preamble(codebuf) : (@preamble && (codebuf << @preamble))
6
+ convert_input(codebuf, input)
7
+ @postamble.nil? ? add_postamble(codebuf) : (@postamble && (codebuf << @postamble))
8
+ @_proc = nil # clear cached proc object
9
+ return codebuf # or codebuf.join()
10
+ end
11
+ end
@@ -1,6 +1,9 @@
1
1
  Brakeman.load_brakeman_dependency 'erubis'
2
2
 
3
+ require 'brakeman/parsers/erubis_patch'
4
+
3
5
  #Erubis processor which ignores any output which is plain text.
4
6
  class Brakeman::ScannerErubis < Erubis::Eruby
5
7
  include Erubis::NoTextEnhancer
8
+ include Brakeman::ErubisPatch
6
9
  end
@@ -1,7 +1,11 @@
1
1
  Brakeman.load_brakeman_dependency 'erubis'
2
2
 
3
+ require 'brakeman/parsers/erubis_patch'
4
+
3
5
  #This is from the rails_xss plugin for Rails 2
4
6
  class Brakeman::Rails2XSSPluginErubis < ::Erubis::Eruby
7
+ include Brakeman::ErubisPatch
8
+
5
9
  def add_preamble(src)
6
10
  #src << "@output_buffer = ActiveSupport::SafeBuffer.new;"
7
11
  end
@@ -1,11 +1,15 @@
1
1
  Brakeman.load_brakeman_dependency 'erubis'
2
2
 
3
+ require 'brakeman/parsers/erubis_patch'
4
+
3
5
  # This is from Rails 5 version of the Erubis handler
4
6
  # https://github.com/rails/rails/blob/ec608107801b1e505db03ba76bae4a326a5804ca/actionview/lib/action_view/template/handlers/erb.rb#L7-L73
5
7
  class Brakeman::Rails3Erubis < ::Erubis::Eruby
8
+ include Brakeman::ErubisPatch
6
9
 
7
10
  def add_preamble(src)
8
11
  @newline_pending = 0
12
+ src << "_this_is_to_make_yields_syntactally_correct {"
9
13
  src << "@output_buffer = output_buffer || ActionView::OutputBuffer.new;"
10
14
  end
11
15
 
@@ -62,7 +66,7 @@ class Brakeman::Rails3Erubis < ::Erubis::Eruby
62
66
 
63
67
  def add_postamble(src)
64
68
  flush_newline_if_pending(src)
65
- src << '@output_buffer.to_s'
69
+ src << '@output_buffer.to_s; }'
66
70
  end
67
71
 
68
72
  def flush_newline_if_pending(src)
@@ -2,6 +2,7 @@
2
2
  module Slim
3
3
  class Embedded
4
4
  class TiltEngine
5
+ alias_method :on_slim_embedded, :on_slim_embedded # silence redefined method warning
5
6
  def on_slim_embedded(engine, body, attrs)
6
7
  # Override this method to avoid Slim trying to load sass/scss and failing
7
8
  case engine
@@ -22,6 +23,7 @@ module Slim
22
23
  class SassEngine
23
24
  protected
24
25
 
26
+ alias_method :tilt_render, :tilt_render # silence redefined method warning
25
27
  def tilt_render(tilt_engine, tilt_options, text)
26
28
  [:dynamic,
27
29
  "BrakemanFilter.render(#{text.inspect}, #{self.class})"]
@@ -32,6 +32,7 @@ class Brakeman::AliasProcessor < Brakeman::SexpProcessor
32
32
  @or_depth_limit = (tracker && tracker.options[:branch_limit]) || 5 #arbitrary default
33
33
  @meth_env = nil
34
34
  @current_file = current_file
35
+ @mass_limit = (tracker && tracker.options[:mass_limit]) || 1000 # arbitrary default
35
36
  set_env_defaults
36
37
  end
37
38
 
@@ -82,8 +83,12 @@ class Brakeman::AliasProcessor < Brakeman::SexpProcessor
82
83
  def replace exp, int = 0
83
84
  return exp if int > 3
84
85
 
85
- if replacement = env[exp] and not duplicate? replacement
86
- replace(replacement.deep_clone(exp.line), int + 1)
86
+ if replacement = env[exp]
87
+ if not duplicate? replacement and replacement.mass < @mass_limit
88
+ replace(replacement.deep_clone(exp.line), int + 1)
89
+ else
90
+ exp
91
+ end
87
92
  elsif tracker and replacement = tracker.constant_lookup(exp) and not duplicate? replacement
88
93
  replace(replacement.deep_clone(exp.line), int + 1)
89
94
  else
@@ -368,7 +373,7 @@ class Brakeman::AliasProcessor < Brakeman::SexpProcessor
368
373
  result << join_item(array.last, nil)
369
374
 
370
375
  # Combine the strings at the beginning because that's what RubyParser does
371
- combined_first = ""
376
+ combined_first = +""
372
377
  result.each do |e|
373
378
  if string? e
374
379
  combined_first << e.value
@@ -660,7 +665,7 @@ class Brakeman::AliasProcessor < Brakeman::SexpProcessor
660
665
  exp[2] = exp[2][1]
661
666
  end
662
667
 
663
- unless array? exp[1] and array? exp[2] and exp[1].length == exp[2].length
668
+ unless array? exp[1] and array? exp[2]
664
669
  return process_default(exp)
665
670
  end
666
671
 
@@ -673,21 +678,42 @@ class Brakeman::AliasProcessor < Brakeman::SexpProcessor
673
678
  # Call each assignment as if it is normal
674
679
  vars.each_with_index do |var, i|
675
680
  val = vals[i]
676
- if val
681
+ next unless val # TODO: Break if there are no vals left?
682
+
683
+ # This happens with nested destructuring like
684
+ # x, (a, b) = blah
685
+ if node_type? var, :masgn
686
+ # Need to add value to masgn exp
687
+ m = var.dup
688
+ m[2] = s(:to_ary, val)
677
689
 
678
- # This happens with nested destructuring like
679
- # x, (a, b) = blah
680
- if node_type? var, :masgn
681
- # Need to add value to masgn exp
682
- m = var.dup
683
- m[2] = s(:to_ary, val)
690
+ process_masgn m
691
+ elsif node_type? var, :splat
692
+ # Assign the rest of the values to the variable:
693
+ #
694
+ # a, *b = 1, 2, 3
695
+ #
696
+ # b == [2, 3]
684
697
 
685
- process_masgn m
698
+
699
+ assign = var[1].dup # var is s(:splat, s(:lasgn, :b))
700
+
701
+ if i == vars.length - 1 # Last variable being assigned, slurp up the rest
702
+ assign.rhs = s(:array, *vals[i..]) # val is the "rest" of the values
686
703
  else
687
- assign = var.dup
688
- assign.rhs = val
689
- process assign
704
+ # Calculate how many values to assign based on how many variables
705
+ # there are.
706
+ #
707
+ # If there are more values than variables, the splat gets an empty array.
708
+
709
+ assign.rhs = s(:array, *vals[i, (vals.length - vars.length + 1)]).line(vals.line)
690
710
  end
711
+
712
+ process assign
713
+ else
714
+ assign = var.dup
715
+ assign.rhs = val
716
+ process assign
691
717
  end
692
718
  end
693
719
 
@@ -52,7 +52,7 @@ module Brakeman
52
52
  def page_via_less text
53
53
  # Adapted from https://github.com/piotrmurach/tty-pager/
54
54
 
55
- write_io = open("|less #{less_options.join}", 'w')
55
+ write_io = IO.popen("less #{less_options.join}", 'w')
56
56
  pid = write_io.pid
57
57
 
58
58
  write_io.write(text)
@@ -27,7 +27,7 @@ class Brakeman::Report::Markdown < Brakeman::Report::Table
27
27
  end
28
28
 
29
29
  def generate_report
30
- out = "# BRAKEMAN REPORT\n\n" <<
30
+ out = +"# BRAKEMAN REPORT\n\n" <<
31
31
  generate_metadata.to_s << "\n\n" <<
32
32
  generate_checks.to_s << "\n\n" <<
33
33
  "### SUMMARY\n\n" <<
@@ -8,7 +8,7 @@ class Brakeman::Report::Table < Brakeman::Report::Base
8
8
 
9
9
  def generate_report
10
10
  summary_option = tracker.options[:summary_only]
11
- out = ""
11
+ out = +""
12
12
 
13
13
  unless summary_option == :no_summary
14
14
  out << text_header <<
@@ -166,7 +166,7 @@ class Brakeman::Report::Table < Brakeman::Report::Base
166
166
 
167
167
  template_rows = template_rows.sort_by{|name, value| name.to_s}
168
168
 
169
- output = ''
169
+ output = +''
170
170
  template_rows.each do |template|
171
171
  output << template.first.to_s << "\n\n"
172
172
  table = @table.new(:headings => ['Output']) do |t|
@@ -9,7 +9,6 @@ class Brakeman::Report::Tabs < Brakeman::Report::Table
9
9
 
10
10
  self.send(meth).map do |w|
11
11
  line = w.line || 0
12
- w.warning_type.gsub!(/[^\w\s]/, ' ')
13
12
  "#{(w.file.absolute)}\t#{line}\t#{w.warning_type}\t#{category}\t#{w.format_message}\t#{w.confidence_name}"
14
13
  end.join "\n"
15
14
 
@@ -4,7 +4,7 @@ class Brakeman::Report::Text < Brakeman::Report::Base
4
4
  def generate_report
5
5
  HighLine.use_color = !!tracker.options[:output_color]
6
6
  summary_option = tracker.options[:summary_only]
7
- @output_string = "\n"
7
+ @output_string = +"\n"
8
8
 
9
9
  unless summary_option == :no_summary
10
10
  add_chunk generate_header
@@ -21,6 +21,9 @@ class Brakeman::Report::Text < Brakeman::Report::Base
21
21
  add_chunk generate_obsolete
22
22
  add_chunk generate_errors
23
23
  add_chunk generate_warnings
24
+ add_chunk generate_show_ignored_overview if tracker.options[:show_ignored] && ignored_warnings.any?
25
+
26
+ @output_string
24
27
  end
25
28
 
26
29
  def add_chunk chunk, out = @output_string
@@ -101,6 +104,10 @@ class Brakeman::Report::Text < Brakeman::Report::Base
101
104
  end
102
105
  end
103
106
 
107
+ def generate_show_ignored_overview
108
+ double_space("Ignored Warnings", ignored_warnings.map {|w| output_warning w})
109
+ end
110
+
104
111
  def generate_errors
105
112
  return if tracker.errors.empty?
106
113
  full_trace = tracker.options[:debug]
@@ -125,7 +125,7 @@ class Brakeman::Scanner
125
125
  end
126
126
 
127
127
  def parse_files
128
- fp = Brakeman::FileParser.new(tracker.app_tree, tracker.options[:parser_timeout], tracker.options[:parallel_checks])
128
+ fp = Brakeman::FileParser.new(tracker.app_tree, tracker.options[:parser_timeout], tracker.options[:parallel_checks], tracker.options[:use_prism])
129
129
 
130
130
  fp.parse_files tracker.app_tree.ruby_file_paths
131
131
 
@@ -414,7 +414,7 @@ class Brakeman::Scanner
414
414
  end
415
415
 
416
416
  def parse_ruby_file file
417
- fp = Brakeman::FileParser.new(tracker.app_tree, tracker.options[:parser_timeout])
417
+ fp = Brakeman::FileParser.new(tracker.app_tree, tracker.options[:parser_timeout], false, tracker.options[:use_prism])
418
418
  fp.parse_ruby(file.read, file)
419
419
  rescue Exception => e
420
420
  tracker.error(e)
@@ -111,6 +111,14 @@ module Brakeman
111
111
  tracker.options[:rails6] = true
112
112
  tracker.options[:rails7] = true
113
113
  Brakeman.notify "[Notice] Detected Rails 7 application"
114
+ elsif @rails_version.start_with? "8"
115
+ tracker.options[:rails3] = true
116
+ tracker.options[:rails4] = true
117
+ tracker.options[:rails5] = true
118
+ tracker.options[:rails6] = true
119
+ tracker.options[:rails7] = true
120
+ tracker.options[:rails8] = true
121
+ Brakeman.notify "[Notice] Detected Rails 8 application"
114
122
  end
115
123
  end
116
124
  end
@@ -193,7 +201,7 @@ module Brakeman
193
201
 
194
202
  version = tracker.config.rails[:load_defaults].value.to_s
195
203
 
196
- unless version.match? /^\d+\.\d+$/
204
+ unless version.match?(/^\d+\.\d+$/)
197
205
  Brakeman.debug "[Notice] Unknown version: #{tracker.config.rails[:load_defaults]}"
198
206
  return
199
207
  end
data/lib/brakeman/util.rb CHANGED
@@ -63,14 +63,12 @@ module Brakeman::Util
63
63
  case exp
64
64
  when Sexp
65
65
  case exp.node_type
66
- when :const
66
+ when :const, :colon3
67
67
  exp.value
68
68
  when :lvar
69
69
  exp.value.to_sym
70
70
  when :colon2
71
71
  "#{class_name(exp.lhs)}::#{exp.rhs}".to_sym
72
- when :colon3
73
- "::#{exp.value}".to_sym
74
72
  when :self
75
73
  @current_class || @current_module || nil
76
74
  else
@@ -1,3 +1,3 @@
1
1
  module Brakeman
2
- Version = "6.1.1"
2
+ Version = "6.2.0"
3
3
  end
@@ -317,7 +317,7 @@ class Brakeman::Warning
317
317
 
318
318
  def format_ruby code, strip
319
319
  formatted = Brakeman::OutputProcessor.new.format(code)
320
- formatted.gsub!(/(\t|\r|\n)+/, " ") if strip
320
+ formatted = formatted.gsub(/(\t|\r|\n)+/, " ") if strip
321
321
  formatted
322
322
  end
323
323
  end
data/lib/brakeman.rb CHANGED
@@ -65,6 +65,7 @@ module Brakeman
65
65
  # * :report_routes - show found routes on controllers (default: false)
66
66
  # * :run_checks - array of checks to run (run all if not specified)
67
67
  # * :safe_methods - array of methods to consider safe
68
+ # * :show_ignored - Display warnings that are usually ignored
68
69
  # * :sql_safe_methods - array of sql sanitization methods to consider safe
69
70
  # * :skip_libs - do not process lib/ directory (default: false)
70
71
  # * :skip_vendor - do not process vendor/ directory (default: true)
@@ -128,9 +129,8 @@ module Brakeman
128
129
 
129
130
  #Load configuration file
130
131
  if config = config_file(custom_location, app_path)
131
- require 'date' # https://github.com/dtao/safe_yaml/issues/80
132
- self.load_brakeman_dependency 'safe_yaml/load'
133
- options = SafeYAML.load_file config, :deserialize_symbols => true
132
+ require 'yaml'
133
+ options = YAML.safe_load_file config, permitted_classes: [Symbol], symbolize_names: true
134
134
 
135
135
  if options
136
136
  options.each { |k, v| options[k] = Set.new v if v.is_a? Array }
@@ -199,6 +199,7 @@ module Brakeman
199
199
  :relative_path => false,
200
200
  :report_progress => true,
201
201
  :safe_methods => Set.new,
202
+ :show_ignored => false,
202
203
  :sql_safe_methods => Set.new,
203
204
  :skip_checks => Set.new,
204
205
  :skip_vendor => true,
@@ -6,6 +6,7 @@ class Sexp
6
6
  ASSIGNMENT_BOOL = [:gasgn, :iasgn, :lasgn, :cvdecl, :cvasgn, :cdecl, :or, :and, :colon2, :op_asgn_or]
7
7
  CALLS = [:call, :attrasgn, :safe_call, :safe_attrasgn]
8
8
 
9
+ alias_method :method_missing, :method_missing # silence redefined method warning
9
10
  def method_missing name, *args
10
11
  #Brakeman does not use this functionality,
11
12
  #so overriding it to raise a NoMethodError.
@@ -46,10 +47,12 @@ class Sexp
46
47
  s
47
48
  end
48
49
 
50
+ alias_method :paren, :paren # silence redefined method warning
49
51
  def paren
50
52
  @paren ||= false
51
53
  end
52
54
 
55
+ alias_method :value, :value # silence redefined method warning
53
56
  def value
54
57
  raise WrongSexpError, "Sexp#value called on multi-item Sexp: `#{self.inspect}`" if size > 2
55
58
  self[1]
@@ -98,6 +101,7 @@ class Sexp
98
101
  old_push arg
99
102
  end
100
103
 
104
+ alias_method :hash, :hash # silence redefined method warning
101
105
  def hash
102
106
  #There still seems to be some instances in which the hash of the
103
107
  #Sexp changes, but I have not found what method call is doing it.
@@ -616,7 +620,7 @@ end
616
620
 
617
621
  #Invalidate hash cache if the Sexp changes
618
622
  [:[]=, :clear, :collect!, :compact!, :concat, :delete, :delete_at,
619
- :delete_if, :drop, :drop_while, :fill, :flatten!, :replace, :insert,
623
+ :delete_if, :drop, :drop_while, :fill, :flatten!, :insert,
620
624
  :keep_if, :map!, :pop, :push, :reject!, :replace, :reverse!, :rotate!,
621
625
  :select!, :shift, :shuffle!, :slice!, :sort!, :sort_by!, :transpose,
622
626
  :uniq!, :unshift].each do |method|
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: brakeman-min
3
3
  version: !ruby/object:Gem::Version
4
- version: 6.1.1
4
+ version: 6.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Justin Collins
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-12-24 00:00:00.000000000 Z
11
+ date: 2024-08-22 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: csv
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: minitest
15
29
  requirement: !ruby/object:Gem::Requirement
@@ -114,28 +128,14 @@ dependencies:
114
128
  requirements:
115
129
  - - "~>"
116
130
  - !ruby/object:Gem::Version
117
- version: 2.4.0
131
+ version: 2.5.1
118
132
  type: :runtime
119
133
  prerelease: false
120
134
  version_requirements: !ruby/object:Gem::Requirement
121
135
  requirements:
122
136
  - - "~>"
123
137
  - !ruby/object:Gem::Version
124
- version: 2.4.0
125
- - !ruby/object:Gem::Dependency
126
- name: safe_yaml
127
- requirement: !ruby/object:Gem::Requirement
128
- requirements:
129
- - - ">="
130
- - !ruby/object:Gem::Version
131
- version: '1.0'
132
- type: :runtime
133
- prerelease: false
134
- version_requirements: !ruby/object:Gem::Requirement
135
- requirements:
136
- - - ">="
137
- - !ruby/object:Gem::Version
138
- version: '1.0'
138
+ version: 2.5.1
139
139
  - !ruby/object:Gem::Dependency
140
140
  name: racc
141
141
  requirement: !ruby/object:Gem::Requirement
@@ -262,6 +262,7 @@ files:
262
262
  - lib/brakeman/format/style.css
263
263
  - lib/brakeman/messages.rb
264
264
  - lib/brakeman/options.rb
265
+ - lib/brakeman/parsers/erubis_patch.rb
265
266
  - lib/brakeman/parsers/haml_embedded.rb
266
267
  - lib/brakeman/parsers/rails2_erubis.rb
267
268
  - lib/brakeman/parsers/rails2_xss_plugin_erubis.rb
@@ -376,7 +377,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
376
377
  - !ruby/object:Gem::Version
377
378
  version: '0'
378
379
  requirements: []
379
- rubygems_version: 3.2.3
380
+ rubygems_version: 3.3.27
380
381
  signing_key:
381
382
  specification_version: 4
382
383
  summary: Security vulnerability scanner for Ruby on Rails.