Skip to content

🔒🐛 Validate RawData and wait to continue literals#660

Merged
nevans merged 1 commit intomasterfrom
parse-raw-data-literals
Apr 23, 2026
Merged

🔒🐛 Validate RawData and wait to continue literals#660
nevans merged 1 commit intomasterfrom
parse-raw-data-literals

Conversation

@nevans
Copy link
Copy Markdown
Collaborator

@nevans nevans commented Apr 23, 2026

Important

This fixes a CRLF/command injection vulnerability for RawData, which is used by:

  • #search and #uid_search send criteria as raw data, when it is a String
  • #fetch and #uid_fetch send attr as raw data, when it is a String.
    When attr is an Array, its String members are sent as raw data.

Caution

RawData does not defend against other forms of argument injection! It is an intentionally low-level API.

This parses a RawData string into an array of text, literal, and literal8 parts. In addition to blocking the CRLF injection vulnerability, this also fixes embedded literals so they correctly wait for server continuation request before sending. Binary and Non-synchronizing literals are also parsed and sent 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.

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.
@nevans nevans added bug Something isn't working backport-0.5 This ticket needs to be backported to the v0.5-stable branch. backport-0.4 This ticket needs to be backported to the v0.4-stable branch labels Apr 23, 2026
@nevans nevans merged commit 47c7218 into master Apr 23, 2026
39 checks passed
@nevans nevans deleted the parse-raw-data-literals branch April 23, 2026 14:20
@nevans nevans added the security vulnerability patch Pull requests that address security vulnerabilities label Apr 23, 2026
nevans added a commit that referenced this pull request Apr 23, 2026
🔒 Fix CRLF injection vulnerabilities (backports #657, #658, #659, #660, #636, #661)
nevans added a commit that referenced this pull request Apr 23, 2026
🔒 Fix CRLF injection vulnerabilities (backports #657, #658, #659, #660, #636, #661)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backport-0.4 This ticket needs to be backported to the v0.4-stable branch backport-0.5 This ticket needs to be backported to the v0.5-stable branch. bug Something isn't working security vulnerability patch Pull requests that address security vulnerabilities

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant