brakeman-lib 6.1.2 → 6.2.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.md +14 -0
- data/README.md +5 -1
- data/lib/brakeman/app_tree.rb +20 -5
- data/lib/brakeman/checks/check_session_settings.rb +1 -1
- data/lib/brakeman/checks/check_unscoped_find.rb +1 -1
- data/lib/brakeman/file_parser.rb +34 -2
- data/lib/brakeman/options.rb +34 -4
- data/lib/brakeman/parsers/erubis_patch.rb +11 -0
- data/lib/brakeman/parsers/rails2_erubis.rb +3 -0
- data/lib/brakeman/parsers/rails2_xss_plugin_erubis.rb +4 -0
- data/lib/brakeman/parsers/rails3_erubis.rb +5 -1
- data/lib/brakeman/parsers/slim_embedded.rb +2 -0
- data/lib/brakeman/processors/alias_processor.rb +34 -13
- data/lib/brakeman/report/report_markdown.rb +1 -1
- data/lib/brakeman/report/report_table.rb +2 -2
- data/lib/brakeman/report/report_tabs.rb +0 -1
- data/lib/brakeman/report/report_text.rb +8 -1
- data/lib/brakeman/scanner.rb +2 -2
- data/lib/brakeman/tracker/config.rb +9 -1
- data/lib/brakeman/util.rb +1 -3
- data/lib/brakeman/version.rb +1 -1
- data/lib/brakeman/warning.rb +1 -1
- data/lib/brakeman.rb +2 -0
- data/lib/ruby_parser/bm_sexp.rb +5 -1
- metadata +24 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8505b612200322b0365a1cca12611c581c4e88c8c31e75bf1e0dcea14619b0e3
|
4
|
+
data.tar.gz: b18f6c46731b0ee1c026b01ae5fd1d9eb19c5ceea59e41d50edbe5c327ccfcb2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3f3b0612e2f45f362784fd26611ae76c2837a612378e7432f7131babca4edea4a1da63bc20d9862adde5309f28557634ebd16a4814749d82c39216e7d4690c56
|
7
|
+
data.tar.gz: af0a5e1edb1762bb76306c7899176f56fd806f02eaeb1c4b92dc1792445f7ebbf9de0c3a57b7c03a20f77d7e6b6452c327850b0ac69a4a10af1f2994dd94c90c
|
data/CHANGES.md
CHANGED
@@ -1,3 +1,17 @@
|
|
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
|
+
|
1
15
|
# 6.1.2 - 2024-02-01
|
2
16
|
|
3
17
|
* Update Highline to 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.
|
data/lib/brakeman/app_tree.rb
CHANGED
@@ -50,7 +50,7 @@ module Brakeman
|
|
50
50
|
"#{Regexp.escape f}\\z"
|
51
51
|
end
|
52
52
|
end
|
53
|
-
Regexp.new("(
|
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
|
-
|
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 = ([
|
259
|
+
roots = ([root_dir] + abs).join(",")
|
245
260
|
rel_engines = (rel + [""]).join("/,")
|
246
|
-
|
261
|
+
"{#{roots}}/{#{rel_engines}}"
|
247
262
|
end
|
248
263
|
|
249
264
|
def prioritize_concerns paths
|
@@ -118,7 +118,7 @@ class Brakeman::CheckSessionSettings < Brakeman::BaseCheck
|
|
118
118
|
yaml = secrets_file.read
|
119
119
|
require 'yaml'
|
120
120
|
begin
|
121
|
-
secrets = YAML.safe_load yaml
|
121
|
+
secrets = YAML.safe_load yaml, aliases: true
|
122
122
|
rescue Psych::SyntaxError, RuntimeError => e
|
123
123
|
Brakeman.notify "[Notice] #{self.class}: Unable to parse `#{secrets_file}`"
|
124
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(:
|
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)
|
data/lib/brakeman/file_parser.rb
CHANGED
@@ -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}")
|
data/lib/brakeman/options.rb
CHANGED
@@ -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"
|
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"
|
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"
|
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] =
|
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})"]
|
@@ -373,7 +373,7 @@ class Brakeman::AliasProcessor < Brakeman::SexpProcessor
|
|
373
373
|
result << join_item(array.last, nil)
|
374
374
|
|
375
375
|
# Combine the strings at the beginning because that's what RubyParser does
|
376
|
-
combined_first = ""
|
376
|
+
combined_first = +""
|
377
377
|
result.each do |e|
|
378
378
|
if string? e
|
379
379
|
combined_first << e.value
|
@@ -665,7 +665,7 @@ class Brakeman::AliasProcessor < Brakeman::SexpProcessor
|
|
665
665
|
exp[2] = exp[2][1]
|
666
666
|
end
|
667
667
|
|
668
|
-
unless array? exp[1] and array? exp[2]
|
668
|
+
unless array? exp[1] and array? exp[2]
|
669
669
|
return process_default(exp)
|
670
670
|
end
|
671
671
|
|
@@ -678,21 +678,42 @@ class Brakeman::AliasProcessor < Brakeman::SexpProcessor
|
|
678
678
|
# Call each assignment as if it is normal
|
679
679
|
vars.each_with_index do |var, i|
|
680
680
|
val = vals[i]
|
681
|
-
if
|
681
|
+
next unless val # TODO: Break if there are no vals left?
|
682
682
|
|
683
|
-
|
684
|
-
|
685
|
-
|
686
|
-
|
687
|
-
|
688
|
-
|
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)
|
689
689
|
|
690
|
-
|
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]
|
697
|
+
|
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
|
691
703
|
else
|
692
|
-
assign
|
693
|
-
|
694
|
-
|
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)
|
695
710
|
end
|
711
|
+
|
712
|
+
process assign
|
713
|
+
else
|
714
|
+
assign = var.dup
|
715
|
+
assign.rhs = val
|
716
|
+
process assign
|
696
717
|
end
|
697
718
|
end
|
698
719
|
|
@@ -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]
|
data/lib/brakeman/scanner.rb
CHANGED
@@ -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?
|
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
|
data/lib/brakeman/version.rb
CHANGED
data/lib/brakeman/warning.rb
CHANGED
@@ -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
|
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)
|
@@ -198,6 +199,7 @@ module Brakeman
|
|
198
199
|
:relative_path => false,
|
199
200
|
:report_progress => true,
|
200
201
|
:safe_methods => Set.new,
|
202
|
+
:show_ignored => false,
|
201
203
|
:sql_safe_methods => Set.new,
|
202
204
|
:skip_checks => Set.new,
|
203
205
|
:skip_vendor => true,
|
data/lib/ruby_parser/bm_sexp.rb
CHANGED
@@ -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!, :
|
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-lib
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 6.
|
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: 2024-
|
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,14 +128,14 @@ dependencies:
|
|
114
128
|
requirements:
|
115
129
|
- - "~>"
|
116
130
|
- !ruby/object:Gem::Version
|
117
|
-
version: 2.
|
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.
|
138
|
+
version: 2.5.1
|
125
139
|
- !ruby/object:Gem::Dependency
|
126
140
|
name: racc
|
127
141
|
requirement: !ruby/object:Gem::Requirement
|
@@ -199,9 +213,9 @@ dependencies:
|
|
199
213
|
- - ">="
|
200
214
|
- !ruby/object:Gem::Version
|
201
215
|
version: 1.3.6
|
202
|
-
- - "
|
216
|
+
- - "<"
|
203
217
|
- !ruby/object:Gem::Version
|
204
|
-
version: '
|
218
|
+
version: '5.3'
|
205
219
|
type: :runtime
|
206
220
|
prerelease: false
|
207
221
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -209,9 +223,9 @@ dependencies:
|
|
209
223
|
- - ">="
|
210
224
|
- !ruby/object:Gem::Version
|
211
225
|
version: 1.3.6
|
212
|
-
- - "
|
226
|
+
- - "<"
|
213
227
|
- !ruby/object:Gem::Version
|
214
|
-
version: '
|
228
|
+
version: '5.3'
|
215
229
|
- !ruby/object:Gem::Dependency
|
216
230
|
name: rexml
|
217
231
|
requirement: !ruby/object:Gem::Requirement
|
@@ -338,6 +352,7 @@ files:
|
|
338
352
|
- lib/brakeman/format/style.css
|
339
353
|
- lib/brakeman/messages.rb
|
340
354
|
- lib/brakeman/options.rb
|
355
|
+
- lib/brakeman/parsers/erubis_patch.rb
|
341
356
|
- lib/brakeman/parsers/haml_embedded.rb
|
342
357
|
- lib/brakeman/parsers/rails2_erubis.rb
|
343
358
|
- lib/brakeman/parsers/rails2_xss_plugin_erubis.rb
|
@@ -452,7 +467,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
452
467
|
- !ruby/object:Gem::Version
|
453
468
|
version: '0'
|
454
469
|
requirements: []
|
455
|
-
rubygems_version: 3.
|
470
|
+
rubygems_version: 3.3.27
|
456
471
|
signing_key:
|
457
472
|
specification_version: 4
|
458
473
|
summary: Security vulnerability scanner for Ruby on Rails.
|