🔒 Fix CRLF injection vulnerabilities (backports #657, #658, #659, #660, #636, #661)#663
Merged
nevans merged 8 commits intov0.4-stablefrom Apr 23, 2026
Merged
Conversation
#657] Flags should not allow `atom-specials`. Previously, no validation was done on symbol data. Sending atom or flag args which contain atom specials could lead to various errors. Although this could theoretically include injection attacks, this is not considered to be a critical vulnerability in `net-imap`, for the following reason: Valid "system flag" inputs are restricted to an enumerated set of RFC-defined flag types. User-defined "keyword" flags are sent as atoms, not flags, which use string inputs (strings which can't be sent as an atom will be quoted or sent as a literal). `\Seen` as a flag (symbol argument) is semantically different from `Seen` as a keyword (string argument). So there is no scenario where it is appropriate to call `#to_sym` on unvetted user input. Any code which calls `#to_sym` indiscriminately on user-input is already buggy. Nevertheless, users should reasonably be able to rely on `net-imap` to do very basic input validation on its basic input types.
…rts #658] Previously, `#store` and `#uid_store` wrapped `attr` with `RawData`. But that's completely unnecessary. `+`, `-`, and `.` are atom chars, and every STORE "message data item" defined in any RFC is an `atom`: ``` FLAGS FLAGS.SILENT +FLAGS +FLAGS.SILENT -FLAGS -FLAGS.SILENT ANNOTATION ANNOTATION.SILENT ``` We can revisit this in the future, if some new extension uses a non-atom for its STORE "message data item", but that seems unlikely. Note also that `Atom` is only applied to `String` arguments.
Includes fixes for v0.4 compatibility.
…kports #636] This updates the QUOTA docs with references to RFC9208 (`QUOTA=RES-*`). For the most part, RFC9208 is backward compatible with RFC2087. So this updates the documentation to reference it wherever relevant. This also documents how `net-imap`'s support for `QUOTA` is incomplete: that it only supports setting `STORAGE` and can only parse a single resource type (which is _usually_ `STORAGE`). The RFCs are very clear that `quota root` is _not_ the same as `mailbox`, so this updates method parameters and rdoc to reflect that. `MailboxQuota#mailbox` is incorrectly named, but renaming it would be backward incompatible. This just updates the documentation and adds `quota_root` as an alias. This also fixes the rdoc for `MailboxQuota#quota` to specify that it is the _storage_ limit, rather than any other quota resource type. This adds a note in the rdoc that _only_ `STORAGE` is currently supported. `GETQUOTA` generally _is_ available to normal users. That comment on `#getquota` may have been copied from `SETQUOTA`. See also: #622
…rts #659] There's no reason to use `RawData` for this. We can use Net::IMAP's standard command argument formatting to send a parenthesized list.
…t/v0.4/security-patches
…kports #660] This parses a RawData string into an array of `text`, `literal`, and `literal8` parts. This fixes embedded literals so they correctly wait for server continuation request before sending. Non-synchronizing literals are also parsed correctly. This adds `Net::IMAP::RawText` which sends verbatim (like `RawData` did previously), and handles `text` validations: * `text` can't contain CR, LF, or NULL * `text` must be ASCII compatible or valid UTF-8 The existing `Literal` and `Literal8` classes handle literal validation: * `literal` can't contain NULL byte, but `literal8` can Additionally, `RawData` validates that: * embedded literal bytesize must be <= remaining string bytesize * final `text` cannot end with `{number}` (in case a `CRLF` comes after) This does _not_ make RawData arguments safe from every type of injection attack. However, without losing any significant flexibility, this _does_ prevent unescaped `CRLF` from creating a _command_ injection.
#661] Now that `setquota`, `store`, and `uid_store` have been fixed, there should only be two parameters that still use `RawData`: search `criteria` and fetch `attr` (and the `UID` variants). `#search` criteria (when a string) had already been documented, but this aspect of `#fetch` attr was _not_ previously documented!
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This backports the fixes for various CRLF injection vulnerabilities to
v0.4-stable.Important
This fixes a CSRF/command injection vulnerability for Symbol arguments.
Important
This fixes a CSRF/command injection vulnerability for the
attrargument to#store/#uid_store.attras anatom#658Important
This fixes a CSRF/command injection vulnerability for the
storage_limitargument to#setquota.#setquotastorage limit argument #659Important
This fixes the CRLF injection / command injection vulnerability in
RawData, which is used for thecriteriaargument#search/#uid_searchwhen it is a String, and theattrargument to#fetch/#uid_fetchwhen is a String, or the String members ofattrwhen it is an Array.Caution
Please note:
RawDatacan still be used for other forms of argument injection!The following documentation PRs were also backported:
#setquota, ♻️ AddMailboxQuota#quota_rootalias #636