Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 68 additions & 0 deletions gems/net-imap/CVE-2026-42245.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
---
gem: net-imap
cve: 2026-42245
ghsa: q2mw-fvj9-vvcw
url: https://github.com/ruby/net-imap/security/advisories/GHSA-q2mw-fvj9-vvcw
title: net-imap has quadratic complexity when reading response literals
date: 2026-05-04
description: |
### Summary

`Net::IMAP::ResponseReader` has quadratic time complexity when reading large
responses containing many string literals. A hostile server can send
responses which are crafted to exhaust the client's CPU for a denial of
service attack.

### Details

For each literal in a response, `ResponseReader` rescans the entire growing
response buffer. The regular expression that is used to scan the response
buffer runs in linear time. With many literals, this becomes O(n²) total
work. The regular expression should run in constant time: it is anchored to
the end and only the last 23 bytes of the buffer are relevant.

Because the algorithmic complexity is super-linear, this bypasses protection
from `max_response_size`: a response can stay well below the default size
limit while still causing very large CPU cost.

`Net::IMAP::ResponseReader` runs continuously in the receiver thread until the
connection closes.

### Impact

This consumes disproportionate CPU time in the client's receiver thread. A
hostile server could use this to exhaust the client's CPU for a denial of
service attack.

For a response near the default `max_response_size`, each individual regexp
scan could take between 100 to 200ms on common modern hardware, and this may
be repeated 200k times per megabyte of response. While the regexp is
scanning, it retains the Global VM lock, preventing other threads from
running.

Although other threads should not be _completely_ blocked, their run time will
be significantly impacted.

### Mitigation
* Upgrade to a patched version of net-imap that reads responses more efficiently.
* Do not connect to untrusted IMAP servers.
* When connecting to untrusted servers, a _much_ smaller `max_response_size`
(for example: 8KiB) will limit the impact. Although this is too small for
fetching unpaginated message bodies, it should be enough for most other
operations.

cvss_v4: 2.3
patched_versions:
- "~> 0.4.24"
- "~> 0.5.14"
- ">= 0.6.4"
related:
url:
- https://github.com/ruby/net-imap/security/advisories/GHSA-q2mw-fvj9-vvcw
- https://github.com/ruby/net-imap/commit/6091f7d6b1f3514cafbfe39c76f2b5d73de3ca96
- https://github.com/ruby/net-imap/commit/88d95231fc8afef11c1f074453f7d75b68c9dfda
- https://github.com/ruby/net-imap/commit/de685f91a4a4cc75eb80da898c2bf8af08d34819
- https://github.com/ruby/net-imap/releases/tag/v0.4.24
- https://github.com/ruby/net-imap/releases/tag/v0.5.14
- https://github.com/ruby/net-imap/releases/tag/v0.6.4
- https://github.com/advisories/GHSA-q2mw-fvj9-vvcw
64 changes: 64 additions & 0 deletions gems/net-imap/CVE-2026-42246.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
---
gem: net-imap
cve: 2026-42246
ghsa: vcgp-9326-pqcp
url: https://github.com/ruby/net-imap/security/advisories/GHSA-vcgp-9326-pqcp
title: net-imap vulnerable to STARTTLS stripping via invalid response timing
date: 2026-05-04
description: |
### Summary

A man-in-the-middle attacker can cause `Net::IMAP#starttls` to return
"successfully", without starting TLS.

### Details

When using `Net::IMAP#starttls` to upgrade a plaintext connection to use TLS,
a man-in-the-middle attacker can inject a tagged `OK` response with an easily
predictable tag. By sending the response before the client finishes sending
the command, the command completes "successfully" before the response handler
is registered. This allows `#starttls` to return without error, but the
response handler is never invoked, the TLS connection is never established,
and the socket remains unencrypted.

This allows man-in-the-middle attackers to perform a STARTTLS stripping
attack, unless the client code explicitly checks `Net::IMAP#tls_verified?`.

### Impact

TLS bypass, leading to cleartext transmission of sensitive information.

### Mitigation

* Upgrade to a patched version of net-imap that raises an exception whenever
`#starttls` does not establish TLS.
* Connect to an implicit TLS port, rather than use `STARTTLS` with a cleartext
port.
This is strongly recommended anyway:
* [RFC 8314](https://www.rfc-editor.org/info/rfc8314): Cleartext Considered
Obsolete: Use of Transport Layer Security (TLS) for Email Submission and
Access
* [NO STARTTLS](https://nostarttls.secvuln.info/): Why TLS is better without
STARTTLS, A Security Analysis of STARTTLS in the Email Context
* Explicitly verify `Net::IMAP#tls_verified?` is `true`, before using the
connection after `#starttls`.
cvss_v4: 7.6
patched_versions:
- "~> 0.3.10"
- "~> 0.4.24"
- "~> 0.5.14"
- ">= 0.6.4"
related:
url:
- https://github.com/ruby/net-imap/security/advisories/GHSA-vcgp-9326-pqcp
- https://github.com/ruby/net-imap/commit/0ede4c40b1523dfeaf95777b2678e54cc0fd9618
- https://github.com/ruby/net-imap/commit/24a4e770b43230286a05aa2a9746cdbb3eb8485e
- https://github.com/ruby/net-imap/commit/97e2488fb5401a1783bddd959dde007d9fbce42c
- https://github.com/ruby/net-imap/commit/f79d35bf5833f186e81044c57c843eda30c873da
- https://github.com/ruby/net-imap/releases/tag/v0.3.10
- https://github.com/ruby/net-imap/releases/tag/v0.4.24
- https://github.com/ruby/net-imap/releases/tag/v0.5.14
- https://github.com/ruby/net-imap/releases/tag/v0.6.4
- https://nostarttls.secvuln.info
- https://www.rfc-editor.org/info/rfc8314
- https://github.com/advisories/GHSA-vcgp-9326-pqcp
81 changes: 81 additions & 0 deletions gems/net-imap/CVE-2026-42256.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
---
gem: net-imap
cve: 2026-42256
ghsa: 87pf-fpwv-p7m7
url: https://github.com/ruby/net-imap/security/advisories/GHSA-87pf-fpwv-p7m7
title: net-imap vulnerable to denial of service via high iteration count for `SCRAM-*`
authentication
date: 2026-05-04
description: |
### Summary

When authenticating a connection with `SCRAM-SHA1` or `SCRAM-SHA256`, a
hostile server can perform a computational denial-of-service attack on the
client process by sending a big iteration count value.

### Details

A hostile IMAP server can send an arbitrarily large PBKDF2 iteration count in
the SCRAM server-first-message, causing the client to perform an expensive
`OpenSSL::KDF.pbkdf2_hmac` call. Because the PBKDF2 function is a blocking C
extension and holds onto Ruby’s Global VM Lock, it can freeze the entire Ruby
VM for the duration of the computation.

OpenSSL enforces an effective maximum by using a 32-bit signed integer for the
iteration count, Depending on hardware capabilities and OpenSSL version, this
iteration count may be sufficient for to block all Ruby threads in the process
for over seven minutes.

This is listed as one of the \"Security Considerations\", in [RFC
7804](https://www.rfc-editor.org/rfc/rfc7804.html#page-15):

> A hostile server can perform a computational denial-of-service attack on
> clients by sending a big iteration count value. In order to defend against
> that, a client implementation can pick a maximum iteration count that it is
> willing to use and reject any values that exceed that threshold (in such
> cases, the client, of course, has to fail the authentication).

### Impact

During SCRAM authentication to a hostile server, the entire Ruby VM will be
locked for the duration of the computation. Depending on hardware
capabilities and OpenSSL version, this may take many minutes.

`OpenSSL::KDF.pbkdf2_hmac` is a blocking C function, so `Timeout` cannot be
used to guard against this. And it retains the Global VM lock, so other ruby
threads will also be unable to run.

### Mitigation

* Upgrade to a patched version of `net-imap` that adds the `max_iterations`
option to the `SASL-*` authenticators, and call `Net::IMAP#authenticate`
with a `max_iterations` keyword argument.

**NOTE:** The default `max_iterations` is `2³¹ - 1`, the maximum signed 32
bit integer, the maximum allowed by OpenSSL.

_To prevent a denial of service attack,_ this must be set to a safe value,
depending on hardware and version of OpenSSL. _It is the user's
responsibility_ to enforce minimum and maximum iteration counts that are
appropriate for their security context.

* Alternatively, avoid `SCRAM-*` mechanisms when authenticating to untrusted
servers.
cvss_v4: 6.0
unaffected_versions:
- "< 0.4.0"
patched_versions:
- "~> 0.4.24"
- "~> 0.5.14"
- ">= 0.6.4"
related:
url:
- https://github.com/ruby/net-imap/security/advisories/GHSA-87pf-fpwv-p7m7
- https://github.com/ruby/net-imap/commit/158d0b505074397cdb5ceb58935e42dd2bcfa612
- https://github.com/ruby/net-imap/commit/808001bc45c06f7297a7e96d341279e041a7f7f4
- https://github.com/ruby/net-imap/commit/99f59eab6064955a23debd95410263ad144df758
- https://github.com/ruby/net-imap/releases/tag/v0.4.24
- https://github.com/ruby/net-imap/releases/tag/v0.5.14
- https://github.com/ruby/net-imap/releases/tag/v0.6.4
- https://www.rfc-editor.org/rfc/rfc7804.html#page-15
- https://github.com/advisories/GHSA-87pf-fpwv-p7m7
120 changes: 120 additions & 0 deletions gems/net-imap/CVE-2026-42257.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
---
gem: net-imap
cve: 2026-42257
ghsa: hm49-wcqc-g2xg
url: https://github.com/ruby/net-imap/security/advisories/GHSA-hm49-wcqc-g2xg
title: net-imap vulnerable to command Injection via "raw" arguments to multiple commands
date: 2026-05-04
description: |
### Summary

Several `Net::IMAP` commands accept a raw string argument that is sent to the
server without validation or escaping. If this string is derived from
user-controlled input, it may contain contain `CRLF` sequences, which an
attacker can use to inject arbitrary IMAP commands.

### Details

`Net::IMAP`'s generic argument handling, used by most command arguments,
interprets string arguments as an IMAP `astring`. Depending on the string
contents and the connection's UTF-8 support, this encodes strings as either a
`atom`, `quoted`, or `literal`. These are safe from command or argument
injection.

But the following commands transform specific String arguments to
`Net::IMAP::RawData`, which bypasses normal argument validation and encoding
and prints the string directly to the socket:

* `#uid_search`, `#search`
* when `criteria` is a String, it is sent raw
* `#uid_fetch`, `#fetch`
* when `attr` is a String, it is sent raw
* when `attr` is an Array, each String in `attr` is sent raw
* `#uid_store`, `#store`
* when `attr` is a String, it is sent raw
* `#setquota`:
* `limit` is interpolated with `#to_s` and that string is sent raw

Because these string arguments are sent without any neutralization, they serve
as a direct vector for command splitting. Any user controlled data
interpolated into these strings can be used to break out of the intended
command context.

Using "raw data" arguments for `#uid_store`, `#store`, and `#setquota` I both
inappropriate and unnecessary. `Net::IMAP`'s generic argument handling is
sufficient to safely validate and encode their arguments. Users of the
library probably do not expect arguments to these commands to be sent raw and
might not be wary of passing unvalidated input.

The API for search criteria and fetch attributes is intentionally low-level
and "close to the wire". It allows developers to use some IMAP extensions
without requiring explicit support from the library and allows developers to
use complex IMAP grammar without complex argument translation. Even so, basic
validation is appropriate and could neutralize command injection.

Although this was explicitly documented for search `criteria`, it was
insufficiently documented for fetch `attr`. So developers may not have
realized that the `attr` argument to `#fetch` and `#uid_fetch` is sent as "raw
data".

### Impact

If a developer passes an unvalidated user-controlled input for one of these
method arguments, an attacker can append CRLF sequence followed by a new IMAP
command (like DELETE mailbox). Although this does not _directly_ enable data
exfiltration, it could be combined with other attack vectors or knowledge of
the target system's attributes, e.g.: shared mail folders or the application's
installed response handlers.

The SEARCH, STORE, and FETCH commands, and their UID variants are some of the
most commonly used features of the library. Applications that build search
queries or fetch attributes dynamically based on user input (e.g., mail
clients or archival tools) may be at significant risk.

Expected use of `Net::IMAP#setquota` is much more limited: `SETQUOTA` is often
only usable by users with special administrative privileges. Depending on the
server, quota administration might be managed through server configuration
rather than via the IMAP protocol `SETQUOTA` command. It is expected to be
uncommonly used in system administration scripts or in interactive sessions,
it should be completely controlled by trusted users, and should only use
trusted inputs. Calling `#setquota` with untrusted user input is expected to
be a very uncommon use case. Please note however this might be combined with
other attacks, for example CSRF, which provide unauthorized access to trusted
inputs, and may specifically target users or scripts with administrator
privileges.

### Mitigation

- Update to a patched version of `net-imap` which:
- validates that `Net::IMAP::RawData` is composed of well-formed IMAP
`text`, `literal`, and `literal8` values, with no unescaped `NULL`, `CR`,
or `LF` bytes.
- does not use `Net::IMAP::RawData` for `#store`, `#uid_store`, or
`#setquota`.
- Prefer to send search criteria as an array of key value pairs. Avoid
sending it as an interpolated string.
- If an immediate upgrade is not possible:
- String inputs to search criteria and fetch attributes can be validated
against command injection by checking for `\r` and `\n` characters.
- Hard-coding the store `attr` argument is often appropriate.
Alternatively, user controlled inputs can be restricted to a small
enumerated list which is valid for the calling application.
- Use `Kernel#Integer` to coerce and validate user controlled inputs to
`#setquota` limit.
cvss_v4: 5.8
patched_versions:
- "~> 0.4.24"
- "~> 0.5.14"
- ">= 0.6.4"
related:
url:
- https://github.com/ruby/net-imap/security/advisories/GHSA-hm49-wcqc-g2xg
- https://github.com/ruby/net-imap/commit/0ec4fd351263e8b9a4f683713427827b7b1ad974
- https://github.com/ruby/net-imap/commit/47c72186d272441878ca73c9499f66013829ca2f
- https://github.com/ruby/net-imap/commit/6bf02aef7e0b5931010c36e377f79a71636b306b
- https://github.com/ruby/net-imap/commit/a4f7649c3da77dec7631f03a037a478eb4330048
- https://github.com/ruby/net-imap/commit/aec06996eb87a7e1bbcef1f9f8926e8add2b8c71
- https://github.com/ruby/net-imap/releases/tag/v0.4.24
- https://github.com/ruby/net-imap/releases/tag/v0.5.14
- https://github.com/ruby/net-imap/releases/tag/v0.6.4
- https://github.com/advisories/GHSA-hm49-wcqc-g2xg
Loading
Loading