brakeman 8.0.2 → 8.0.5
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 +21 -0
- data/bundle/load.rb +1 -1
- data/bundle/ruby/3.2.0/gems/parallel-1.28.0/lib/parallel/version.rb +4 -0
- data/bundle/ruby/3.2.0/gems/{parallel-1.27.0 → parallel-1.28.0}/lib/parallel.rb +11 -0
- data/lib/brakeman/checks/check_execute.rb +13 -4
- data/lib/brakeman/checks/check_sql.rb +4 -3
- data/lib/brakeman/commandline.rb +9 -4
- data/lib/brakeman/options.rb +6 -2
- data/lib/brakeman/processors/base_processor.rb +13 -6
- data/lib/brakeman/processors/gem_processor.rb +1 -1
- data/lib/brakeman/processors/haml_template_processor.rb +3 -1
- data/lib/brakeman/processors/lib/rails3_config_processor.rb +10 -1
- data/lib/brakeman/processors/lib/render_helper.rb +3 -1
- data/lib/brakeman/scanner.rb +8 -2
- data/lib/brakeman/version.rb +1 -1
- data/lib/brakeman.rb +27 -13
- metadata +6 -6
- data/bundle/ruby/3.2.0/gems/parallel-1.27.0/lib/parallel/version.rb +0 -4
- /data/bundle/ruby/3.2.0/gems/{parallel-1.27.0 → parallel-1.28.0}/MIT-LICENSE.txt +0 -0
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 90b39cd822319fe03d9a0b331239d2ed8fbcfe2db659761d3f0273b3a48e4116
|
|
4
|
+
data.tar.gz: aff94e8cefaa7e8d54aa8a5d7f9a3c0a9bb532ac758e8c3bd7acd2c30df5c6ee
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c2f00398efaf4e652a4ae1034facdaa28169a852ebef8464e5723fcd328dba1fb08d8e7b1c75d639f5d7127046eb1aa296d0f1a38d1e563180b59596aa3d5437
|
|
7
|
+
data.tar.gz: f8131d641b70c662017e6918f669825cc62c766325ac124dee4210dd2fd4a42bb892ef901d4f12dd7245043fb84539694f6de7badf996c19c0f7aa63e27a83c6
|
data/CHANGES.md
CHANGED
|
@@ -1,3 +1,24 @@
|
|
|
1
|
+
# 8.0.5 - 2026-06-12
|
|
2
|
+
|
|
3
|
+
* Add `quote_schema_name` to safe quote method list (Zsolt Kozaroczy)
|
|
4
|
+
* Fix SQL injection false positive for `compact_blank`/`compact` on permitted params (Arpit Jain)
|
|
5
|
+
* Fix inline render false positive for local named `text` (Arpit Jain)
|
|
6
|
+
* Fix HAML crash on `.raw` calls (Federico Franco)
|
|
7
|
+
* Fix Ruby version parsing - especially for non-CRuby versions (Chris Southerland Jr)
|
|
8
|
+
* Fix `TemplateAliasProcessor#template_name` arity (viralpraxis)
|
|
9
|
+
* Reduce false positives when using shell escaping
|
|
10
|
+
|
|
11
|
+
# 8.0.4 - 2026-02-26
|
|
12
|
+
|
|
13
|
+
* Load 'date' library for `--ensure-latest`
|
|
14
|
+
|
|
15
|
+
# 8.0.3 - 2026-02-26
|
|
16
|
+
|
|
17
|
+
* Fix `polymorphic_name` SQLi false positive (Fredrico Franco)
|
|
18
|
+
* Fix logger behavior when loading config files
|
|
19
|
+
* Handle application names with module prefixes
|
|
20
|
+
* Add release age option for `--ensure-latest`
|
|
21
|
+
|
|
1
22
|
# 8.0.2 - 2026-02-03
|
|
2
23
|
|
|
3
24
|
* Reline console control should use stderr
|
data/bundle/load.rb
CHANGED
|
@@ -3,7 +3,7 @@ $:.unshift "#{path}/bundle/ruby/3.2.0/gems/csv-3.3.5/lib"
|
|
|
3
3
|
$:.unshift "#{path}/bundle/ruby/3.2.0/gems/erubi-1.13.1/lib"
|
|
4
4
|
$:.unshift "#{path}/bundle/ruby/3.2.0/gems/haml-6.4.0/lib"
|
|
5
5
|
$:.unshift "#{path}/bundle/ruby/3.2.0/gems/highline-3.1.2/lib"
|
|
6
|
-
$:.unshift "#{path}/bundle/ruby/3.2.0/gems/parallel-1.
|
|
6
|
+
$:.unshift "#{path}/bundle/ruby/3.2.0/gems/parallel-1.28.0/lib"
|
|
7
7
|
$:.unshift "#{path}/bundle/ruby/3.2.0/gems/reline-0.6.3/lib"
|
|
8
8
|
$:.unshift "#{path}/bundle/ruby/3.2.0/gems/rexml-3.4.4/lib"
|
|
9
9
|
$:.unshift "#{path}/bundle/ruby/3.2.0/gems/ruby2ruby-2.5.2/lib"
|
|
@@ -15,6 +15,17 @@ module Parallel
|
|
|
15
15
|
super()
|
|
16
16
|
@value = value
|
|
17
17
|
end
|
|
18
|
+
|
|
19
|
+
# marshal_dump that is used for ruby exceptions
|
|
20
|
+
# avoid dumping the cause since nobody needs that and it can include undumpable exceptions
|
|
21
|
+
def _dump(_depth)
|
|
22
|
+
Marshal.dump(@value)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# marshal_load that is used for ruby exceptions
|
|
26
|
+
def self._load(data)
|
|
27
|
+
new(Marshal.load(data))
|
|
28
|
+
end
|
|
18
29
|
end
|
|
19
30
|
|
|
20
31
|
class Kill < Break
|
|
@@ -122,9 +122,14 @@ class Brakeman::CheckExecute < Brakeman::BaseCheck
|
|
|
122
122
|
# should be ignored
|
|
123
123
|
|
|
124
124
|
args.pop if hash?(args.last) && args.length > 2
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
125
|
+
|
|
126
|
+
args.each_sexp do |arg|
|
|
127
|
+
failure = include_user_input?(arg) ||
|
|
128
|
+
dangerous_interp?(arg) ||
|
|
129
|
+
dangerous_string_building?(arg)
|
|
130
|
+
|
|
131
|
+
break if failure
|
|
132
|
+
end
|
|
128
133
|
else
|
|
129
134
|
failure = include_user_input?(args) ||
|
|
130
135
|
dangerous_interp?(args) ||
|
|
@@ -176,6 +181,8 @@ class Brakeman::CheckExecute < Brakeman::BaseCheck
|
|
|
176
181
|
def include_user_input? exp
|
|
177
182
|
if node_type? exp, :arglist, :dstr, :evstr, :dxstr
|
|
178
183
|
exp.each_sexp do |e|
|
|
184
|
+
next if shell_escape? e
|
|
185
|
+
|
|
179
186
|
if res = include_user_input?(e)
|
|
180
187
|
return res
|
|
181
188
|
end
|
|
@@ -196,7 +203,7 @@ class Brakeman::CheckExecute < Brakeman::BaseCheck
|
|
|
196
203
|
# Check for input at start of string
|
|
197
204
|
exp[1] == "" and
|
|
198
205
|
node_type? exp[2], :evstr and
|
|
199
|
-
|
|
206
|
+
dangerous? exp[2]
|
|
200
207
|
else
|
|
201
208
|
has_immediate_user_input? exp
|
|
202
209
|
end
|
|
@@ -266,6 +273,8 @@ class Brakeman::CheckExecute < Brakeman::BaseCheck
|
|
|
266
273
|
end
|
|
267
274
|
|
|
268
275
|
def dangerous_interp? exp
|
|
276
|
+
return if shell_escape? exp
|
|
277
|
+
|
|
269
278
|
match = include_interp? exp
|
|
270
279
|
return unless match
|
|
271
280
|
interp = match.match
|
|
@@ -311,7 +311,7 @@ class Brakeman::CheckSQL < Brakeman::BaseCheck
|
|
|
311
311
|
end
|
|
312
312
|
|
|
313
313
|
if request_value? arg
|
|
314
|
-
unless call? arg and params? arg.target and [:permit, :slice, :to_h, :to_hash, :symbolize_keys].include? arg.method
|
|
314
|
+
unless call? arg and params? arg.target and [:permit, :slice, :to_h, :to_hash, :symbolize_keys, :compact, :compact_blank].include? arg.method
|
|
315
315
|
# Model.where(params[:where])
|
|
316
316
|
arg
|
|
317
317
|
end
|
|
@@ -600,7 +600,8 @@ class Brakeman::CheckSQL < Brakeman::BaseCheck
|
|
|
600
600
|
:sanitize_sql_for_assignment, :sanitize_sql_for_conditions, :sanitize_sql_hash,
|
|
601
601
|
:sanitize_sql_hash_for_assignment, :sanitize_sql_hash_for_conditions,
|
|
602
602
|
:to_sql, :sanitize, :primary_key, :table_name_prefix, :table_name_suffix,
|
|
603
|
-
:where_values_hash, :foreign_key, :uuid, :escape, :escape_string
|
|
603
|
+
:where_values_hash, :foreign_key, :uuid, :escape, :escape_string,
|
|
604
|
+
:polymorphic_name
|
|
604
605
|
]
|
|
605
606
|
|
|
606
607
|
def ignore_methods_in_sql
|
|
@@ -644,7 +645,7 @@ class Brakeman::CheckSQL < Brakeman::BaseCheck
|
|
|
644
645
|
locale_call? exp
|
|
645
646
|
end
|
|
646
647
|
|
|
647
|
-
QUOTE_METHODS = [:quote, :quote_column_name, :quoted_date, :quote_string, :quote_table_name]
|
|
648
|
+
QUOTE_METHODS = [:quote, :quote_column_name, :quoted_date, :quote_string, :quote_table_name, :quote_schema_name]
|
|
648
649
|
|
|
649
650
|
def quote_call? exp
|
|
650
651
|
if call? exp.target
|
data/lib/brakeman/commandline.rb
CHANGED
|
@@ -31,7 +31,7 @@ module Brakeman
|
|
|
31
31
|
set_interrupt_handler options
|
|
32
32
|
early_exit_options options
|
|
33
33
|
set_options options, default_app_path
|
|
34
|
-
check_latest if options[:ensure_latest]
|
|
34
|
+
check_latest(options[:ensure_latest]) if options[:ensure_latest]
|
|
35
35
|
run_report options
|
|
36
36
|
|
|
37
37
|
quit
|
|
@@ -39,9 +39,14 @@ module Brakeman
|
|
|
39
39
|
|
|
40
40
|
# Check for the latest version.
|
|
41
41
|
#
|
|
42
|
-
# If the latest version is newer
|
|
43
|
-
|
|
44
|
-
|
|
42
|
+
# If the latest version is newer than the current version
|
|
43
|
+
# and age, exit.
|
|
44
|
+
def check_latest(days_old = 0)
|
|
45
|
+
if days_old == true
|
|
46
|
+
days_old = 0
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
if error = Brakeman.ensure_latest(days_old:)
|
|
45
50
|
quit Brakeman::Not_Latest_Version_Exit_Code, error
|
|
46
51
|
end
|
|
47
52
|
end
|
data/lib/brakeman/options.rb
CHANGED
|
@@ -63,8 +63,12 @@ module Brakeman::Options
|
|
|
63
63
|
options[:exit_on_error] = exit_on_error
|
|
64
64
|
end
|
|
65
65
|
|
|
66
|
-
opts.on "--ensure-latest", "Fail when Brakeman is outdated" do
|
|
67
|
-
|
|
66
|
+
opts.on "--ensure-latest [DAYS]", Integer, "Fail when Brakeman is outdated. Optionally set minimum age in days." do |days|
|
|
67
|
+
if days and not (1..15).include? days
|
|
68
|
+
raise OptionParser::InvalidArgument
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
options[:ensure_latest] = days || true
|
|
68
72
|
end
|
|
69
73
|
|
|
70
74
|
opts.on "--ensure-ignore-notes", "Fail when an ignored warnings does not include a note" do
|
|
@@ -258,12 +258,19 @@ class Brakeman::BaseProcessor < Brakeman::SexpProcessor
|
|
|
258
258
|
#Look for "type" of render in options hash
|
|
259
259
|
#For example, render :file => "blah"
|
|
260
260
|
if hash? last_arg
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
261
|
+
if type
|
|
262
|
+
#The render type was already determined by a positional argument, so a
|
|
263
|
+
#key in the options hash that happens to match a render type name (e.g.
|
|
264
|
+
#`text:`) is a local passed to the partial/action, not a type directive.
|
|
265
|
+
rest = last_arg
|
|
266
|
+
else
|
|
267
|
+
hash_iterate(last_arg) do |key, val|
|
|
268
|
+
if symbol? key and types_in_hash.include? key.value
|
|
269
|
+
type = key.value
|
|
270
|
+
value = val
|
|
271
|
+
else
|
|
272
|
+
rest << key << val
|
|
273
|
+
end
|
|
267
274
|
end
|
|
268
275
|
end
|
|
269
276
|
end
|
|
@@ -6,7 +6,7 @@ class Brakeman::GemProcessor < Brakeman::BasicProcessor
|
|
|
6
6
|
def initialize *args
|
|
7
7
|
super
|
|
8
8
|
@gem_name_version = /^\s*([-_+.A-Za-z0-9]+) \((\w(\.\w+)*)\)/
|
|
9
|
-
@ruby_version = /^\s+ruby (\d
|
|
9
|
+
@ruby_version = /^\s+ruby (\d+\.\d+\.\d+)/
|
|
10
10
|
end
|
|
11
11
|
|
|
12
12
|
def process_gems gem_files
|
|
@@ -17,6 +17,7 @@ require 'brakeman/processors/lib/basic_processor'
|
|
|
17
17
|
#Values for tracker.config.rails will still be Sexps.
|
|
18
18
|
class Brakeman::Rails3ConfigProcessor < Brakeman::BasicProcessor
|
|
19
19
|
RAILS_CONFIG = Sexp.new(:call, nil, :config)
|
|
20
|
+
RAILS_APPLICATION = Sexp.new(:colon2, s(:const, :Rails), :Application)
|
|
20
21
|
|
|
21
22
|
def initialize *args
|
|
22
23
|
super
|
|
@@ -48,7 +49,7 @@ class Brakeman::Rails3ConfigProcessor < Brakeman::BasicProcessor
|
|
|
48
49
|
|
|
49
50
|
#Look for class Application < Rails::Application
|
|
50
51
|
def process_class exp
|
|
51
|
-
if exp
|
|
52
|
+
if application_class? exp
|
|
52
53
|
@inside_config = true
|
|
53
54
|
process_all exp.body if sexp? exp.body
|
|
54
55
|
@inside_config = false
|
|
@@ -57,6 +58,14 @@ class Brakeman::Rails3ConfigProcessor < Brakeman::BasicProcessor
|
|
|
57
58
|
exp
|
|
58
59
|
end
|
|
59
60
|
|
|
61
|
+
def application_class? exp
|
|
62
|
+
return unless node_type? exp, :class
|
|
63
|
+
|
|
64
|
+
exp.class_name == :Application or
|
|
65
|
+
(node_type? exp.class_name, :colon2 and exp.class_name.rhs == :Application) or
|
|
66
|
+
(exp.parent_name == RAILS_APPLICATION)
|
|
67
|
+
end
|
|
68
|
+
|
|
60
69
|
#Look for configuration settings that
|
|
61
70
|
#are just a call like
|
|
62
71
|
#
|
|
@@ -19,7 +19,9 @@ module Brakeman::RenderHelper
|
|
|
19
19
|
end
|
|
20
20
|
when :default
|
|
21
21
|
begin
|
|
22
|
-
|
|
22
|
+
# exp[2] is either the action name (from controller) or :default when no explicit arg
|
|
23
|
+
name_arg = (exp[2].nil? || exp[2] == :default) ? nil : exp[2]
|
|
24
|
+
process_template template_name(name_arg), exp[3], nil, exp.line
|
|
23
25
|
rescue ArgumentError
|
|
24
26
|
Brakeman.debug "Problem processing render: #{exp}"
|
|
25
27
|
end
|
data/lib/brakeman/scanner.rb
CHANGED
|
@@ -187,8 +187,14 @@ class Brakeman::Scanner
|
|
|
187
187
|
end
|
|
188
188
|
|
|
189
189
|
if @app_tree.exists? ".ruby-version"
|
|
190
|
-
|
|
191
|
-
|
|
190
|
+
contents = @app_tree.file_path(".ruby-version").read
|
|
191
|
+
# Skip alternative Ruby implementations — the EOL dates Brakeman knows
|
|
192
|
+
# about are MRI's, so a `.ruby-version` of "jruby-10.0.2.0" should not
|
|
193
|
+
# be parsed as MRI 0.0.2 / 10.0.2.
|
|
194
|
+
unless contents =~ /\A\s*(jruby|truffleruby|rbx|rubinius|mruby)\b/i
|
|
195
|
+
if version = contents[/(\d+\.\d+\.\d+)/]
|
|
196
|
+
tracker.config.set_ruby_version version, @app_tree.file_path(".ruby-version"), 1
|
|
197
|
+
end
|
|
192
198
|
end
|
|
193
199
|
end
|
|
194
200
|
|
data/lib/brakeman/version.rb
CHANGED
data/lib/brakeman.rb
CHANGED
|
@@ -167,7 +167,6 @@ module Brakeman
|
|
|
167
167
|
#Load options from YAML file
|
|
168
168
|
def self.load_options line_options
|
|
169
169
|
custom_location = line_options[:config_file]
|
|
170
|
-
quiet = line_options[:quiet]
|
|
171
170
|
app_path = line_options[:app_path]
|
|
172
171
|
|
|
173
172
|
#Load configuration file
|
|
@@ -175,29 +174,28 @@ module Brakeman
|
|
|
175
174
|
require 'yaml'
|
|
176
175
|
options = YAML.safe_load_file config, permitted_classes: [Symbol], symbolize_names: true
|
|
177
176
|
|
|
178
|
-
# Brakeman.logger is probably not set yet
|
|
179
|
-
logger = Brakeman::Logger.get_logger(options || line_options)
|
|
180
|
-
|
|
181
177
|
if options
|
|
182
178
|
options.each { |k, v| options[k] = Set.new v if v.is_a? Array }
|
|
183
179
|
|
|
184
180
|
# After parsing the yaml config file for options, convert any string keys into symbols.
|
|
185
181
|
options.keys.select {|k| k.is_a? String}.map {|k| k.to_sym }.each {|k| options[k] = options[k.to_s]; options.delete(k.to_s) }
|
|
186
182
|
|
|
183
|
+
# Brakeman.logger is probably not set yet
|
|
184
|
+
logger = Brakeman::Logger.get_logger(options.merge(line_options))
|
|
185
|
+
|
|
187
186
|
unless line_options[:allow_check_paths_in_config]
|
|
188
187
|
if options.include? :additional_checks_path
|
|
189
188
|
options.delete :additional_checks_path
|
|
190
189
|
|
|
191
|
-
logger.alert 'Ignoring additional check paths in config file. Use --allow-check-paths-in-config to allow'
|
|
190
|
+
logger.alert 'Ignoring additional check paths in config file. Use --allow-check-paths-in-config to allow'
|
|
192
191
|
end
|
|
193
192
|
end
|
|
194
193
|
|
|
195
|
-
|
|
196
|
-
# potentially remove these checks now that logger is used
|
|
197
|
-
logger.alert "Using configuration in #{config}" unless (options[:quiet] || quiet)
|
|
194
|
+
logger.alert "Using configuration in #{config}"
|
|
198
195
|
options
|
|
199
196
|
else
|
|
200
|
-
logger
|
|
197
|
+
logger = Brakeman::Logger.get_logger(line_options)
|
|
198
|
+
logger.alert "Empty configuration file: #{config}"
|
|
201
199
|
{}
|
|
202
200
|
end
|
|
203
201
|
else
|
|
@@ -416,11 +414,27 @@ module Brakeman
|
|
|
416
414
|
end
|
|
417
415
|
end
|
|
418
416
|
|
|
419
|
-
|
|
417
|
+
# Returns quit message unless the latest version
|
|
418
|
+
# of Brakeman matches the current version.
|
|
419
|
+
#
|
|
420
|
+
# Optionally checks that the latest version is at least
|
|
421
|
+
# the specified number of days old.
|
|
422
|
+
def self.ensure_latest(days_old: 0)
|
|
423
|
+
require 'date'
|
|
424
|
+
|
|
420
425
|
current = Brakeman::Version
|
|
421
|
-
latest = Gem.
|
|
422
|
-
|
|
423
|
-
|
|
426
|
+
latest = Gem.latest_spec_for('brakeman')
|
|
427
|
+
release_date = latest.date.to_date
|
|
428
|
+
latest_version = latest.version.to_s
|
|
429
|
+
|
|
430
|
+
if (Date.today - latest.date.to_date) >= days_old
|
|
431
|
+
if current != latest_version
|
|
432
|
+
return "Brakeman #{current} is not the latest version #{latest_version}"
|
|
433
|
+
else
|
|
434
|
+
false
|
|
435
|
+
end
|
|
436
|
+
else
|
|
437
|
+
false
|
|
424
438
|
end
|
|
425
439
|
end
|
|
426
440
|
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: brakeman
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 8.0.
|
|
4
|
+
version: 8.0.5
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Justin Collins
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-
|
|
11
|
+
date: 2026-06-12 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: racc
|
|
@@ -150,9 +150,9 @@ files:
|
|
|
150
150
|
- bundle/ruby/3.2.0/gems/highline-3.1.2/lib/highline/terminal/unix_stty.rb
|
|
151
151
|
- bundle/ruby/3.2.0/gems/highline-3.1.2/lib/highline/version.rb
|
|
152
152
|
- bundle/ruby/3.2.0/gems/highline-3.1.2/lib/highline/wrapper.rb
|
|
153
|
-
- bundle/ruby/3.2.0/gems/parallel-1.
|
|
154
|
-
- bundle/ruby/3.2.0/gems/parallel-1.
|
|
155
|
-
- bundle/ruby/3.2.0/gems/parallel-1.
|
|
153
|
+
- bundle/ruby/3.2.0/gems/parallel-1.28.0/MIT-LICENSE.txt
|
|
154
|
+
- bundle/ruby/3.2.0/gems/parallel-1.28.0/lib/parallel.rb
|
|
155
|
+
- bundle/ruby/3.2.0/gems/parallel-1.28.0/lib/parallel/version.rb
|
|
156
156
|
- bundle/ruby/3.2.0/gems/reline-0.6.3/BSDL
|
|
157
157
|
- bundle/ruby/3.2.0/gems/reline-0.6.3/COPYING
|
|
158
158
|
- bundle/ruby/3.2.0/gems/reline-0.6.3/README.md
|
|
@@ -700,7 +700,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
700
700
|
- !ruby/object:Gem::Version
|
|
701
701
|
version: '0'
|
|
702
702
|
requirements: []
|
|
703
|
-
rubygems_version: 3.4.
|
|
703
|
+
rubygems_version: 3.4.19
|
|
704
704
|
signing_key:
|
|
705
705
|
specification_version: 4
|
|
706
706
|
summary: Security vulnerability scanner for Ruby on Rails.
|
|
File without changes
|