@@ -266,6 +266,12 @@ def self.[](config)
266
266
# CopyUIDData for +COPYUID+ response codes, and UIDPlusData or
267
267
# AppendUIDData for +APPENDUID+ response codes.
268
268
#
269
+ # UIDPlusData stores its data in arrays of numbers, which is vulnerable to
270
+ # a memory exhaustion denial of service attack from an untrusted or
271
+ # compromised server. Set this option to +false+ to completely block this
272
+ # vulnerability. Otherwise, parser_max_deprecated_uidplus_data_size
273
+ # mitigates this vulnerability.
274
+ #
269
275
# AppendUIDData and CopyUIDData are _mostly_ backward-compatible with
270
276
# UIDPlusData. Most applications should be able to upgrade with little
271
277
# or no changes.
@@ -288,6 +294,30 @@ def self.[](config)
288
294
true , false
289
295
]
290
296
297
+ # The maximum +uid-set+ size that ResponseParser will parse into
298
+ # deprecated UIDPlusData. This limit only applies when
299
+ # parser_use_deprecated_uidplus_data is not +false+.
300
+ #
301
+ # <em>(Parser support for +UIDPLUS+ added in +v0.3.2+.)</em>
302
+ #
303
+ # <em>Support for limiting UIDPlusData to a maximum size was added in
304
+ # +v0.3.8+, +v0.4.19+, and +v0.5.6+.</em>
305
+ #
306
+ # <em>UIDPlusData will be removed in +v0.6+.</em>
307
+ #
308
+ # ==== Versioned Defaults
309
+ #
310
+ # Because this limit guards against a remote server causing catastrophic
311
+ # memory exhaustion, the versioned default (used by #load_defaults) also
312
+ # applies to versions without the feature.
313
+ #
314
+ # * +0.3+ and prior: <tt>10,000</tt>
315
+ # * +0.4+: <tt>1,000</tt>
316
+ # * +0.5+: <tt>100</tt>
317
+ # * +0.6+: <tt>0</tt>
318
+ #
319
+ attr_accessor :parser_max_deprecated_uidplus_data_size , type : Integer
320
+
291
321
# Creates a new config object and initialize its attribute with +attrs+.
292
322
#
293
323
# If +parent+ is not given, the global config is used by default.
@@ -368,6 +398,7 @@ def defaults_hash
368
398
sasl_ir : true ,
369
399
responses_without_block : :silence_deprecation_warning ,
370
400
parser_use_deprecated_uidplus_data : true ,
401
+ parser_max_deprecated_uidplus_data_size : 1000 ,
371
402
) . freeze
372
403
373
404
@global = default . new
@@ -377,6 +408,7 @@ def defaults_hash
377
408
version_defaults [ 0 ] = Config [ 0.4 ] . dup . update (
378
409
sasl_ir : false ,
379
410
parser_use_deprecated_uidplus_data : true ,
411
+ parser_max_deprecated_uidplus_data_size : 10_000 ,
380
412
) . freeze
381
413
version_defaults [ 0.0 ] = Config [ 0 ]
382
414
version_defaults [ 0.1 ] = Config [ 0 ]
@@ -385,6 +417,7 @@ def defaults_hash
385
417
386
418
version_defaults [ 0.5 ] = Config [ 0.4 ] . dup . update (
387
419
responses_without_block : :warn ,
420
+ parser_max_deprecated_uidplus_data_size : 100 ,
388
421
) . freeze
389
422
390
423
version_defaults [ :default ] = Config [ 0.4 ]
@@ -394,6 +427,7 @@ def defaults_hash
394
427
version_defaults [ 0.6 ] = Config [ 0.5 ] . dup . update (
395
428
responses_without_block : :frozen_dup ,
396
429
parser_use_deprecated_uidplus_data : false ,
430
+ parser_max_deprecated_uidplus_data_size : 0 ,
397
431
) . freeze
398
432
version_defaults [ :future ] = Config [ 0.6 ]
399
433
0 commit comments