brakeman-lib 6.0.0 → 6.1.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 +13 -0
- data/lib/brakeman/checks/check_ransack.rb +53 -0
- data/lib/brakeman/checks/check_sql.rb +1 -1
- data/lib/brakeman/options.rb +4 -0
- data/lib/brakeman/processors/alias_processor.rb +1 -2
- data/lib/brakeman/processors/lib/module_helper.rb +31 -1
- data/lib/brakeman/processors/library_processor.rb +6 -0
- data/lib/brakeman/scanner.rb +104 -42
- data/lib/brakeman/tracker/config.rb +14 -8
- data/lib/brakeman/tracker/controller.rb +14 -10
- data/lib/brakeman/tracker.rb +1 -1
- data/lib/brakeman/version.rb +1 -1
- data/lib/brakeman/warning_codes.rb +1 -0
- metadata +6 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 121dc05b33eccbae05d0ff68b37baec12e2e3fbbc7c575a7cfe3e5c36cfb557b
|
4
|
+
data.tar.gz: bb7c6fe91660f3f766a23fdf6a54398c4f417b8be05d6354bdbe3a36e7fe3761
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2d8e948cb8cf55ad27d4760e391c6b028a921b4c4b171aef41bcb9420f100a38792ea28816e653446aeceec950f94b6cbb367d089c90bc20ed574be4d7490293
|
7
|
+
data.tar.gz: ee6425b330db3397bd4c5a53e4c096b5affb39c91936408493f270277a6cce93f796809a11c8f407300e741f279b03aa5555c05306a73049982d01034ae28018
|
data/CHANGES.md
CHANGED
@@ -1,3 +1,16 @@
|
|
1
|
+
# 6.1.0 - 2023-12-04
|
2
|
+
|
3
|
+
* Add `--timing` to add timing duration for scan steps
|
4
|
+
* Fix keyword splats in filter arguments
|
5
|
+
* Add check for unfiltered search with Ransack
|
6
|
+
* Fix class method lookup in parent classes
|
7
|
+
* Handle `class << self`
|
8
|
+
* Add `PG::Connection.escape_string` as a SQL sanitization method (Joévin Soulenq)
|
9
|
+
|
10
|
+
# 6.0.1 - 2023-07-20
|
11
|
+
|
12
|
+
* Accept strings for `load_defaults` version
|
13
|
+
|
1
14
|
# 6.0.0 - 2023-05-24
|
2
15
|
|
3
16
|
* Add obsolete fingerprints to comparison report
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'brakeman/checks/base_check'
|
2
|
+
|
3
|
+
class Brakeman::CheckRansack < Brakeman::BaseCheck
|
4
|
+
Brakeman::Checks.add self
|
5
|
+
|
6
|
+
@description = "Checks for dangerous use of the Ransack library"
|
7
|
+
|
8
|
+
def run_check
|
9
|
+
return unless version_between? "0.0.0", "3.99", tracker.config.gem_version(:ransack)
|
10
|
+
check_ransack_calls
|
11
|
+
end
|
12
|
+
|
13
|
+
def check_ransack_calls
|
14
|
+
tracker.find_call(method: :ransack, nested: true).each do |result|
|
15
|
+
next unless original? result
|
16
|
+
|
17
|
+
call = result[:call]
|
18
|
+
arg = call.first_arg
|
19
|
+
|
20
|
+
# If an allow list is defined anywhere in the
|
21
|
+
# class or super classes, consider it safe
|
22
|
+
class_name = result[:chain].first
|
23
|
+
|
24
|
+
next if ransackable_allow_list?(class_name)
|
25
|
+
|
26
|
+
if input = has_immediate_user_input?(arg)
|
27
|
+
confidence = if tracker.find_class(class_name).nil?
|
28
|
+
confidence = :low
|
29
|
+
elsif result[:location][:file].relative.include? 'admin'
|
30
|
+
confidence = :medium
|
31
|
+
else
|
32
|
+
confidence = :high
|
33
|
+
end
|
34
|
+
|
35
|
+
message = msg('Unrestricted search using ', msg_code('ransack'), ' library called with ', msg_input(input), '. Limit search by defining ', msg_code('ransackable_attributes'), ' and ', msg_code('ransackable_associations'), ' methods in class or upgrade Ransack to version 4.0.0 or newer')
|
36
|
+
|
37
|
+
warn result: result,
|
38
|
+
warning_type: 'Missing Authorization',
|
39
|
+
warning_code: :ransack_search,
|
40
|
+
message: message,
|
41
|
+
user_input: input,
|
42
|
+
confidence: confidence,
|
43
|
+
cwe_id: [862],
|
44
|
+
link: 'https://positive.security/blog/ransack-data-exfiltration'
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def ransackable_allow_list? class_name
|
50
|
+
tracker.find_method(:ransackable_attributes, class_name, :class) and
|
51
|
+
tracker.find_method(:ransackable_associations, class_name, :class)
|
52
|
+
end
|
53
|
+
end
|
@@ -591,7 +591,7 @@ class Brakeman::CheckSQL < Brakeman::BaseCheck
|
|
591
591
|
:sanitize_sql_for_assignment, :sanitize_sql_for_conditions, :sanitize_sql_hash,
|
592
592
|
:sanitize_sql_hash_for_assignment, :sanitize_sql_hash_for_conditions,
|
593
593
|
:to_sql, :sanitize, :primary_key, :table_name_prefix, :table_name_suffix,
|
594
|
-
:where_values_hash, :foreign_key, :uuid
|
594
|
+
:where_values_hash, :foreign_key, :uuid, :escape, :escape_string
|
595
595
|
]
|
596
596
|
|
597
597
|
def ignore_methods_in_sql
|
data/lib/brakeman/options.rb
CHANGED
@@ -244,6 +244,10 @@ module Brakeman::Options
|
|
244
244
|
options[:debug] = true
|
245
245
|
end
|
246
246
|
|
247
|
+
opts.on "--timing", "Measure time for scan steps" do
|
248
|
+
options[:show_timing] = true
|
249
|
+
end
|
250
|
+
|
247
251
|
opts.on "-f",
|
248
252
|
"--format TYPE",
|
249
253
|
[:pdf, :text, :html, :csv, :tabs, :json, :markdown, :codeclimate, :cc, :plain, :table, :junit, :sarif, :sonar, :github],
|
@@ -84,6 +84,9 @@ module Brakeman::ModuleHelper
|
|
84
84
|
res.line(exp.line)
|
85
85
|
@current_method = nil
|
86
86
|
|
87
|
+
# TODO: if target is not self/nil, then
|
88
|
+
# the method should be added to `target`, not current class
|
89
|
+
|
87
90
|
if @current_class
|
88
91
|
@current_class.add_method @visibility, name, res, @current_file
|
89
92
|
elsif @current_module
|
@@ -96,7 +99,13 @@ module Brakeman::ModuleHelper
|
|
96
99
|
name = exp.method_name
|
97
100
|
|
98
101
|
@current_method = name
|
99
|
-
|
102
|
+
|
103
|
+
if @inside_sclass
|
104
|
+
res = Sexp.new :defs, s(:self), name, exp.formal_args, *process_all!(exp.body)
|
105
|
+
else
|
106
|
+
res = Sexp.new :defn, name, exp.formal_args, *process_all!(exp.body)
|
107
|
+
end
|
108
|
+
|
100
109
|
res.line(exp.line)
|
101
110
|
@current_method = nil
|
102
111
|
|
@@ -108,4 +117,25 @@ module Brakeman::ModuleHelper
|
|
108
117
|
|
109
118
|
res
|
110
119
|
end
|
120
|
+
|
121
|
+
# class << self
|
122
|
+
def process_sclass exp
|
123
|
+
@inside_sclass = true
|
124
|
+
|
125
|
+
process_all! exp
|
126
|
+
|
127
|
+
exp
|
128
|
+
ensure
|
129
|
+
@inside_sclass = false
|
130
|
+
end
|
131
|
+
|
132
|
+
def make_defs exp
|
133
|
+
# 'What if' there was some crazy code that had a
|
134
|
+
# defs inside a def inside an sclass? :|
|
135
|
+
return exp if node_type? exp, :defs
|
136
|
+
|
137
|
+
raise "Unexpected node type: #{exp.node_type}" unless node_type? exp, :defn
|
138
|
+
|
139
|
+
Sexp.new(:defs, s(:self), exp.method_name, exp.formal_args, *exp.body).line(exp.line)
|
140
|
+
end
|
111
141
|
end
|
@@ -30,6 +30,12 @@ class Brakeman::LibraryProcessor < Brakeman::BaseProcessor
|
|
30
30
|
end
|
31
31
|
|
32
32
|
def process_defn exp
|
33
|
+
# TODO: Why is this different from ModuleHelper?
|
34
|
+
|
35
|
+
if @inside_sclass
|
36
|
+
exp = make_defs(exp)
|
37
|
+
end
|
38
|
+
|
33
39
|
if exp.method_name == :initialize
|
34
40
|
@alias_processor.process_safely exp.body_list
|
35
41
|
@initializer_env = @alias_processor.only_ivars
|
data/lib/brakeman/scanner.rb
CHANGED
@@ -30,6 +30,7 @@ class Brakeman::Scanner
|
|
30
30
|
end
|
31
31
|
|
32
32
|
@processor = processor || Brakeman::Processor.new(@app_tree, options)
|
33
|
+
@show_timing = tracker.options[:debug] || tracker.options[:show_timing]
|
33
34
|
end
|
34
35
|
|
35
36
|
#Returns the Tracker generated from the scan
|
@@ -37,35 +38,89 @@ class Brakeman::Scanner
|
|
37
38
|
@processor.tracked_events
|
38
39
|
end
|
39
40
|
|
41
|
+
def process_step description
|
42
|
+
Brakeman.notify "#{description}...".ljust(40)
|
43
|
+
|
44
|
+
if @show_timing
|
45
|
+
start_t = Time.now
|
46
|
+
yield
|
47
|
+
duration = Time.now - start_t
|
48
|
+
|
49
|
+
Brakeman.notify "(#{description}) Duration: #{duration} seconds"
|
50
|
+
else
|
51
|
+
yield
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def process_step_file description
|
56
|
+
if @show_timing
|
57
|
+
Brakeman.notify "Processing #{description}"
|
58
|
+
|
59
|
+
start_t = Time.now
|
60
|
+
yield
|
61
|
+
duration = Time.now - start_t
|
62
|
+
|
63
|
+
Brakeman.notify "(#{description}) Duration: #{duration} seconds"
|
64
|
+
else
|
65
|
+
yield
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
40
69
|
#Process everything in the Rails application
|
41
70
|
def process
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
71
|
+
process_step 'Processing gems' do
|
72
|
+
process_gems
|
73
|
+
end
|
74
|
+
|
75
|
+
process_step 'Processing configuration' do
|
76
|
+
guess_rails_version
|
77
|
+
process_config
|
78
|
+
end
|
79
|
+
|
80
|
+
process_step 'Parsing files' do
|
81
|
+
parse_files
|
82
|
+
end
|
83
|
+
|
84
|
+
process_step 'Detecting file types' do
|
85
|
+
detect_file_types
|
86
|
+
end
|
87
|
+
|
88
|
+
process_step 'Processing initializers' do
|
89
|
+
process_initializers
|
90
|
+
end
|
91
|
+
|
92
|
+
process_step 'Processing libs' do
|
93
|
+
process_libs
|
94
|
+
end
|
95
|
+
|
96
|
+
process_step 'Processing routes' do
|
97
|
+
process_routes
|
98
|
+
end
|
99
|
+
|
100
|
+
process_step 'Processing templates' do
|
101
|
+
process_templates
|
102
|
+
end
|
103
|
+
|
104
|
+
process_step 'Processing data flow in templates' do
|
105
|
+
process_template_data_flows
|
106
|
+
end
|
107
|
+
|
108
|
+
process_step 'Processing models' do
|
109
|
+
process_models
|
110
|
+
end
|
111
|
+
|
112
|
+
process_step 'Processing controllers' do
|
113
|
+
process_controllers
|
114
|
+
end
|
115
|
+
|
116
|
+
process_step 'Processing data flow in controllers' do
|
117
|
+
process_controller_data_flows
|
118
|
+
end
|
119
|
+
|
120
|
+
process_step 'Indexing call sites' do
|
121
|
+
index_call_sites
|
122
|
+
end
|
123
|
+
|
69
124
|
tracker
|
70
125
|
end
|
71
126
|
|
@@ -214,8 +269,9 @@ class Brakeman::Scanner
|
|
214
269
|
#Adds parsed information to tracker.initializers
|
215
270
|
def process_initializers
|
216
271
|
track_progress @file_list[:initializers] do |init|
|
217
|
-
|
218
|
-
|
272
|
+
process_step_file init[:path] do
|
273
|
+
process_initializer init
|
274
|
+
end
|
219
275
|
end
|
220
276
|
end
|
221
277
|
|
@@ -234,8 +290,9 @@ class Brakeman::Scanner
|
|
234
290
|
end
|
235
291
|
|
236
292
|
track_progress @file_list[:libs] do |lib|
|
237
|
-
|
238
|
-
|
293
|
+
process_step_file lib.path do
|
294
|
+
process_lib lib
|
295
|
+
end
|
239
296
|
end
|
240
297
|
end
|
241
298
|
|
@@ -266,8 +323,9 @@ class Brakeman::Scanner
|
|
266
323
|
#Adds processed controllers to tracker.controllers
|
267
324
|
def process_controllers
|
268
325
|
track_progress @file_list[:controllers] do |controller|
|
269
|
-
|
270
|
-
|
326
|
+
process_step_file controller.path do
|
327
|
+
process_controller controller
|
328
|
+
end
|
271
329
|
end
|
272
330
|
end
|
273
331
|
|
@@ -275,9 +333,10 @@ class Brakeman::Scanner
|
|
275
333
|
controllers = tracker.controllers.sort_by { |name, _| name.to_s }
|
276
334
|
|
277
335
|
track_progress controllers, "controllers" do |name, controller|
|
278
|
-
|
279
|
-
|
280
|
-
|
336
|
+
process_step_file name do
|
337
|
+
controller.src.each do |file, src|
|
338
|
+
@processor.process_controller_alias name, src, nil, file
|
339
|
+
end
|
281
340
|
end
|
282
341
|
end
|
283
342
|
|
@@ -300,8 +359,9 @@ class Brakeman::Scanner
|
|
300
359
|
templates = @file_list[:templates].sort_by { |t| t[:path] }
|
301
360
|
|
302
361
|
track_progress templates, "templates" do |template|
|
303
|
-
|
304
|
-
|
362
|
+
process_step_file template[:path] do
|
363
|
+
process_template template
|
364
|
+
end
|
305
365
|
end
|
306
366
|
end
|
307
367
|
|
@@ -313,8 +373,9 @@ class Brakeman::Scanner
|
|
313
373
|
templates = tracker.templates.sort_by { |name, _| name.to_s }
|
314
374
|
|
315
375
|
track_progress templates, "templates" do |name, template|
|
316
|
-
|
317
|
-
|
376
|
+
process_step_file name do
|
377
|
+
@processor.process_template_alias template
|
378
|
+
end
|
318
379
|
end
|
319
380
|
end
|
320
381
|
|
@@ -323,8 +384,9 @@ class Brakeman::Scanner
|
|
323
384
|
#Adds the processed models to tracker.models
|
324
385
|
def process_models
|
325
386
|
track_progress @file_list[:models] do |model|
|
326
|
-
|
327
|
-
|
387
|
+
process_step_file model[:path] do
|
388
|
+
process_model model[:path], model[:ast]
|
389
|
+
end
|
328
390
|
end
|
329
391
|
end
|
330
392
|
|
@@ -189,13 +189,19 @@ module Brakeman
|
|
189
189
|
# Load defaults based on config.load_defaults value
|
190
190
|
# as documented here: https://guides.rubyonrails.org/configuring.html#results-of-config-load-defaults
|
191
191
|
def load_rails_defaults
|
192
|
-
return unless
|
192
|
+
return unless node_type? tracker.config.rails[:load_defaults], :lit, :str
|
193
|
+
|
194
|
+
version = tracker.config.rails[:load_defaults].value.to_s
|
195
|
+
|
196
|
+
unless version.match? /^\d+\.\d+$/
|
197
|
+
Brakeman.debug "[Notice] Unknown version: #{tracker.config.rails[:load_defaults]}"
|
198
|
+
return
|
199
|
+
end
|
193
200
|
|
194
|
-
version = tracker.config.rails[:load_defaults].value
|
195
201
|
true_value = Sexp.new(:true)
|
196
202
|
false_value = Sexp.new(:false)
|
197
203
|
|
198
|
-
if version >= 5.0
|
204
|
+
if version >= '5.0'
|
199
205
|
set_rails_config(value: true_value, path: [:action_controller, :per_form_csrf_tokens])
|
200
206
|
set_rails_config(value: true_value, path: [:action_controller, :forgery_protection_origin_check])
|
201
207
|
set_rails_config(value: true_value, path: [:active_record, :belongs_to_required_by_default])
|
@@ -203,12 +209,12 @@ module Brakeman
|
|
203
209
|
set_rails_config(value: true_value, path: [:ssl_options, :hsts, :subdomains])
|
204
210
|
end
|
205
211
|
|
206
|
-
if version >= 5.1
|
212
|
+
if version >= '5.1'
|
207
213
|
set_rails_config(value: false_value, path: [:assets, :unknown_asset_fallback])
|
208
214
|
set_rails_config(value: true_value, path: [:action_view, :form_with_generates_remote_forms])
|
209
215
|
end
|
210
216
|
|
211
|
-
if version >= 5.2
|
217
|
+
if version >= '5.2'
|
212
218
|
set_rails_config(value: true_value, path: [:active_record, :cache_versioning])
|
213
219
|
set_rails_config(value: true_value, path: [:action_dispatch, :use_authenticated_cookie_encryption])
|
214
220
|
set_rails_config(value: true_value, path: [:active_support, :use_authenticated_message_encryption])
|
@@ -217,7 +223,7 @@ module Brakeman
|
|
217
223
|
set_rails_config(value: true_value, path: [:action_view, :form_with_generates_ids])
|
218
224
|
end
|
219
225
|
|
220
|
-
if version >= 6.0
|
226
|
+
if version >= '6.0'
|
221
227
|
set_rails_config(value: Sexp.new(:lit, :zeitwerk), path: [:autoloader])
|
222
228
|
set_rails_config(value: false_value, path: [:action_view, :default_enforce_utf8])
|
223
229
|
set_rails_config(value: true_value, path: [:action_dispatch, :use_cookies_with_metadata])
|
@@ -230,7 +236,7 @@ module Brakeman
|
|
230
236
|
set_rails_config(value: true_value, path: [:active_record, :collection_cache_versioning])
|
231
237
|
end
|
232
238
|
|
233
|
-
if version >= 6.1
|
239
|
+
if version >= '6.1'
|
234
240
|
set_rails_config(value: true_value, path: [:action_controller, :urlsafe_csrf_tokens])
|
235
241
|
set_rails_config(value: Sexp.new(:lit, :lax), path: [:action_dispatch, :cookies_same_site_protection])
|
236
242
|
set_rails_config(value: Sexp.new(:lit, 308), path: [:action_dispatch, :ssl_default_redirect_status])
|
@@ -242,7 +248,7 @@ module Brakeman
|
|
242
248
|
set_rails_config(value: true_value, path: [:active_storage, :track_variants])
|
243
249
|
end
|
244
250
|
|
245
|
-
if version >= 7.0
|
251
|
+
if version >= '7.0'
|
246
252
|
video_args =
|
247
253
|
Sexp.new(:str, "-vf 'select=eq(n\\,0)+eq(key\\,1)+gt(scene\\,0.015),loop=loop=-1:size=2,trim=start_frame=1' -frames:v 1 -f image2")
|
248
254
|
hash_class = s(:colon2, s(:colon2, s(:const, :OpenSSL), :Digest), :SHA256)
|
@@ -120,16 +120,20 @@ module Brakeman
|
|
120
120
|
filter[:methods] << a[1] if a.node_type == :lit
|
121
121
|
end
|
122
122
|
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
123
|
+
options = args.last
|
124
|
+
|
125
|
+
if hash? options
|
126
|
+
# Probably only one option,
|
127
|
+
# but this also avoids issues with kwsplats
|
128
|
+
hash_iterate(options) do |option, value|
|
129
|
+
case value.node_type
|
130
|
+
when :array
|
131
|
+
filter[option.value] = value.sexp_body.map {|v| v[1] }
|
132
|
+
when :lit, :str
|
133
|
+
filter[option.value] = value[1]
|
134
|
+
else
|
135
|
+
Brakeman.debug "[Notice] Unknown before_filter value: #{option} => #{value}"
|
136
|
+
end
|
133
137
|
end
|
134
138
|
else
|
135
139
|
filter[:all] = true
|
data/lib/brakeman/tracker.rb
CHANGED
@@ -245,7 +245,7 @@ class Brakeman::Tracker
|
|
245
245
|
end
|
246
246
|
|
247
247
|
# Not in any included modules, check the parent
|
248
|
-
@method_cache[cache_key] = find_method(method_name, klass.parent)
|
248
|
+
@method_cache[cache_key] = find_method(method_name, klass.parent, method_type)
|
249
249
|
end
|
250
250
|
end
|
251
251
|
|
data/lib/brakeman/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: brakeman-lib
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 6.
|
4
|
+
version: 6.1.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-05
|
11
|
+
date: 2023-12-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: minitest
|
@@ -86,14 +86,14 @@ dependencies:
|
|
86
86
|
requirements:
|
87
87
|
- - "~>"
|
88
88
|
- !ruby/object:Gem::Version
|
89
|
-
version:
|
89
|
+
version: 3.20.2
|
90
90
|
type: :runtime
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
94
|
- - "~>"
|
95
95
|
- !ruby/object:Gem::Version
|
96
|
-
version:
|
96
|
+
version: 3.20.2
|
97
97
|
- !ruby/object:Gem::Dependency
|
98
98
|
name: sexp_processor
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
@@ -288,6 +288,7 @@ files:
|
|
288
288
|
- lib/brakeman/checks/check_pathname.rb
|
289
289
|
- lib/brakeman/checks/check_permit_attributes.rb
|
290
290
|
- lib/brakeman/checks/check_quote_table_name.rb
|
291
|
+
- lib/brakeman/checks/check_ransack.rb
|
291
292
|
- lib/brakeman/checks/check_redirect.rb
|
292
293
|
- lib/brakeman/checks/check_regex_dos.rb
|
293
294
|
- lib/brakeman/checks/check_render.rb
|
@@ -451,7 +452,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
451
452
|
- !ruby/object:Gem::Version
|
452
453
|
version: '0'
|
453
454
|
requirements: []
|
454
|
-
rubygems_version: 3.
|
455
|
+
rubygems_version: 3.3.3
|
455
456
|
signing_key:
|
456
457
|
specification_version: 4
|
457
458
|
summary: Security vulnerability scanner for Ruby on Rails.
|