Skip to content

Releases: ruby/net-imap

v0.5.6

08 Feb 00:11
v0.5.6
Compare
Choose a tag to compare

What's Changed

🔒 Security Fix

Fixes CVE-2025-25186 (GHSA-7fc5-f82f-cx69): A malicious server can exhaust client memory by sending APPENDUID or COPYUID responses with very large uid-set ranges. Net::IMAP::UIDPlusData expands these ranges into arrays of integers.

Fix with minor API changes

Set config.parser_use_deprecated_uidplus_data to false to replace UIDPlusData with AppendUIDData and CopyUIDData. These classes store their UIDs as Net::IMAP::SequenceSet objects (not expanded into arrays of integers). Code that does not handle APPENDUID or COPYUID responses should not see any difference. Code that does handle these responses may need to be updated.

For v0.3.8, this option is not available
For v0.4.19, the default value is true.
For v0.5.6, the default value is :up_to_max_size.
For v0.6.0, the only allowed value will be false (UIDPlusData will be removed from v0.6).

Mitigate with backward compatible API

Adjust config.parser_max_deprecated_uidplus_data_size to limit the maximum UIDPlusData UID set size.
When config.parser_use_deprecated_uidplus_data == true, larger sets will crash.
When config.parser_use_deprecated_uidplus_data == :up_to_max_size, larger sets will use AppendUIDData or CopyUIDData.

For v0.3,8, this limit is hard-coded to 10,000.
For v0.4.19, this limit defaults to 1000.
For v0.5.6, this limit defaults to 100.
For v0.6.0, the only allowed value will be 0 (UIDPlusData will be removed from v0.6).

Please Note: unhandled responses

If the client does not add response handlers to prune unhandled responses, a malicious server can still eventually exhaust all client memory, by repeatedly sending malicious responses. However, net-imap has always retained unhandled responses, and it has always been necessary for long-lived connections to prune these responses. This is not significantly different from connecting to a trusted server with a long-lived connection. To limit the maximum number of retained responses, a simple handler might look something like the following:

limit = 1000
imap.add_response_handler do |resp|
  next unless resp.respond_to?(:name) && resp.respond_to?(:data)
  name = resp.name
  code = resp.data.code&.name if resp.data.is_a?(Net::IMAP::ResponseText)
  imap.responses(name) { _1.slice!(0...-limit) }
  imap.responses(code) { _1.slice!(0...-limit) }
end

Added

  • 🔧 Ensure ResponseParser config is mutable and non-global by @nevans in #381
  • ✨ Add SequenceSet methods for querying about duplicates by @nevans in #384
  • ✨ Add SequenceSet#each_ordered_number by @nevans in #386
  • ✨ Add SequenceSet#find_ordered_index by @nevans in #396
  • ✨ Add SequenceSet#ordered_at by @nevans in #397
  • ✨ Add AppendUIDData and CopyUIDData classes by @nevans in #400
  • 🔧 Add parser config for APPENDUID/COPYUID, 🗑️ Deprecate UIDPlusData by @nevans in #401

Fixed

  • 🐛 Fix SequenceSet#append when its @string is nil by @nevans in #376
  • 🐛 Fix SequenceSet merging in another SequenceSet by @nevans in #377
  • 🐛 Fix SequenceSet count dups with multiple "*" by @nevans in #387
  • 🥅 Re-raise #starttls error from receiver thread by @nevans in #395

Documentation

  • 📚 Fix SequenceSet#cover? documentation by @nevans in #379
  • 📚 Document COPYUID in tagged vs untagged responses by @nevans in #398

Other Changes

  • 🚚 Move UIDPlusData to its own file by @nevans in #391
  • ♻️ Parse uid-set as sequence-set without * by @nevans in #393

Miscellaneous

  • ⬆️ Bump step-security/harden-runner from 2.10.2 to 2.10.3 by @dependabot in #375
  • ⬆️ Bump step-security/harden-runner from 2.10.3 to 2.10.4 by @dependabot in #380
  • ✅ Improve test coverage for SequenceSet enums by @nevans in #383
  • ♻️✅ Refactor SequenceSet enumerator tests by @nevans in #385
  • ➕ Add "irb" to Gemfile to silence warning by @nevans in #388
  • Omit flaky test with macOS platform by @hsbt in #389
  • ✅ Improve UIDPlusData test coverage by @nevans in #392
  • 🚚 Rename UIDPLUS test file for consistency by @nevans in #399

Full Changelog: v0.5.5...v0.5.6

v0.4.19

08 Feb 00:14
v0.4.19
Compare
Choose a tag to compare

What's Changed

🔒 Security Fix

Fixes CVE-2025-25186 (GHSA-7fc5-f82f-cx69): A malicious server can exhaust client memory by sending APPENDUID or COPYUID responses with very large uid-set ranges. Net::IMAP::UIDPlusData expands these ranges into arrays of integers.

Fix with minor API changes

Set config.parser_use_deprecated_uidplus_data to false to replace UIDPlusData with AppendUIDData and CopyUIDData. These classes store their UIDs as Net::IMAP::SequenceSet objects (not expanded into arrays of integers). Code that does not handle APPENDUID or COPYUID responses should not see any difference. Code that does handle these responses may need to be updated.

For v0.3.8, this option is not available
For v0.4.19, the default value is true.
For v0.5.6, the default value is :up_to_max_size.
For v0.6.0, the only allowed value will be false (UIDPlusData will be removed from v0.6).

Mitigate with backward compatible API

Adjust config.parser_max_deprecated_uidplus_data_size to limit the maximum UIDPlusData UID set size.
When config.parser_use_deprecated_uidplus_data == true, larger sets will crash.
When config.parser_use_deprecated_uidplus_data == :up_to_max_size, larger sets will use AppendUIDData or CopyUIDData.

For v0.3,8, this limit is hard-coded to 10,000.
For v0.4.19, this limit defaults to 1000.
For v0.5.6, this limit defaults to 100.
For v0.6.0, the only allowed value will be 0 (UIDPlusData will be removed from v0.6).

Please Note: unhandled responses

If the client does not add response handlers to prune unhandled responses, a malicious server can still eventually exhaust all client memory, by repeatedly sending malicious responses. However, net-imap has always retained unhandled responses, and it has always been necessary for long-lived connections to prune these responses. This is not significantly different from connecting to a trusted server with a long-lived connection. To limit the maximum number of retained responses, a simple handler might look something like the following:

limit = 1000
imap.add_response_handler do |resp|
  next unless resp.respond_to?(:name) && resp.respond_to?(:data)
  name = resp.name
  code = resp.data.code&.name if resp.data.in?(Net::IMAP::ResponseText)
  imap.responses(name) { _1.slice!(0...-limit) }
  imap.responses(code) { _1.slice!(0...-limit) }
end

Added

  • 🔧 ResponseParser config is mutable and non-global (backports #381) by @nevans in #382
  • ✨ SequenceSet ordered entries methods (backports to v0.4-stable) by @nevans in #402
    Backports the following:
    • ✨ Add SequenceSet methods for querying about duplicates by @nevans in #384
    • ✨ Add SequenceSet#each_ordered_number by @nevans in #386
    • ✨ Add SequenceSet#find_ordered_index by @nevans in #396
    • ✨ Add SequenceSet#ordered_at by @nevans in #397
  • ✨ Backport UIDPlusData, AppendUIDData, CopyUIDData to v0.4 by @nevans in #404
    Backports the following:
    • ✨ Add AppendUIDData and CopyUIDData classes by @nevans in #400
    • 🔧 Add parser config for APPENDUID/COPYUID, 🗑️ Deprecate UIDPlusData by @nevans in #401

Fixed

  • 🐛 Backport SequenceSet bugfixes (#376, #377) to v0.4 by @nevans in #378
    Backports the following:
    • 🐛 Fix SequenceSet#append when its @string is nil by @nevans in #376
    • 🐛 Fix SequenceSet merging in another SequenceSet by @nevans in #377
  • 🥅 Re-raise #starttls error from receiver thread (backport #395 to v0.4) by @nevans in #403

Other Changes

Full Changelog: v0.4.18...v0.4.19

v0.3.8

08 Feb 00:21
v0.3.8
Compare
Choose a tag to compare

What's Changed

🔒 Security Fix

Mitigates CVE-2025-25186 (GHSA-7fc5-f82f-cx69): A malicious server can exhaust client memory by sending APPENDUID or COPYUID responses with very large uid-set ranges. Net::IMAP::UIDPlusData expands these ranges into arrays of integers.

Fix with minor API changes

For v0.3.8, this option is not available. Upgrade to v0.4.19, v0.5.6, or higher to replace UIDPlusData with AppendUIDData and CopyUIDData. These classes store their UIDs as Net::IMAP::SequenceSet objects (not expanded into arrays of integers).

Mitigate with backward compatible API

This release mitigates the attack by crashing if a server tries to send a uid-set that represents more than 10,000 numbers. This should be larger than almost all legitimate COPYUID or APPENDUID responses and would limit the array to only 80KB (on a 64 bit system).

For v0.3.8, this option is not configurable. Upgrade to v0.4.19, v0.5.6, or higher to configure this limit.

Please Note: unhandled responses

If the client does not add response handlers to prune unhandled responses, a malicious server can still eventually exhaust all client memory, by repeatedly sending malicious responses. However, net-imap has always retained unhandled responses, and it has always been necessary for long-lived connections to prune these responses. This is not significantly different from connecting to a trusted server with a long-lived connection. To limit the maximum number of retained responses, a simple handler might look something like the following:

limit = 1000
imap.add_response_handler do |resp|
  name = resp.name
  code = resp.data.code&.name if resp.data.in?(Net::IMAP::ResponseText)
  # before 0.4.0:
  imap.responses[name].slice!(0...-limit)
  imap.responses[code].slice!(0...-limit)
  # since 0.4.0:
  imap.responses(name) { _1.slice!(0...-limit) }
  imap.responses(code) { _1.slice!(0...-limit) }
end

Miscellaneous

  • ✅ Renew test certificates for CI by @sorah in #259

Full Changelog: v0.3.7...v0.3.8

v0.5.5

04 Jan 05:22
v0.5.5
Compare
Choose a tag to compare

What's Changed

Breaking Changes

  • 🐛💥 Remove accidental Data#attributes method by @nevans in #371
    For ruby 3.2 and above, this PR is not a breaking change, and it fixes a YAML serialization bug.
    Net::IMAP::Data#attributes was only available in ruby 3.1, with net-imap v0.5.2 - v0.5.4. It can be replaced by #to_h.

Added

Documentation

New Contributors

  • @avdi made their first contribution in #366

Full Changelog: v0.5.4...v0.5.5

v0.5.4

23 Dec 00:20
v0.5.4
Compare
Choose a tag to compare

What's Changed

Added

  • ✨ Add support for PARTIAL extension (RFC9394) by @nevans in #367

Fixed

  • 🐛 Fix partial-range encoding of exclusive ranges by @nevans in #370

Documentation

Full Changelog: v0.5.3...v0.5.4

v0.5.3

22 Dec 23:48
v0.5.3
Compare
Choose a tag to compare

What's Changed

Added

  • ✨ Add support for VANISHED responses by @nevans in #329

Documentation

Full Changelog: v0.5.2...v0.5.3

v0.5.2

16 Dec 15:36
v0.5.2
Compare
Choose a tag to compare

What's Changed

Added

  • 🥅 Raise ArgumentError on multiple search charset args by @nevans in #363
  • ✨ Add keyword argument for search charset by @nevans in #364
  • ✨ Add basic ESEARCH support (RFC4466, RFC4731) by @nevans in #333

Fixed

  • 🐛 Return empty SearchResult for no search result by @nevans in #362

Documentation

  • 📚 Fix README example by @nevans in #354
  • 📦📚 Add release.yml for better release note generation by @nevans in #355
  • 📚💄 Fix rdoc 6.8 CSS styles by @nevans in #356
  • 📚 Update IMAP#search docs (again) by @nevans in #360
  • 📚 Consistent heading levels inside method rdoc by @nevans in #361

Other Changes

  • ✨ Add Data polyfill for ruby 3.1 by @nevans in #352
  • ♻️ Refactor internal command data classes by @nevans in #358

Miscellaneous

  • 🔥 Drop YAML.unsafe_load_file refinement (tests only) by @nevans in #353
  • ⬆️ Bump step-security/harden-runner from 2.10.1 to 2.10.2 by @dependabot in #357
  • Enabled windows-latest on GHA by @hsbt in #359

Full Changelog: v0.5.1...v0.5.2

v0.5.1

08 Nov 23:10
v0.5.1
Compare
Choose a tag to compare

What's Changed

Added

  • ✨ Add SequenceSet#deconstruct by @nevans in #343
  • ✨ Coerce Set, :*, #to_sequence_set search args into sequence-set by @nevans in #351
  • ✨ Enable parenthesized lists in search criteria by @nevans in #345

Fixed

  • 🐛 Ensure set is loaded in ruby 3.1 by @nevans in #342
  • 🐛 Fix SequenceSet.try_convert by @nevans in #349

Documentation

Other Changes

  • ♻️ Reduce duplication in normalizing search args by @nevans in #348

Miscellaneous

  • Make simplecov-json as optional dependency by @hsbt in #344
  • Removed needless workaround by @hsbt in #346

Full Changelog: v0.5.0...v0.5.1

v0.4.18

08 Nov 23:11
v0.4.18
Compare
Choose a tag to compare

What's Changed

Full Changelog: v0.4.17...v0.4.18

v0.5.0

16 Oct 23:03
v0.5.0
Compare
Choose a tag to compare

What's Changed

Breaking Changes

  • 💥 Drop ruby 2.7 and 3.0 support, and require ruby 3.1 by @nevans in #276
  • 💥⚡ Simplify header-fld-name parser (backward incompatible) by @nevans in #216
    For example, HEADER.FIELDS (Content-Type) and HEADER.FIELDS ("Content-Type") are semantically identical, and a server may choose to return the quoted version.
    • Before this change, the FetchData attr header name would be quoted if the server sent the field name quoted.
    • After this change, the header field names will always be unquoted by the parser, so the result will always available via fetch_data.header_fields("Content-Type") or fetch_data.attr_upcase["HEADER.FIELDS (CONTENT-TYPE)"].
  • 💥 Replace MessageSet with SequenceSet by @nevans in #282
    Most of the changes are bugfixes or allow something new to work that didn't work before. See the PR for more details.
    This affects #search, #uid_search, #sort, #uid_sort, #fetch, #uid_fetch, #store, #uid_store, #copy, #uid_copy, #move, #uid_move, and #uid_expunge.
  • 💥 SequenceSet input validation for Set, Array, and enumerables by @nevans in #319
    • Array inputs can still be deeply nested. This is unchanged.
    • Set inputs can only contain integers and "*" or :*, to be consistent with SequenceSet#to_set.
    • Other Enumerables will only be converted if they implement #to_sequence_set.
  • 🔥 Remove deprecated #client_thread attr_reader by @nevans in #321
    #client_thread was deprecated by v0.4.0.
  • 🔥 Drop deprecated BodyType structs by @nevans in #323
    These structs were deprecated by v0.4.0.

Added

  • ✨ Add #extract_responses method by @nevans in #330 Also backported to v0.4.17.
  • ✨ New config option to return frozen dup from #responses by @nevans in #334 Also backported to v0.4.17.
  • 🥅 Improve SequenceSet frozen errors by @nevans in #331 Also backported to v0.4.17.
  • 📚 SequenceSet API is considered stable now by @nevans in #318
  • 🔒 Enforce LOGINDISABLED requirement by @nevans in #307
    To workaround buggy servers, config.enforce_logindisabled can be set to :when_capabilities_cached or false.
  • 🔒 SASL DIGEST-MD5: realm, host, service_name, etc by @nevans in #284
    Please note that the DIGEST-MD5 SASL mechanism is insecure and deprecated.

Deprecations

  • 🔊 Warn about deprecated #responses usage by @nevans in #97
    To silence these warnings:
    • pass a block to #responses (supported since v0.4.0),
    • pass a response type to #responses for a frozen copied array (since v0.4.17),
    • set config.responses_without_block to :silence_deprecation_warning (since v0.4.13),
    • set config.responses_without_block to :frozen_dup for a frozen copy (since v0.4.17),
    • use #clear_responses instead (since v0.4.0),
    • use #extract_responses instead (since v0.4.17).
  • 🗑️ Deprecate MessageSet by @nevans in #282
    MessageSet was only intended for internal use, and all internal usage has been replaced.

Fixed

  • 🐛 Fix #send_data to send DateTime as time by @taku0 in #313
    Also backported to v0.4.15.
  • 🐛 Fix #header_fld_name to handle quoted strings correctly by @taku0 in #315
    Also backported to v0.4.16.
  • 🐛 Fix SequenceSet[input] when input is a SequenceSet by @nevans in #326
    Also backported to v0.4.17.
  • 🐛 Fix Set inputs for SequenceSet by @nevans in #332
    This bug was introduced by #319, which had not been previously released.

Other Changes

  • 🔧 Update default config for v0.5 by @nevans in #305
  • ♻️ Use Integer.try_convert (new in ruby 3.1+) by @nevans in #316
  • 🗑️ Add category: :deprecated to calls to warn by @nevans in #322
  • ♻️ Extract SASL::Authenticators#normalize_name by @nevans in #309
  • 🔒 📚 Improvements and docs for SASL::ClientAdapter by @nevans in #320
  • ♻️ Use SASL::ClientAdapter by @nevans in #194

Documentation

  • 📚 Update Config rdoc for v0.5 by @nevans in #306
  • 📚 Update SASL documentation by @nevans in #308
  • 📚 SequenceSet API is considered stable now by @nevans in #318
  • 🔒 📚 Improvements and docs for SASL::ClientAdapter by @nevans in #320

Miscellaneous

  • ✅ Add a Mutex to FakeServer (for tests only) by @nevans in #317
    Also backported to v0.4.17.
  • ⬆️ Bump step-security/harden-runner from 2.8.1 to 2.9.0 by @dependabot in #311
  • ⬆️ Bump step-security/harden-runner from 2.9.0 to 2.9.1 by @dependabot in #312
  • Bump step-security/harden-runner from 2.9.1 to 2.10.1 by @dependabot in #325
  • 🔨📚 Fix rdoc => ghpages workflow by @nevans in #335
  • ✅ Fix GH action for rubygems Trusted Publishing by @nevans in #340
    Also backported to v0.4.17.
  • ✅ Setup simplecov by @nevans in #328

New Contributors

Full Changelog: v0.4.14...v0.5.0
(Note that v0.4.x releases since v0.4.14 have used the v0.4-stable branch.)