Net::IMAP implements Internet Message Access Protocol (IMAP) client functionality in Ruby. Prior to versions 0.5.7, 0.4.20, 0.3.9, and…
GitHub_M·CWE-400·Published 2025-04-28
Net::IMAP implements Internet Message Access Protocol (IMAP) client functionality in Ruby. Prior to versions 0.5.7, 0.4.20, 0.3.9, and 0.2.5, there is a possibility for denial of service by memory exhaustion when net-imap reads server responses. At any time while the client is connected, a malicious server can send can send a "literal" byte count, which is automatically read by the client's receiver thread. The response reader immediately allocates memory for the number of bytes indicated by the server response. This should not be an issue when securely connecting to trusted IMAP servers that are well-behaved. It can affect insecure connections and buggy, untrusted, or compromised servers (for example, connecting to a user supplied hostname). This issue has been patched in versions 0.5.7, 0.4.20, 0.3.9, and 0.2.5.
Net::IMAP implements Internet Message Access Protocol (IMAP) client functionality in Ruby. Prior to versions 0.5.7, 0.4.20, 0.3.9, and 0.2.5, there is a possibility for denial of service by memory exhaustion when net-imap reads server responses. At any time while the client is connected, a malicious server can send can send a "literal" byte count, which is automatically read by the client's receiver thread. The response reader immediately allocates memory for the number of bytes indicated by the server response. This should not be an issue when securely connecting to trusted IMAP servers that are well-behaved. It can affect insecure connections and buggy, untrusted, or compromised servers (for example, connecting to a user supplied hostname). This issue has been patched in versions 0.5.7, 0.4.20, 0.3.9, and 0.2.5.
### Summary There is a possibility for denial of service by memory exhaustion when `net-imap` reads server responses. At any time while the client is connected, a malicious server can send can send a "literal" byte count, which is automatically read by the client's receiver thread. The response reader immediately allocates memory for the number of bytes indicated by the server response. This should not be an issue when securely connecting to trusted IMAP servers that are well-behaved. It can affect insecure connections and buggy, untrusted, or compromised servers (for example, connecting to a user supplied hostname). ### Details The IMAP protocol allows "literal" strings to be sent in responses, prefixed with their size in curly braces (e.g. `{1234567890}\r\n`). When `Net::IMAP` receives a response containing a literal string, it calls `IO#read` with that size. When called with a size, `IO#read` immediately allocates memory to buffer the entire string before processing continues. The server does not need to send any more data. There is no limit on the size of literals that will be accepted. ### Fix #### Upgrade Users should upgrade to `net-imap` 0.5.7 or later. A configurable `max_response_size` limit has been added to `Net::IMAP`'s response reader. The `max_response_size` limit has also been backported to `net-imap` 0.2.5, 0.3.9, and 0.4.20. To set a global value for `max_response_size`, users must upgrade to `net-imap` ~> 0.4.20, or > 0.5.7. #### Configuration To avoid backward compatibility issues for secure connections to trusted well-behaved servers, the default `max_response_size` for `net-imap` 0.5.7 is _very high_ (512MiB), and the default `max_response_size` for `net-imap` ~> 0.4.20, ~> 0.3.9, and 0.2.5 is `nil` (unlimited). When connecting to untrusted servers or using insecure connections, a much lower `max_response_size` should be used. ```ruby # Set the global max_response_size (only ~> v0.4.20, > 0.5.7) Net::IMAP.config.max_response_size = 256 << 10 # 256 KiB # Set when creating the connection imap = Net::IMAP.new(hostname, ssl: true, max_response_size: 16 << 10) # 16 KiB # Set after creating the connection imap.max_response_size = 256 << 20 # 256 KiB # flush currently waiting read, to ensure the new setting is loaded imap.noop ``` _**Please Note:**_ `max_response_size` only limits the size _per response_. It does not prevent a flood of individual responses and it does not limit how many unhandled responses may be stored on the responses hash. Users are responsible for adding response handlers to prune excessive unhandled responses. #### Compatibility with lower `max_response_size` A lower `max_response_size` may cause a few commands which legitimately return very large responses to raise an exception and close the connection. The `max_response_size` could be temporarily set to a higher value, but paginated or limited versions of commands should be used whenever possible. For example, to fetch message bodies: ```ruby imap.max_response_size = 256 << 20 # 256 KiB imap.noop # flush currently waiting read # fetch a message in 252KiB chunks size = imap.uid_fetch(uid, "RFC822.SIZE").first.rfc822_size limit = 252 << 10 message = ((0..size) % limit).each_with_object("") {|offset, str| str << imap.uid_fetch(uid, "BODY.PEEK[]<#{offset}.#{limit}>").first.message(offset:) } imap.max_response_size = 16 << 20 # 16 KiB imap.noop # flush currently waiting read ``` ### References * PR to introduce max_response_size: https://github.com/ruby/net-imap/pull/444 * Specific commit: [0ae8576c1 - lib/net/imap/response_reader.rb](https://github.com/ruby/net-imap/pull/444/commits/0ae8576c1a90bcd9573f81bdad4b4b824642d105#diff-53721cb4d9c3fb86b95cc8476ca2df90968ad8c481645220c607034399151462) * Backport to 0.4: https://github.com/ruby/net-imap/pull/445 * Backport to 0.3: https://github.com/ruby/net-imap/pull/446 * Backport to 0.2: https://github.com/ruby/net-imap/pull/447
### Summary There is a possibility for denial of service by memory exhaustion when `net-imap` reads server responses. At any time while the client is connected, a malicious server can send can send a "literal" byte count, which is automatically read by the client's receiver thread. The response reader immediately allocates memory for the number of bytes indicated by the server response. This should not be an issue when securely connecting to trusted IMAP servers that are well-behaved. It can affect insecure connections and buggy, untrusted, or compromised servers (for example, connecting to a user supplied hostname). ### Details The IMAP protocol allows "literal" strings to be sent in responses, prefixed with their size in curly braces (e.g. `{1234567890}\r\n`). When `Net::IMAP` receives a response containing a literal string, it calls `IO#read` with that size. When called with a size, `IO#read` immediately allocates memory to buffer the entire string before processing continues. The server does not need to send any more data. There is no limit on the size of literals that will be accepted. ### Fix #### Upgrade Users should upgrade to `net-imap` 0.5.7 or later. A configurable `max_response_size` limit has been added to `Net::IMAP`'s response reader. The `max_response_size` limit has also been backported to `net-imap` 0.2.5, 0.3.9, and 0.4.20. To set a global value for `max_response_size`, users must upgrade to `net-imap` ~> 0.4.20, or > 0.5.7. #### Configuration To avoid backward compatibility issues for secure connections to trusted well-behaved servers, the default `max_response_size` for `net-imap` 0.5.7 is _very high_ (512MiB), and the default `max_response_size` for `net-imap` ~> 0.4.20, ~> 0.3.9, and 0.2.5 is `nil` (unlimited). When connecting to untrusted servers or using insecure connections, a much lower `max_response_size` should be used. ```ruby # Set the global max_response_size (only ~> v0.4.20, > 0.5.7) Net::IMAP.config.max_response_size = 256 << 10 # 256 KiB # Set when creating the connection imap = Net::IMAP.new(hostname, ssl: true, max_response_size: 16 << 10) # 16 KiB # Set after creating the connection imap.max_response_size = 256 << 20 # 256 KiB # flush currently waiting read, to ensure the new setting is loaded imap.noop ``` _**Please Note:**_ `max_response_size` only limits the size _per response_. It does not prevent a flood of individual responses and it does not limit how many unhandled responses may be stored on the responses hash. Users are responsible for adding response handlers to prune excessive unhandled responses. #### Compatibility with lower `max_response_size` A lower `max_response_size` may cause a few commands which legitimately return very large responses to raise an exception and close the connection. The `max_response_size` could be temporarily set to a higher value, but paginated or limited versions of commands should be used whenever possible. For example, to fetch message bodies: ```ruby imap.max_response_size = 256 << 20 # 256 KiB imap.noop # flush currently waiting read # fetch a message in 252KiB chunks size = imap.uid_fetch(uid, "RFC822.SIZE").first.rfc822_size limit = 252 << 10 message = ((0..size) % limit).each_with_object("") {|offset, str| str << imap.uid_fetch(uid, "BODY.PEEK[]<#{offset}.#{limit}>").first.message(offset:) } imap.max_response_size = 16 << 20 # 16 KiB imap.noop # flush currently waiting read ``` ### References * PR to introduce max_response_size: https://github.com/ruby/net-imap/pull/444 * Specific commit: [0ae8576c1 - lib/net/imap/response_reader.rb](https://github.com/ruby/net-imap/pull/444/commits/0ae8576c1a90bcd9573f81bdad4b4b824642d105#diff-53721cb4d9c3fb86b95cc8476ca2df90968ad8c481645220c607034399151462) * Backport to 0.4: https://github.com/ruby/net-imap/pull/445 * Backport to 0.3: https://github.com/ruby/net-imap/pull/446 * Backport to 0.2: https://github.com/ruby/net-imap/pull/447
Net::IMAP implementa la funcionalidad de cliente del Protocolo de Acceso a Mensajes de Internet (IMAP) en Ruby. En versiones anteriores a la 0.5.7, 0.4.20, 0.3.9 y 0.2.5, existía la posibilidad de denegación de servicio por agotamiento de memoria al leer las respuestas del servidor. Mientras el cliente esté conectado, un servidor malicioso puede enviar un recuento literal de bytes, que el hilo receptor del cliente lee automáticamente. El lector de la respuesta asigna inmediatamente memoria para la cantidad de bytes indicada por la respuesta del servidor. Esto no debería ser un problema al conectarse de forma segura a servidores IMAP confiables y con buen comportamiento. Puede afectar a conexiones inseguras y servidores con errores, no confiables o comprometidos (por ejemplo, al conectarse a un nombre de host proporcionado por el usuario). Este problema se ha corregido en las versiones 0.5.7, 0.4.20, 0.3.9 y 0.2.5.
| Version | Type | Source | Base | Exp | Impact | Vector |
|---|---|---|---|---|---|---|
| 3.1 | Primary | NVD | 6.5 | 2.8 | 3.6 | CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:N/A:H |
| 4.0 | Primary | cve.org | 6.0 | — | — | CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:P/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N |
| 4.0 | Primary | cve.org | 6.0 | — | — | CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:P/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N |
| 4.0 | Secondary | NVD | 6.0 | — | — | CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:P/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X |
| 4.0 | Secondary | GHSA | 6.0 | — | — | CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:P/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N |